Posted (Updated ) in Uncategorized

JQuery UI supports a really handy feature called content via AJAX whereby when you click/display a tab, it will create a div element to load your content into, then perform the AJAX call and drop it in. But what happens when you want to specify the element to load the AJAX request into? Thankfully after a bit of digging around it’s not only possible, but pretty easy.

Here’s an example of AJAX load with JQuery UI Tabs:

1
2
3
4
5
6
7
<div id="tabs">
    <ul>
        <li><a href="ajax-content-1.html">Tab 1</a></li>
        <li><a href="ajax-content-2.html">Tab 2</a></li>
        <li><a href="ajax-content-3.html">Tab 3</a></li>
    </ul>
</div>

And here’s how you can specify the panel elements. Simply add an aria-controls attribute to your tab LI element that points to the ID of your target panel element:

1
2
3
4
5
6
7
8
9
10
11
<div id="tabs">
    <ul>
        <li aria-controls="my-first-tab"><a href="ajax-content-1.html">Tab 1</a></li>        <li aria-controls="my-second-tab"><a href="ajax-content-2.html">Tab 2</a></li>        <li aria-controls="my-third-tab"><a href="ajax-content-3.html">Tab 3</a></li>    </ul>
 
    <div id="my-first-tab"></div>    <div id="my-second-tab"></div>    <div id="my-third-tab"></div></div>

 

Demo

Read More »

Posted (Updated ) in Uncategorized

If you refresh or come back to a site often, it’s handy to have JQuery UI tabs remember which tab you were last on as you left. This simple script will handle that for you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
jQuery(function($) {
    var index = 'qpsstats-active-tab';
    //  Define friendly data store name
    var dataStore = window.sessionStorage;
    var oldIndex = 0;
    //  Start magic!
    try {
        // getter: Fetch previous value
        oldIndex = dataStore.getItem(index);
    } catch(e) {}
 
    $( "#tabs" ).tabs({        active: oldIndex,
        activate: function(event, ui) {
            //  Get future value
            var newIndex = ui.newTab.parent().children().index(ui.newTab);
            //  Set future value
            try {
                dataStore.setItem( index, newIndex );
            } catch(e) {}
        }
    });
});

No other code is necessary. Add your tab markup as you normally would (Remember to give it a matching ID):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="tabs">	<ul>
		<li><a href="#tabs-1">Tab 1</a></li>
		<li><a href="#tabs-2">Tab 2</a></li>
		<li><a href="#tabs-3">Tab 3</a></li>
	</ul>
	<div id="tabs-1">
		first tab
	</div>
	<div id="tabs-2">
		second tab
	</div>
	<div id="tabs-3">
		third tab
	</div>
</div>

 

Demo

Read More »

Posted (Updated ) in Javascript

Despite a global shift towards touch-oriented devices on the internet and the existence of a relatively old bug report, Google has decided not to add support for mobile/touch to their ChartRangeFilter for Google Charts (as of the time of writing). See for yourself:

Demo | Source – Doesn’t work on mobile. Frustrating!

This is really annoying, especially if you are dealing with a significant chunk of data that could take advantage of this functionality by allowing users to ‘zoom in’ on specific areas.

 

A Workaround (For Now)

Although we can’t get the ChartRangeFilter working on mobile, we can display something else instead for mobile devices such as the handy jQRangeSlider. To do so we’ll need to hook into the methods provided by google.visualization.ControlWrapper (which sits around the ChartRangeFilter).

In the source we have:

var controlWrapper = new google.visualization.ControlWrapper({
	controlType: 'ChartRangeFilter',
	...
});

We can update the selection in the ChartRangeFilter by calling the following on its ControlWrapper:

controlWrapper.setState({
	range: {
		start: new Date(2004, 01, 01),
		end: new Date(2006, 01, 01)
	}
});
controlWrapper.draw();

Combine this with a mobile UA check (terrible I know, but you can’t really use browser  feature detection for this) and a DateRangeSlider (I’m using dates on my X axis) and you get the following:

var is_mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
// ChartRangeFilter doesn't work on mobile. Use a dateRangeSlider to manipulate it
if ( is_mobile )
{
	$('#filter').hide();
	$('#filter_mobile').show();
 
	$( "#filter_mobile" ).dateRangeSlider({
		bounds: {
			min: new Date(2001, 1, 1),
			max: new Date(2013, 3, 1)
		},
		defaultValues: {
			min: new Date(2001, 1, 1),
			max: new Date(2013, 3, 1)
		},
		step: {
			months: 1
		},
		arrows: true,
		wheelMode: null
	}).bind('valuesChanged', function(e, data) {
		controlWrapper.setState({range: { start: data.values.min, end: data.values.max }});
		controlWrapper.draw();
	});
}

Demo

ChartRangeFilter workaround for mobile devices

ChartRangeFilter workaround for mobile devices

Try the demo below. View it on a mobile device (or use a mobile UA string). You get the standard Google Charts ChartRangeFilter for desktop and jQRangeSlider for mobile. Everything works nicely!

Demo | Source – Snazzy mobile-specific date range widget

Read More »

Posted (Updated ) in Javascript, PHP

JQuery Data Tables is an incredibly handy tool that can make a developers life alot easier – notably by handling search, pagination, filtering and sorting for you. The default functionality is very good, however you’ll often need a bit of customization. This post will detail how to add custom filters and position them to nicely theme with your table. The filters’ state will also be saved so they’ll still be there if you reload the page.

You can see the demo page for this post here. Select a filter and reload the page to see it in action.

Read More »

Posted (Updated ) in Javascript

I discovered recently a little quirk with accessing a JQuery UI Dialog‘s options and methods from within the dialog itself. I was AJAXing the dialog’s contents and was having difficulty figuring out how to access the dialog’s methods. As it turns out, from the contents of the dialog you don’t use

$(this).closest('.ui-dialog').option()

which returns a javascript object, but instead use

$(this).closest('.ui-dialog-content').option()

Seeing as this post would otherwise be pretty short, let’s do a little more than simply retrieving options. Below I’ll explain not only to open a AJAX dialog from a HTML link, but also tell the dialog what element opened it. This could be useful in such instances as when you need to click a link which opens a dialog allowing you to upload a user avatar, and upon uploading, replaces the link with the avatar image.

For the lazy, you can download the complete tutorial files here.

Read More »