jQuery UI - Sorting tabs and remembering positions



Article Index

Just now digging into the archives of Google and not found a normal solution of this problem. All the proposed options have only worked in one of the variations - or only with the sortable pluging, or only with the cookie plugin.

So, let's begin.

We need the following libraries and plugins.

jQuery 1.6.4 version or later. If you want to adapt the code under an older version, simply replace the prop() for attr()

jQuery UI 1.12+ and above with modules Core, Widget, Mouse, Sortable, Tabs

JavaScript Cookie

Demo

Javascript code looks like this:

jQuery(document).ready(function($){
	$('#tabs1').tabs().find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			Cookies.set($(this).parent().attr('id'), $(this).sortable('toArray').toString(), { expires: 365 });
		}
	});
	$('#tabs2').tabs().find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			Cookies.set($(this).parent().prop('id'), $(this).sortable('toArray').toString(), { expires: 365 });
		}
	});
	$('#tabs3').tabs().find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			Cookies.set($(this).parent().prop('id'), $(this).sortable('toArray').toString(), { expires: 365 });
		}
	});

	function restoreOrder(selector){
		var $selector = $(selector),
			cookie = '',
			IDs = [],
			items = [],
			rebuild = [];

		if (!$selector || $selector.length < 1) return;

		$.each($selector, function(key, object){
			if ($(object).hasClass('ui-tabs')) {
				cookie = Cookies.get($(object).prop('id'));

				if (cookie) {
					IDs = cookie.split(',');
					var li = $('ul', object).children('li.ui-tabs-tab');

					$.each($(li), function(i, o) {
						items.push($(o).attr('id'));
					});

					for (var v = 0; v < items.length; v++) {
						rebuild[items[v]] = items[v];
					}

					for (var i = 0; i < IDs.length; i++) {
						var itemID = IDs[i],
							item = rebuild[itemID],
							child = $('.ui-tabs-nav', object).children('#' + item),
							savedOrd = $('.ui-tabs-nav', object).children('#' + itemID);

						child.detach();
						$('.ui-tabs-nav', object).filter(':first').append(savedOrd);
					}
				} else {
					Cookies.set($(object).prop('id'), $('.ui-tabs-nav', object).sortable('toArray').toString(), { expires: 365 });
				}
			}
		});
	}

	restoreOrder('#tabs1, #tabs2, #tabs3');
});

And html code:


<div id="tabs1">
	<ul>
		<li id="li-1-1"><a href="#tabs-1-1">1 Nunc tincidunt</a></li>
		<li id="li-1-2"><a href="#tabs-1-2">2 Proin dolor</a></li>
		<li id="li-1-3"><a href="#tabs-1-3">3 Aenean lacinia</a></li>
	</ul>
	<div id="tabs-1-1">
		<p>Content for tab1</p>
	</div>
	<div id="tabs-1-2">
		<p>Content for tab2</p>
	</div>
	<div id="tabs-1-3">
		<p>Content for tab3</p>
	</div>
</div>

ID attribute for li is required!