Category Archives: jQuery

Make Bootstrap Nav Tabs remember what was last selected

I’m prototyping an app in Bootstrap and using Nav Tabs as part of it. I wanted a way to make it so if you had a certain tab selected last time you were  on the page, wen you return, that same tab would be preselected.

I accomplished this by setting a cookie each time a tab is picked, and then checking for that cookie on page load, and if it exists, read it back and open the right tab.

This example uses the jQuery Cookie plugin.

	$("ul.nav-tabs li").on("click", function() {
		var cookieName = 'tab-'+document.URL.replace("/", "").replace(":", "").replace("%", "").replace("#", "");
		var cookieValue = $(this).find("a[role='tab']").attr("href");
		$.cookie(cookieName, cookieValue);

Part 1: Any time a tab is clicked, save a cookie describing which tab it was, on which page.

Line 2: Select any nav tabs on the page, attach a click listener.
Line 3: Make up a cookie name, based on the current URL. Strip out all the special characters in case a browser doesn’t like them in cookie names. That should make a pretty unique identifier for this page right?
Line 4: Get the anchor element inside this tab’s LI element, and find it’s href. That should be a unique identifier for that tab.
Line 5: Save the cookie.

	var cookieName = 'tab-'+document.URL.replace("/", "").replace(":", "");
	if ($.cookie(cookieName)) {
		$("ul.nav-tabs li a[href='"+$.cookie(cookieName)+"']").click();

Part 2: Look up any cookies related to this page, and if we find one, read it and repick the related tab.

Line 2: Divine the cookie the exact same way we did before.
Line 3: See if there’s a cookie by that name
Line 4: If there is, find the tab, and the anchor within it, that matches the one we name of in the cookie, and click it with Javascript.

Simple way to make screens/steps/pages/views for a web app with a little jQuery.

This isn’t the way to build a huge web app, and it’s not super performant, but if you need to alternate between screens in a web app, this is one way to do it.

For what it’s worth, you get similar functionality built into all the JS frameworks; Angular, Backbone, Ember, even jQuery UI. Those ones mostly have each page in separate files, and they load the new page via AJAX, and swap out the content on the fly. We’re going simpler– all our pages will exist the whole time, and we’ll write logic to show and hide them.

Here’s an example on CodePen:

First, make your screens. I’ve called them “pages” in my code, and they’re really just divs with the class .page

<div class="page" id="home">
	Home page content
<div class="page" id="page2">
	page 2 content
<div class="page" id="settings">
	settings content

Now, in a JS file, let’s write a script to hide all but the first page. It’s simpler than you might think. In human language, this reads “get me all the pages, hide them, narrow the selection down to just the first one, show it.


Of course, that should be inside a document ready. Everything in jQuery should be inside a document ready.

Next, let’s add some links to the pages, that will take us from page to page.

<div class="page" id="home">
	Home page content<br />
	<a class="pagelink" href="#page2">Take me to page 2</a>

See how that new link has a class, page_link, so we can treat it specially, and it’s href isn’t to a URL, or even an anchor on the page (not one that exists anyway), it’s to the ID #page2. That won’t do anything yet, we haven’t wired it up yet.

So let’s make the links work. Back in the JS file:

$(".page a.pagelink").on("click", function(e) {
	var newPageID = $(this).attr("href").replace("#", "");

So when any .pagelink get’s clicked, we…

  1. prevent the browser from it’s default behaviour (navigating away from this page, to the link)
  2. getting the href of the link (remember, it’s actually an ID for another “page” in our app), and trim off that pesky “#”.
  3. call a new function we haven’t written yet called changePage, with the ID of the page we want to see.

From there, it’s a case of hiding whatever page is currently visible, and showing the new one, the one that ID we just found, refers to. Of course, you’ll want to replace the animation with whatever suits your app.

function changePage(pageID) {

This might be enough for some apps, but I want to add a couple more things.

First, the reason I made changePage a separate function– we can call it from anywhere.  A form validator could call it if validation is passed. A game timer could call it after a certain amount of time (example below).

setTimeout(function() {
}, 30000)

Let’s add a new feature- events for when a page is shown or hidden.

function changePage(pageID) {

Adding the above lines makes each page fire two new events, one when the page is hidden, the other when it’s shown. To listen for those events, and say, start a game timer when the user reaches the game page, would be something like this:

$(".page#game").on("show", function() {
	setTimeout(function() {
	}, 30000);

So there you have it, a basic paged web-app in a few dozen lines of jQuery.

Why we (mobile website designers) need to learn CSS animation.

I got a comment on an earlier post about making animation look better on mobile, and there seemed to be some confusion about using javascript animation versus css animation, when targeting mobile browsers. I wrote back and explained my thoughts, but I thought it might make for a good post too. So here goes…

It is absolutely vital for mobile developers to learn CSS animation instead of javascript.

The reason is that Javascript is actually very inefficient for animation, and it’s only recently, with the proliferation of mobile browsers, that we are starting to notice this. If we had been trying to do javascript animation on the computers we had back in the late nineties (which were of similar power to our current mobile phones), we’d have seen it then.

You see, with a JS animation (e.g. created using jQuery’s animate function), the javascript library sets an interval timer (lets say, 33ms, which is about 30 frames per second), and on that interval, it figures out where the animated element should be, using some pretty complex math calculated by the CPU, and then puts it there. Unfortunately, if the CPU is too slow to do that calculation every interval, it gets backed up and the animation stutters. jQuery and other JS animation tools do some work to combat this, sensing a drop in frame rate and trying to make the interval wider, to give it more time to complete the calculations, but it’s often too-little-too-late.

On the other hand, when you do a CSS animation (e.g. using the transform or webkit-transform css properties), you leave it to the GPU to simply calculate where the element should be as often as it can. As soon as it calculates the element’s new position and places it there, the GPU starts the calculation again. This means the animation is always as smooth as the GPU can possibly make it, no matter what. If you animate too many elements for the GPU to handle it may still have trouble, but instead of ugly stuttering, it will be a more graceful drop in framerate.

That’s why CSS animation is a must for mobile targeted websites. The good news is that all mobile browsers (the ones we care about anyway) support CSS3’s animation techniques, so there’s no need for capability detection and fallbacks.

Fix: CSS Animation slow or choppy in mobile browsers

EDIT: DONT DO THIS. It breaks z-index rules sometimes on modern webkit based browsers.

I’m developing an iPhone app using the PhoneGap library, which lets you write your app as if it were a website. That means any UI transitions or animations have to be written the way you would for any modern website targeting Webkit: CSS3 transitions (mobile javascript is too slow for frame by frame calculations).

Unfortunately, CSS transitions can be a little slow, a little choppy, even on iPhone 4 and the faster Android based phones. The problem is that, by default, webkit doesn’t involve the GPU unless you’re doing 3D transforms. With desktop horsepower, thats fine. On a mobile device, that GPU could really help.

So how do you force webkit to share the processing load with the GPU?

Apply this style to the element you’re animating:

-webkit-transform: translateZ(0);

Simple, but effective.

TypeKit (@font-face) font’s look like crap in IE7 & IE8 when animated with jQuery

Internet Explorer does a pretty lousy job of displaying fonts anyway, especially fonts from all those new we font websites such as TypeKit (who I strongly recommend). But when you use, say, jQuery’s fadeIn() effect like this


… type looks like crap all the way through the animation, and stays that way after.
Crappy type after animating

The reason for this is a bad implementation of “filters” in IE. “What are filters” you ask? Well while the rest of the web was being standardized to make our lives easier, Microsoft was ignoring the new standards and making up their own, worse looking and harder to write versions. jQuery hides all that from us by turning your fadeIn() into the appropriate filter code in IE, or opacity code in everything else.

There are 3 fixes.
1) Avoid the problem. That means using a non-typekit font, or using an image of the type (which means it won’t be selectable, and google can’t see it).

2) Partial fix: At the end of your fadeIn() you can tell IE to drop all filters from the element. This isn’t great because it means that the type will still look like crap all the way through the animation, and then snap to normal looking (which is still not great in IE) at the end. Code for that below:

$(".fadeThisGuy").fadeIn(400, function() {
	$(this).css('filter', "");

3) “Graceful degradation”. The buzzword “graceful degradation,” refers to the act of checking the capabilities of your visitor’s browser, and scaling your awesomeness back to fit what their browser can do. They should still get the same website, just without the bells and whistles their browser can’t handle.

In this case, we’re checking for IE, and whether it’s version is < 9.

if ($.browser.msie && parseInt($.browser.version) < 9) {
	// dumb it down for old IE 6, 7, and 8
} else {
	// regular awesomeness for people who know how to use Windows Update

As an alternative to a fadeIn() and fadeOut() I’d suggest either a simple show() and hide(), or any of the other jQuery Effects that don’t have to do with opacity/filters. You can find a list of jQuery effects here in the effects section.

Make your own live, auto-updating data feed with PHP (CodeIgniter) and Javascript (jQuery)

EDIT: I guess you don’t need to store the last entry time in a cookie, storing it in a simple js var works fine. I’ve updated the code to reflect this.
EDIT2: If your server isn’t doing a good job of responding to the queries for the last entry time, and it’s just sending 304 Not Modified every time, then you can add a random GET var on the request, so it always give you a fresh copy. Takes more resources though.

	url: "latest_report_time.txt?" + Math.floor(Math.random()*10000),

Original Post:
I’ve been working on a webapp recently which involves users in the field sumbitting reports, and users back at the office seeing those reports as they come in. Eventually I’ll probably set it up right, with true two way communication between the field users and the office users, via an XMPP server, but in the meantime I went with a simpler approach.

Here’s what I came up with.

1) When a field user submits a report, it goes into the database as you would expect, but a new function I wrote just for this purpose also does something else, something very simple, it replaces a text file on the server with the current timestamp. Note that its a simple .txt file and that the single timestamp of the latest report is all it contains. That way there’s no PHP overhead when someone looks at that file, and if they’ve already looked it up once and it hasn’t changed, the server will return a 304 not modified message, and the browser won’t even download the file. Very efficient.
In CodeIgniter, that code looks like this, but it could be done in any framework, or plain old PHP.

$timestamp = now();
write_file('latest_report_time.txt', $timestamp);

2) When an office user opens a page in their browser that is meant to be auto-updating, a new javascript is run. All that script does is look up that file we made, latest_report_time.txt, every 5 seconds, and checks to see if the timestamp in it has changed since the last check (which was saved in a cookie on the last check). Note that I’m using jQuery and a very jQuery plugin called jQuery Cookie, but you could do this in any JS framework, or plain old JS.

setInterval(checkForReportUpdates, 5000);

var oldLastReportSeen = 0;
function checkForReportUpdates() {
		url: "latest_report_time.txt",
		success: function(data) {
			var newLastReportSeen = data;
			if (oldLastReportSeen != newLastReportSeen) {
				console.log("New report found, get it and set new cookie");
				oldLastReportSeen = newLastReportSeen;
			} else {
				console.log("No new reports");
				oldLastReportSeen = newLastReportSeen;

3) Finally, if the timestamp on the server has been updated, do another ajax call to grab the latest report. I leave the rest of this up to you, because the structures of our sites are probably very different, but you’ll probably end up writing some of your own logic to check to make sure the newly fetched report is not one you are already showing, and then use jQuery’s prepend() or append() to insert it into your page.

function getNewLatestReport() {
		url: "reports/latest",
		success: function(data){
			if (/*check for duplicates here*/) {

Load more content as the user reaches the bottom of your page, with jQuery

I recently built a project gallery for Primal Screen’s new website (not live yet). Instead of having the traditional < 1 2 3 4 5 > pagination setup, we decided to take a leap forward into the the world of modern browsers, ajax, and users with very short attention spans. In this on-demand world, we load the content as needed: when the user hits the bottom of page one, page two is loaded and appended, and so on until you run out of content, or the user’s scroll wheel breaks. It’s a never ending page, without a never ending load. You may have seen this functionality in the Firefox plugin, AutoPager, or the Chrome/Safari plugin AutoPagerize.

Anyway, basically it works like this:
1) User loads page with 15 thumbnails on it
2) User scrolls to bottom of page, triggering a jQuery event we set up
3) 15 more thumbnails appear like magic or voodoo or mindreading or something and the page gets longer! Without even clicking!
4) User scrolls some more, hits bottom of page again, jQuery event fires again and
5) 15 more thumbnails appear and the page gets longer, further blowing the user’s mind!
6) ?
7) Profit.

alreadyloading = false;
nextpage = 2;

$(window).scroll(function() {
	if ($('body').height() <= ($(window).height() + $(window).scrollTop())) {
		if (alreadyloading == false) {
			var url = "page"+nextpage+".html";
			alreadyloading = true;
			$.post(url, function(data) {
				alreadyloading = false;

Line 1 is a state variable. We set it to true when we start loading a new page, false when it's loaded and shown, and before we load a new page we check to make sure the variable is set to false to ensure that we don't try to load page three before page two is done loading.
Line 4 Standard jQuery scroll event. This fires several times per second when scrolling in a modern browser, but on old browsers it just fires once when you stop scrolling.
Line 5 Here we check to see if the user is at the bottom of the page.
Line 6 Here we check to make sure we aren;t already loading a page.
Line 7 This is where the magic happens. $.post is a jQuery function that loads the url you give it in it's first parameter, and runs the callback function you give it in it's second parameter (and that function get's the loaded data in it's one and only parameter, did you follow all that?).
Line 8 Now that we have the loaded page, we have to put it in our existing page. Translated to english, this line reads "find the element with the ID: galleryThumbsCol, find it's last child, and put the loaded data in after that child.
Line 9, 10 Then we set our variables so we're ready to load the next page.

Find the Pixel perfect position of an element with jQuery (and keep elements always visible)

If you need to know the exact x and y positioning of any element on your page (relative to the viewport), use jQuery like this.

var x = $("#myElement").offset().left;
var y = $("#myElement").offset().top;

Then you can do stuff like this

$(window).scroll(function() {
	var y = $("#myElement").offset().top;
	var scrollY = $(window).scrollTop();
	if (scrollY > y) {
		var padY = scrollY - y;
		$("#myElement").css("paddingTop", padY);

This script would compare your scrollbar’s position and the position of the element, #myElement, every time you scroll (several times per second on good browsers, when you let go of the scrollbar on bad browsers). Then, if the top of the element is above the top edge of the viewport, it adds some padding-top to it to keep it locked there at the top of the screen.

Use jQuery to attach an event to a key press

Keep in mind that some browsers don’t let jQuery know about certain key presses. For example, Chrome doesn’t send the event for keyCode 27 (escape), but Safari does.

$(document).keypress(function(e) {
	if (e.keyCode == 13) {
		alert("You pressed Enter!");

And here’s a list of all the available keyCodes for you to use.