jQuery UI - Сортировка вкладок и запоминание позиции



Содержание материала

Как-то порывшись в архивах Google так и не нашел нормального решения этой задачи. Все предложенные варианты работали только в одной из вариаций - либо только с плагином sortable, либо только с плагином cookie.

Итак, начнем.

Нам потребуются следующие библиотеки и плагины.

jQuery версии не ниже 1.6.4. Если хотите адаптировать код под более старую версию, то просто замените prop() на attr()

jQuery UI версии 1.12+ в конфигурации Core, Widget, Mouse, Sortable, Tabs

JavaScript Cookie

Демо

Код Javascript выглядит так:


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');
});

И html структура:

<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>

Для li обязательно нужно указывать ID!


Нам потребуются следующие библиотеки и плагины.

jQuery версии не ниже 1.6.4. Если хотите адаптировать код под более старую версию, то просто замените prop() на attr()

jQuery UI версии 1.8+ в конфигурации Core, Widget, Mouse, Sortable, Tabs

jQuery Cookie

Демо

Код Javascript выглядит так:

jQuery(document).ready(function($){
	function restoreOrder(selector){
		var lists_arr = $(selector),
			cookie = '',
			IDs = [],
			items = [],
			rebuild = [];
		if (!lists_arr || lists_arr.length < 1) return;
		$.each(lists_arr, function(key, object){
			if ($(object).hasClass('ui-tabs')) {
				cookie = $.cookie($(object).prop('id'));
				if (cookie) {
					IDs = cookie.split(',');
					items = $(object).sortable('toArray');
					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.remove();
						$('.ui-tabs-nav', object).filter(':first').append(savedOrd);
					}
				} else {
					$.cookie($(object).prop('id'), $('.ui-tabs-nav', object).sortable('toArray'), { expires: 365 });
				}
			}
		});
	}
	$('#tabs1').tabs({ cookie: { expires: 365 } }).find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			$.cookie($(this).parent().prop('id'), $(this).sortable('toArray'), { expires: 365 });
		}
	});
	$('#tabs2').tabs({ cookie: { expires: 365 } }).find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			$.cookie($(this).parent().prop('id'), $(this).sortable('toArray'), { expires: 365 });
		}
	});
	$('#tabs4').tabs({ cookie: { expires: 365 } }).find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			$.cookie($(this).parent().prop('id'), $(this).sortable('toArray'), { expires: 365 });
		}
	});
	$('#tabs6').tabs({ cookie: { expires: 365 } }).find('.ui-tabs-nav').sortable({
		axis: 'x',
		update: function(){
			$.cookie($(this).parent().prop('id'), $(this).sortable('toArray'), { expires: 365 });
		}
	});
	restoreOrder('#tabs1, #tabs2, #tabs3, #tabs4, #tabs5, #tabs6');
});

И html структура:

<div id="tabs1">
	<ul>
		<li id="t1"><a href="#tabs-1">1 Nunc tincidunt</a></li>
		<li id="t2"><a href="#tabs-2">2 Proin dolor</a></li>
		<li id="t3"><a href="#tabs-3">3 Aenean lacinia</a></li>
	</ul>
	<div id="tabs-1">
		<p>Lorem ipsum dolor sit amet, sciendum ait. Pentapolitanas Cyrenensi reversus est cum unde. Secundis sacerdotem filia dedit erat bene nostrae iam, quidditas mihi Tyrum in lucem exitum atque bona pater. Christo tunc Tharsos determinatio vestes periit patrem dixit est se in.</p>
	</div>
	<div id="tabs-2">
		<p>Athenagora mihi esse deprecor cum autem est cum. Facere consultum in deinde cepit roseo commendavit patris in. Verenam operibus furiam conclusoque sponte profundo. Nimis barbam cum unde tu illum decidat quam dicentes semper vide eis fictas fundatur sicut in modo.</p>
	</div>
	<div id="tabs-3">
		<p>Labore accusam in deinde vero rex Dionysiadi rex ut libertatem non dum veniens. Virginem in deinde vero quo alacres ad quia. Materia amicis filia in fuerat construeret cena reges undis effugere quod non dum animae tibi alloquitur hanc si Ave.</p>
		<p>Venis potest contremiscunt pater in. Pater vero cum magna Dianam. Athenagoram rigorem nisl cum autem illud huius. Tharsiae ortam adipiscing enixa ait est Apollonius non ait regem adventu nihil puella est Apollonius ut libertatem accipies. Tempor in rei exultant deo apprehendit, accepit Archistratis suae in deinde duas particularis.</p>
	</div>
</div>
<br />
<div id="tabs2">
	<ul>
		<li id="t1"><a href="#tabs-1">1 Nunc tincidunt</a></li>
		<li id="t2"><a href="#tabs-2">2 Proin dolor</a></li>
		<li id="t3"><a href="#tabs-3">3 Aenean lacinia</a></li>
	</ul>
	<div id="tabs-1">
		<p>Antiochia de tuae infami cum magna duobus consolabor potest ei primum intus ad per. Mauricii materialia sola habiturus in modo. Antiocho mittat est amet consensit cellula filia puella sed esse deprecor.</p>
	</div>
	<div id="tabs-2">
		<p>Lugens in rei sensibilium acciperem qui enim formam unitas reddere Dionysiadem. Coram te finis puellam flentem praemio unam lacrimae valete. Ut a his e neptem semper incurristi filiam sunt, permansit in modo cavendum es sed quod eam ad per. Cur meae ad suis Tyrium coniugem flebant Tharsiam, ratio omnes Hellenicus dixisset hoc Apollonius in fuerat!</p>
	</div>
	<div id="tabs-3">
		<p>Nuntiatur ad suis caelo in lucem exitum atque bona dei cenam inhaeret Visceribusque esocem manibus individuationis quod tamen ait. Palladio in fuerat est se vero cum autem nobiscum laetitia. Tempore Quaere allocutus ait est Apollonius in modo compungi mulierem ubi diu perdidi si quod tamen ait in.</p>
		<p>Priapum avarus videret quaeritur vero quo sanctis oravit in rei civibus laude clamaverunt donavit potest. Sordido triclinio laudes honore est se ad quia, euismod tollam impedit intra tectus Scrutor audire propter illa benignissime vi.</p>
	</div>
</div>
<div id="tabs3">
	<ul>
		<li id="t1"><a href="#tabs-1">1 Nunc tincidunt</a></li>
		<li id="t2"><a href="#tabs-2">2 Proin dolor</a></li>
		<li id="t3"><a href="#tabs-3">3 Aenean lacinia</a></li>
	</ul>
	<div id="tabs-1">
		<p>Quicumque enim materiam profusis magna anima Apollonium sit dolor virgo coniunx efficerer nuptiarum cui ut a. Nuptui tradiditque semper incommunicabile in lucem in lucem concitaverunt in deinde vero non coepit. Elige ipsa Invitamus me missam ne alicuius altum pervenit item ut a patriam ei quoque luctare non dum est Apollonius.
	Consuetudo aut veneris accedens est amet constanter approximavit te.</p>
	</div>
	<div id="tabs-2">
		<p>Stet consequat eiusdem ea commotio gaude haec aliquam inlido laetare quod non dum est amet Cur meae. Singulas noveras aliqui civitatem in rei civibus in lucem. Permiseras enim est Apollonius eius ad per accipere filia in rei sensibilium iussit hoc. Ni fluctus evasit dic ipsum se sed dominum oculos, antiocho mittat est amet amet constanter determinatio debitis torporis quin.</p>
	</div>
	<div id="tabs-3">
		<p>Recedite fit proponebat vidit ad te ad per. Dona abstulit meis dolor virgo. Retrorsum redire ad suis est in. Item filiam vel ita per sanctus ait est se sed dominum sit audivit illius generositas mihi cum suam in. Amen ad per sanctus primum subsannio oculos ut sua.</p>
		<p>Materia ad suis alteri ad quia ei. Plus istum igni ait regem ut casus adprehendens melius ait in lucem exitum atque bona dei. Salve quos vero rex in rei sensibilium acciperem qui auri tecum mortis remisit piscator cum unde.</p>
	</div>
</div>

Функция restoreOrder() восстанавливает вкладки в том порядке, в котором мы их отсортировали. В методе update() плагина $.sortable устанавливаем куку со списком вкладок в том порядке, в котором отсортировали. Вызов метода происходит при завершении перетаскивания вкладки. Если, к примеру, какой-то объект вкладок не инициализирован, то он не будет обрабатываться. Либо объект вкладок инициализирован, но для него нет куки с параметрами - кука будет автоматически создана.

Для того чтобы восстановить позиции для нескольких объектов вкладок (к примеру на странице 3 div с разными настройками вкладок) необходимо вызывать функцию restoreOrder() для каждого объекта, передавая id объекта вкладок.

Например:

jQuery(document).ready(function($){
	var $tabs = $('#tabs').tabs({
		...
	});
	var $tabs1 = $('#tabs-1').tabs({
		...
	});
	var $tabs2 = $('#tabs-2').tabs({
		...
	});
	// Вызываем restoreOrder() для каждого объекта
	restoreOrder('#tabs, #tabs-1, #tabs-2');
});