Tag Archives: html

Yeah so my audio player in jQuery Mobile and NodeJS (part 2)

Ok so my prev post was about how to construct a playlist in jQuery Mobile with some simple NodeJS file serving. This one is to construct the audio player itself! Mine looks like this (cause I was kinda too lazy to do the styling properly):

My audio player

My audio player

Ok so it’s very basic: we got a toggle Play/Pause button, Next button, Prev button, the progress bar for download progress and a fake album art (cause I didn’t know how to extract mp3 metadata yet). The features that I implemented are pretty basic:

1. Play/Pause

2. Next/Prev Song

3. Progress bar for song buffering

4. Time Left

5. Auto-play the next one if this one ended

6. Header shows song name

The HTML structure itself is rather simple as jQuery Mobile does most of the styling for u:


<div data-role="page" class="player">

    <div data-role="header">
        <h1>My collection</h1>
    </div><!-- /header -->

    <div data-role="content">

	<div class='cover-art' style='text-align:center'>
		<audio src='music/kpop/ttl2.mp3' preload autoplay></audio>
		<img src='images/no-album-art.png' />
	</div>
    </div><!-- /content -->
    <div data-role='footer' style='text-align:center'>
	<p class='track-info'>
		<span class="song-progress">
			<input type="range" min="0" max="100" value="0" />
		</span>
		<span class="timeleft"></span>
	</p>
	<div class='playback' data-role="controlgroup" data-type='horizontal' style='text-align:center'>
<button class='playback-prev' data-icon='back'>Prev</button>
<button class='playback-play' >||</button>
<button class='playback-next' data-icon="forward" data-iconpos="right">Next</button>
</div>
	</div>
<script type="text/javascript">
	$('div.player').bind('pageshow', function(ev, ui) {
		if (!$(this).attr('data-init')) {
			Player.init('div.player.ui-page-active', $.getUrlVar($(this).attr('data-url'), 'song'));
			$(this).attr('data-init', 'true');
		}
	});
</script>
</div><!-- /page -->

So again, I bind some initialization to the “pageshow” event of the page and make sure it doesn’t get initialized twice. Since the href in each <li> points to the same page but different parameter, jQuery loads this again every single time even if it’s the same one. This only prevents the forward history button to reload the song. However, this does not prevent having multiple songs playing at the same time cause jQuery mobile loads those as different div. You can customize the changePage behavior when user clicks on a <li> but I didn’t, just to keep it simple.

The parameter is stored in the main player div (with selector “div.player”, class “ui-page-active” indicates its the active one) so $.getUrlVar just extract the parameter song from it (which indicates the song index):

$.extend({
	getUrlVars : function(string) {
		var vars = [];
		var hash;
		var href = string ? string : window.location.href;
		console.log(href);
		if (href.indexOf('#') > -1) {
			var hrefArr = href.split('#');
			href = hrefArr[hrefArr.length - 1];
		}
    		var hashes = href.slice(href.indexOf('?') + 1).split('&');
		for (var i = 0; i < hashes.length; i++) {
			hash = hashes[i].split('=');
			vars.push(hash[0]);
			vars[hash[0]] = hash[1];
		}
		return vars;
	},

	getUrlVar : function(string, name) {
		return $.getUrlVars(string)[name];
	}
});

Pretty simple, just basically splitting the data-url field into a map of parameter names and values. The Player.init function takes in the parent div selector (so that I can locate the control relative to the parent div) and the song index. I basically keep track of all the control DOM elements:

var $next = $(div + ' button.playback-next');
var $prev = $(div + ' button.playback-prev');
var $play = $(div + ' button.playback-play');
var $trackInfo = $(div + ' p.track-info');
var $songProgress = $trackInfo.find('.song-progress');
var $loading = $songProgress.find('.loading');
var $timeLeft = $trackInfo.find('.timeleft');
var $slider = $songProgress.find('.ui-slider');
var $handle = $slider.find('.ui-slider-handle');
$songProgress.find('input[type="number"]').hide();
var $title = $(div + ' h1.ui-title');
var $audio = $(div + ' audio');
var audio = $audio.get(0);

I have this habit of prefixing jQuery objects with $ to distinguish from actual DOM element ($audio is the jQuery-wrapped object of audio). Play/pause is really easy:

$play.click(function(ev) {
    var $buttonText = $(this).parent().find('.ui-btn-text');
    if (audio.paused) {
        $audio.attr('data-state', 'play');
        audio.play();
        $buttonText.text("||");
    }
    else {
        $audio.attr('data-state', 'pause');
        audio.pause();
        $buttonText.text("Play");
    }
});

Prev/Next is also straightforward:

$next.click(function(ev) {
    var state = $audio.attr('data-state');
    var current = parseInt($audio.attr('data-current'));
    Player.getSongPath(current + 1, $audio, $title, function() {
        $audio.attr('data-current', current + 1);
        if (state == 'play') {
            audio.play();
        }
    });
});
$prev.click(function(ev) {
    var state = $audio.attr('data-state');
    var current = parseInt($audio.attr('data-current'));
    Player.getSongPath(current - 1, $audio, $title, function() {
        $audio.attr('data-current', current - 1);
        if (state == 'play') {
            audio.play();
        }
    });
});

So we’ve done 1 and 2. Let’s jump to 5 cause its also easy:

$audio.bind('ended', function(ev) {
    $next.click();
});

I did 6 as a separate functionality that ping the server for the song’ path, change the audio source and also title:

getSongPath: function(index, $audio, $title, fn) {
    $.post('playlist?song=' + index, null, function(data) {
        console.log(data);
        $audio.attr('src', data.result);
        var filenameArr = data.result.split('/');
        var filename = filenameArr[filenameArr.length - 1];
        $title.text(filename);
        if ($.isFunction(fn)) {
            fn();
        }
    }, 'json');
}

For some reason I put null in the POST request data instead of the actual data (song=2) cause I wasn’t getting that data on the server side (I tried req.body, req.query and everything… didn’t seem to show up, will look into it a bit more). OK now lets get back to 3:

if (!$loading.get(0)) { //this inject the white loading bar before the handler
    $handle.before('<div class="ui-slider loading" style="width: 3%; float: left; top: 0; left: -3%; background-color: buttonface;"></div>');
    $loading = $slider.find('div.loading'); //update var
}
$audio.bind('progress', function() {
    var loaded = parseInt(((audio.buffered.end(0) / audio.duration) * 100) + 3, 10);
    $loading.css({
        width: loaded + '%' //change width accordingly
    });
});
var manualSeek = false;
var loaded = false;
$handle.css({
    top: '-50%' //somehow I think the styling of footer and handler conflicted and messed it up so I had to bump it up 50%
});

I actually didn’t know how to get the current time of the audio but after googling around and looking at audio attributes, things got a bit clearer. Here’s 4:

$audio.bind('timeupdate', function() {
    var rem = parseInt(audio.duration - audio.currentTime, 10),
        pos = Math.floor((audio.currentTime / audio.duration) * 100),
        mins = Math.floor(rem / 60, 10),
        secs = rem - mins * 60;
    $timeLeft.text('-' + mins + ':' + (secs > 9 ? secs : '0' + secs));
    if (!manualSeek) {
        $handle.css({
            left: pos + '%'
        });
    }
    if (!loaded) {
        loaded = true;
    }
});

Ok so that’s how I made a sorta functional audio player. There’re still problems with it but hopefully this DIY guide gave u some idea on how to control the audio element manually.

Advertisements
Tagged , , , , , , ,

What I’ve been up to… (a.k.a making an audio player using jQuery Mobile & NodeJS) Part 1

So I recently signed up for a VPS from AlienVPS at a ridiculously low price and guess what, it crashed on me twice today… -_- But $19/month is still pretty darn cheap. At least it gave me some sandbox to play around with NodeJS and jQuery Mobile.

OK so far NodeJS has been rather simple and straightforward. I actually use Express framework on top of NodeJS which ease the work a little bit. However, I can really see how this can become complicated really really fast. 1st of all, I sorta have to implement all the HTTP protocol code manually in NodeJS (except for 500 Internal Error and 200 OK I think). So that includes 404, 403, blah blah. Not that it matters that much except I wanna maximize my site traffic by taking advantage of Search Engine bots. Well I disallow everything in robots.txt right now so if those bots behave, I should be good. You can check it out at http://208.93.155.39:8080/playlist.html but please please don’t spread it around or I’m gonna have to shut it down due to my limited bandwidth. The app is still buggy since it’s a work in progress but a refresh should make it behave a bit better.

Anyway, now the 1st thing a web server should be able to do is to serve static web pages and it can be achieved pretty easily:

var app = require('express').createServer();
var fs = require('fs');
var public_path = 'public/';
var PORT = 8080;
app.get('/', function(req, res) {
        res.sendfile(public_path + 'index.html');
});
app.get('/*', function(req, res) {
        var page = req.params[0];
        res.sendfile(public_path + page);
});

Easy enuf… Now I want to query some specific stuff like, idk my KOREAN POP playlist!!

var songs;
app.post('/playlist.html', function(req, res){
        Controller.handlePlaylist(req, res);
});
var Playlist = {
        get : function(name) {
                return fs.readdirSync(public_path + MUSIC_PATH + name);
        }
};
var Controller = {
        handlePlaylist : function(req, res) {
                if (!songs) { //lazy-initialize this
                        songs = Playlist.get(req.param('playlist'));
                }
                var index = req.param('song');
                if (index && index >=0 && index < songs.length) { //if I query a specific song number, give me the path to the song
                        res.send({ 'result' : MUSIC_PATH + 'kpop/' + songs[index] });
                } else { //otherwise give me the whole list
                        res.send({ 'filenames' : songs });
                }
        }
};

Now when I hit up playlist.html?playlist=kpop with POST, I can get my playlist and playlist.html?song=1 with POST gives me the 2nd song. This is a simple enuf song serving mechanism that will help me build my audio player.

Playlist Page

Playlist Page

Since I’m not using any view rendering engine, in playlist.html I actually have to use the trick of loading the file 1st, then make an ajax call to populate the data. This gets very very tricky with jQuery mobile since it doesn’t have a lot of control events on when it’s done rendering and what not. This combines with ambiguous timing from AJAX callbacks can lead to a pretty disruptive UX (I’m still having trouble with synchronizing stuff in JavaScript). But anyway, the playlist.html has a pretty simple structure:

<div data-role="page" class="playlist">
    <div data-role="header">
        <h1>My collection</h1>
    </div><!-- /header -->

    <div data-role="content">
        <ul data-role="listview" data-inset="true">
                <li data-role="list-divider">Kpop</li>
        </ul>
    </div><!-- /content -->
    <script type='text/javascript'> 
    $('div.playlist').bind('pageshow', function() {
        var $page = $(this); // to use inside callback since "this" in the callback function is different
        if (!($page.attr('data-init'))) { // Initialize once
                $.post('playlist.html?playlist=kpop', null, function(data) { //retrieve the data
                        var i;
                        var filenames = data['filenames'];
                        var $playlist = $page.find('ul[data-role="listview"]');
                        for (i in filenames) { //populate the list of songs
                                $playlist.append('<li><a href="player.html?song=' + i + '">' + filenames[i] + '</a></li>'); 
                        }
                        $page.attr('data-init', 'true');
                        $playlist.listview('refresh'); //refresh the view
                }, 'json');
        }
    });
    </script>

</div><!-- /page -->

The HTML structure itself is simple the the JavaScript is kind of a hack. “Pageshow” event in jQuery Mobile gets invoked after page has been initialized (a.k.a after jQuery converts basic elements into its themed mobile looks). Why not “pagecreate” or “pagebeforecreate”? Because the callback is actually an AJAX call to grab the data and listview can only be refresh after it’s been initialized (also not guaranteed in the previous 2 event hooks). If I were to use a view rendering engine to populate the data, then send across the wire, I wouldn’t have had this problem so… something to look at next time.

OK so that’s the easy part, I write next time about how to actually make the player cause that took me like 3 days… >.< sleep now!

Tagged , , , , , ,

Why I’m hooked on JavaScript!!

Now I’m apparently not even an expert at JavaScript but I’ve had some exposure to it in 1 way or another, mainly through using jQuery in my last project (which I totally dig!!). I’m still working on web development in general and that project in particular right now and my friend and I have been going back and forth between the popular languages/frameworks like Ruby on Rails, Django and NodeJS. Honestly, I’m kinda a fanboy for NodeJS… I really am. Here’s why:

Now JavaScript has been mainly used for client side in web browser. The interesting thing is that each big boss (Mozilla/Google/IE) seems to develop their own JS Compiler. The Google V8 Engine (which NodeJS is built on) seems to be the fastest one right now. I was pretty amazed when JS was used as a server side technology but if you break it down, I wouldn’t say it’s impossible.

IMHO, I guess the important thing about writing a server is to handle sockets and a few protocols (HTTP, TCP… stuff like that). Now protocols are (again, IMO) rules of how information should be positioned in a packet so you can do that with pretty much any language. Traditional server technologies like Apache Tomcat, Glassfish… have been spawning threads to handle each incoming request. That’s not necessarily a bad thing but the bottlenecks seem to come down to IO so there’s been drawbacks in terms of blocking threads when u do a long query and such. Now u can overcome that by implementing distributed systems with a load balancer on top, along with some request filtering and routing, at which point it becomes kinda costly.

NodeJS

NodeJS

NodeJS uses Event Queue which puts everything in there and does event loop and uses callback functions. So technically there’re no blocking and the app is very scalable, theoretically. With that said, a long query gets run and once it’s done the callback is invoked. Now that sounds kinda cool.

OK so it can handle HTTP request, what else? Another important thing I would say is the database, which kinda comes down to separate vendor. How does the server connects to the database? Using a driver! Java gets an advantage cause it maintains an interface for vendors to write drivers based on. RoR supports a couple of database technologies and so is Django. There’re enough database vendors and plugins out there that it’s gonna take a while for NodeJS to catch up on that front, I assume.

What else? Some process manipulations like File IO and such, cause apparently the server will need to, at some point, modify some file resources, invoke some processes and stuff like that. NodeJS does have this, although I’m not sure how stable/mature it is. But that should take care of it.

Now I’ve always thought that RoR and Django were booming due to their ability to do rapid prototyping/development really really fast. You can get started on a webapp at a reasonably good pace with those, thanks to ORM and dependency injection and all the fun stuff. Honestly, I’m kinda a purist to a degree that I don’t hate abstracting 1 language over another, but magic can be disastrous sometimes. I believe that I should hand-write SQL queries and HTML/CSS instead of using ORM and compiled HTML (such as erb/jsp/asp…) cause you get a better control over it. It gets hard to manage after a while but it’s easier to identify the bottleneck and optimize it, instead of optimizing RoR and hoping that would optimize SQL.

Besides, using compiled HTML puts more load on the server than client, which in a way provides a more stable outcome since client machines/browsers vary a lot. But again, back to mixed language kinda thing, gotta be careful.

1 of the things I found that is challenging to JavaScript is actually synchronization. Now according to my knowledge, browser JS is executed in a single thread so how come synchronization is a big deal? Because browsers render different things in a different threads (you’ve been wondering how they load part by part, right??). Now what that means is, browsers render images/HTML structure/CSS styling/JS separately in different threads so its was such a pain for me to get a consistent User Experience. I honestly haven’t dug around enough to solve this issue since the nature of callback is just like that. Putting timeout and synchronization variables don’t seem to suffice…

Wait, so what about setTimeout and setInterval and stuff, aren’t they supposed to give a better control? Well FYI, setTimeout to 1000ms doesn’t mean it’ll get executed after 1000ms. It means that’ll get executed after AT LEAST 1000ms (cause it’s a queue…) so yeah, still digging around.

Back to my project which is a CMS now might turn into an RDS, I honestly think all we need are those important features listed above. Worst case is that we write a thin layer of wrapper around the tools we want to use, then invoke shell processes for those. But anw, it comes down to a light, thin server framework cause we probably don’t need all the big guns (which can take tons of time to tune). So yeah, it’d be great to set foot on that!!!

 

Tagged , , ,

Uhhh… exams? Nah I’ve over it!!!! Let’s do some web stuff

So it’s our final exam week and I only have 1 exam on Tuesday which I don’t really care since I’m graduating. Sounds irresponsible but I’ve been waiting for this chance to come my whole college life!! Yeah to all you underclassmen haterz I’m DONE! 😛

Anyway I did go to see Ironman 2 and it WAS GOOD!!! It was funny and witty and of course the gadgets are cool. One thing I would comment is that I shouldn’t have watched all the trailers and read all the news cause those are spoilers!!! They put out all the best scenes in the trailers so the movie would have been 1000x better had I not watched those!! If you haven’t watch Ironman 1, watch it ASAP, then watch Ironman 2!! HIGHLY RECOMMENDED STILL

That aside, I’m actually really deciding between being a Web Developer and a Software Engineer. Web Developer is more “hip” and dynamic IMO. Software Engineer is more sorta low-level, which is something I do enjoy but Web Developer delivers a nice blend between front-end and sometimes back-end. Our MetaDB project is pretty back-end heavy so I sorta apply a lot of those SE principles on the front-end. I think it makes things a bit more organized but not very intuitive.

Web Development really splits out into 3 main components:

  1. Structure: That’s the HTML, XHTML codes. They define what content will be on the site but most of the time not how it looks
  2. Presentation: That’s Cascading StyleSheet (CSS). This decides what components look like and coming up with a clean CSS is pretty hard
  3. Functionalities: That’s JavaScript or any sort of server-side scripting like PHP, Ruby on Rails, JSP, .NET and all that. Those determine what the components will do

Now it’s 1 of those basic principles in SE to not mix those up. We have a lot of bad examples, like Volkswagen website below:

Volkswagen on the outside

Volkswagen on the outside

Now the outside looks very simple and elegant. But if u pop the hood, it’s a pretty bad mixture of inline CSS, HTML and JavaScript, which makes things really really hard to read and maintain:

Volkswagen under the hood

Volkswagen under the hood

Now it’s easy to criticize and everything but I don’t really blame the IT Dept. This sort of syntax and technology was probably pretty outdated and there’s a lot of steps to take if you wanna change a big corporate’s main page. I’ve had similar experience with bureaucracy here at Lafayette. Things here move pretty slowly and get forgotten sometimes.

One of those very important things I learned when working in MetaDB is to negotiate with my boss. There’s always tradeoffs!! ALWAYS!! The main tradeoff in web development is pretty much beauty and efficiency. Beauty can mean complicated HTML/CSS and various image div tags. Those are certainly not cheap.

One of those techniques that got used back in like Nintendo 64 is called “Image Sprite”. That is, if you have a bunch of icons, don’t save them separately cause the overhead is just too costly. Instead, you dump them all together in 1 big image file then offset within to get a certain piece, it’ll be more efficient since it’ll be loaded so many times the browser caches it automatically!!

Yup that’s 1 piece of my open-source experience that I really wanna share. Have fun and keep on rolling guys

Tagged , , ,

Apple gone wild??

Aight so I just found out (after 3 days) that the reporter Jason Chen who was writing articles on the lost iPhone (which he purchased for $5,000) just got his home razed!!! By the (Apple) Police!! Dang, talking about freedom of speech right there.

The story is that he was chilling with his wife having 1 of those romantic dates. After that they came back home only to find out the police was BROKE through the front door and seizing his properties. He kinda expected this and didn’t flip out or anything. But I mean this is pretty crazy how Apple handled the situation of a leaked prototype, which was their fault in the beginning. In case you don’t know, the one who found iPhone 4G was trying to give it back to Apple by calling Customer Service but of course they are not aware of such product so he just received a ticket number instead.

Jason Chen Search Warrant

Jason Chen Search Warrant

I guess Apple was making sure that he didn’t uncover any trade secrets from the phone that he didn’t publish, but this is a bit too much. You can see the details right here. Honestly I feel really bad for the guys, he lost like 4 computers and 2 servers and a whole bunch of other stuff. Bad Apple!!

John Stewart also made fun of it as well and he’s funny:

Ok so that’s that. My friend Pooja also asked me for a list of like HTML tutorials and stuff so here’s my 2 cents:

First of all HTML is a markup language (HyperText Markup Language is what it stands for). It relies heavily on web browser to actually display the images and buttons and stuff. There’re a lot of editing tools for it, including WYSIWYG and normal text editor. WYSIWYG stands for What You See Is What You Get, with more precise definition here. Those tools give you a better visualization of how things are gonna look like but it also shows lack of professionalism since it kinda shows that you don’t really understand HTML, thus not knowing what it will look like.

One of those WYSIWYG tools are Dreamweaver by Adobe, which is heavily used . Dashboard by Apple is also one of those, but geared more towards Safari and Safari Mobile (or iPhone Safari browser). Technically you don’t need those but for beginners they might be very useful. Remember HTML is just text so any text editor would do.

Some of the good tutorials I found are:

W3School: Yeah this one has tutorials on HTML/CSS/JavaScript and those are pretty short and precise.

Principle of Beautiful Web Design: This book is awesome. It teaches u the very basic web design stuff with a certain level of technicality.

Learning Web Design: Another one, more technical and basic, also a pretty good source.

So probably that’s enough to get you started. Have fun and keep on designing!!! And Apple is bad this time, BAD!!

Tagged , , , , ,

Redesigning my site!!!

So I’ve been a bit late in blogging today (normally I blogged at like 2a.m) cause I’ve been working on a new skin for my website. I got bored after looking at it for a while so a redesign would also help keep my creativity fresh. Also there’re a lot of awesome professional web designs out there that brought to my attention so I’ll dedicate this post to some of them. So this’s what I have so far as the prototype:

Prototype Site

Prototype Site

So I’ve tried to simplify it and keep focus on certain parts of the site. I also tried to minimize all the descriptions and stuff since reading is not really that fun in general. Hmm what else, oh brighter background and tetradic color scheme. The glasses in the background are the closest ones to mine that I can find on stock xchng. BTW, if you want high quality plain images of objects, go to stock xchng at http://www.sxc.hu/. They have really really high-res pictures. Of course it’s non-commercial and for personal use only.

I also found out that my domain is surprisingly close to another domain called azndesign (mine is azndezign). Coincidence lol! The guy is also Vietnamese and is a graphics & web design. He’s much more experienced than me though. Anyway, besides stock xchng, you can also visit http://colorschemedesigner.com/ for color scheme generator (wait I think I mentioned that).

For inspirational purpose, you can check out some of the top web designs right here:

http://www.thebestdesigns.com/

Also here are the best CSS website collection:

http://www.csselite.com/

Some of my favorite ones are here:

Aaron Beall

Aaron Beall

Morphix

Morphix

N-Design Studio

N-Design Studio

Oh btw CSS websites refer to non-flash web. I myself am not a big fan of flash although it’s a very strong animation format. Well first of all Mac can’t run flash, yeah Flash will burn your Mac processor. It’s an architecture problem so it’s unlikely its gonna get fixed soon.

Flash is also not compatible with iPhone so you have to maintain 2 versions of your site, which is a pain. Flash also requires flash plugin and that leads to some additional security issues. Yup so stick with XHTML/CSS + JavaScript. Aaron Beall’s site is just too awesome I gotta make an exception for it. Kk guys have fun and keep on designing!

Tagged , , , , , , , , , ,

Web 2.0 Stuff… hmm Part 1 I guess – FONT!!

Now in case you don’t know what Web 2.0 is, it’s pretty much everything you use nowadays including social media like Facebook, YouTube and all that. It’s a new trend of web design both in terms of visual interface and technology. The technology part I believe is mainly the development of AJAX (Asynchronous JavaScript And XML), which gives you the ability to push/pull specific part of your website without reloading the page, like what I did with my personal homepage right here: http://www.azndezign.com

Anyway to me AJAX is really cool since you might have realized a big part of a website might be its template. Well it’s also useless to reload the template cause it’s not gonna be changed until the webmaster upgraded the site itself (like Facebook changed its template 125816 times in like 3 months). Thus, web becomes more efficient, data gets packed into its very raw form and then made beautiful once its gets to your Firefox (or IE/Chrome/Safari) browser, saving you Internet traffic bill every month (yes!).

The more impressive part of web 2.0 is the significant change in visual interface, particularly the elimination of using tables with “spacer.gif” (yeah I hate spacer.gif so much) and switch to liquid/fixed/hybrid div tags which are cross-browser compatible and visually stunning also. In this 1st part I’ll talk about FONT!!!! Yes web 2.0 font is nice and elegant for sure.

So let’s see… I believe there’re 2 main font family: serif and sans-serif. What is serif? serif indicates the stroke at the tail of the letter like Times New Roman font:

Serif fonts

Serif fonts

I saw serif fonts more often in headlines and sans-serif in the body, probably because too many strokes confuse your eyes. You can read the details on Wikipedia so let’s not dive into history too much: http://en.wikipedia.org/wiki/Serif

So what is sans-serif? sans-serif fonts don’t have those strokes. They look more fresh and creative than the traditional mentioned fonts. Arial is 1 example of sans-serif but for web 2.0 I see a lot of people using Helvetica.

Helvetica Font

Helvetica Font

Most computers do support this font. Otherwise, Verdana is also equally nice and is a web-safe font just like Times New Roman. In general I believe there’re 9 web-safe fonts that are on both Windows and Mac OS X:

9 Web Safe Fonts

9 Web Safe Fonts

As you can see, there’re only 3 serif fonts out of 9, which means sans-serif is taking over (soon).

Besides choosing a nice font-family, a reasonable font size is also necessary. 12pt seems to be the common standard that works in most screen resolution. You don’t want the font size to be too large, which can cause pixelation and make you page look totally ugly. Of course too small means people can’t read your page properly.

In addition, you can incorporate your own fonts using CSS (Cascading Style Sheet). For example I use Ubuntu font for my navigation bar in my homepage:

@font-face {
font-family: "Ubuntu";
src: url(fonts/ubuntu.ttf) format("truetype");
}

Ubuntu Font

Ubuntu Font

This font looks kinda cute, clearly sans-serif but requires additional rendering from the browser. Also it’s a good practice to fall back on a traditional font if your computers/web browsers do not support those. You can do that in CSS:
font-family: Helvetica, Verdana, Arial, sans-serif;

What this does is it tries to render the web page using those fonts in priority. 1st priority is Helvetica (my favorite), if Helvetica is not available, then Verdana, then Arial, then any type of generic sans-serif fonts that computer has. You can change this weight by adjusting
font-weight: bold;

if the font supports bold text. Now if you’re good at graphics design and typography and all, you can even make your own font. Making a new font is rather complicated since you must follow a specific set of rules

Anatomy of Letterform

Anatomy of Letterform

So there you go, pick your favorite font or make your own and keep on designing!!

Tagged , , , , , , , ,

How to make a combobox with jQuery

So jQuery came out with a new version 1.4.2 recently and jQuery UI is trying catch up with its 1.8rc3 since 1.7.2 is not compatible with the new jQuery library itself. Since jQuery UI starts incorporating its own theme builder tool, I’ve been using it and it seems to be very nice and elegant itself.

jQueryUI has its own autocomplete feature and button so I just wanna combine them together to make a combobox, which acts as both a select box and an autocomplete field.

So the HTML is like this:

<input id="example-text-field" type="text" /><button></button>

Well you can dynamically adding the button and even the text field using jQuery manipulation method

We start with configuring the autocomplete text field first.

var $input = $('#example-text-field');
$input.autocomplete({
   source: 'ExampleAutocompleteServerHandler.do', //you obviously need the source, it can be a JavaScript array or string or some handler from the server
   minLength: 0, //important! You need to set minLength to 0 for the button to work
   delay: 0 //make it a bit faster since there's no delay
})
.css('float', 'left');

So the text field is done, now let’s move on to the button next to it:

var $btn = $input.siblings('button:first');
$btn.button({
   icons: {
      primary: "ui-icon-triangle-1-s" //this puts the down arrow into the button
   },
   text: false //no text inside the button, just the arrow
})
.removeClass("ui-corner-all")  //disable rounded corner, it's optional
.addClass("ui-button-icon")   //put in styling as a button icon since the default button is pretty big
.css({
   height: "17px",    //make it as high as the text field
   width: "18px",    //this is optional, you can make it as wide as you want
   float: 'left'    //float it to the left so that it's right next to the text field
})
.unbind('click')   //it's optional but I like to clear all events associated to it before binding new click event
.click(function() {   //set up click binding event
   if ($input.autocomplete("widget").is(":visible")) {   //close the displaying result if it's visible already
      $input.autocomplete("close");
      return false;
   }
   $input.autocomplete("search", ""); //pass empty string as search query, this is why you need to set minLength = 0 so that it still searches, but displays all possible choices
   $input.focus();  //focus on the text field
   return false;  //disable form submit
});

$input.parents(':first').find('.ui-autocomplete') //configure result display so that it won't shift down the content
.css('width', '150px')
.css('height', '100px')
.css('overflow', 'auto');

There you go, combobox is done, you can pack it into a plugin with jQuery or inside your main JavaScript file, up to you.

Tagged , , , , , ,