Shifty - выбор элементов с помощью клавиш Ctrl и Shift

Часто бывает так, что в одной таблице надо выбрать большое количество хаотично разбросанных строк. А если ещё десяток выбираемых строк идёт друг за другом... В этом случае на помощь приходит Shifty - небольшой плагин, написанный мной в попытке разрешить эту проблему.

С помощью Shifty можно выбирать как несколько строк подряд (используя клавишу Shift) так и выделять и снимать выделение с отдельных элементов (используя клавишу Ctrl).

Но, как говорится, лучше один раз увидеть, чем сто раз услышать - вот пример работы плагина:
Строка 1Ещё одна строка 1
Строка 2Ещё одна строка 2
Строка 3Ещё одна строка 3
Строка 4Ещё одна строка 4
Строка 5Ещё одна строка 5
Строка 6Ещё одна строка 6
Строка 7Ещё одна строка 7
Строка 8Ещё одна строка 8
Строка 9Ещё одна строка 9
Строка 10Ещё одна строка 10

Код плагина

(function($){
	$.fn.shifty = function(o){
		var o = $.extend({
			className:'shifty-select', // название класса по умолчанию
			select:function(){},  // функция при выделении
			unselect:function(){} // функция при снятии выделения
		}, o);
		elems = $(this); // получаем элементы
		last = null;
		var className = o.className; // и название класса
		return $(this).each(function(){
        	    var block = $(this); // работаем с отдельным элементом
          	    $(document).keydown(function(e){ // при нажатии клавиши
        		    if (!e.ctrlKey && !e.shiftKey) return;  // если клавиша не shift и не ctrl выходим из функции
                            this.onselectstart = function(){return false}; // запрет выделения для IE
	        	    block.unbind('click').css({'-moz-user-select':'none','-webkit-user-select':'none','user-select':'none'}); // и для всех остальных браузеров
	        	    if (e.ctrlKey) {  // если нажата клавиша ctrl
		                block.click(function(){
		        	    block.toggleClass(className); // снимаем либо добавляем выделение
		        	    last = elems.index(block); // определяем номер элемента
		        	    o.unselect(elems); // снимаем выделение, выполняя пользовательскую функцию
		        	    o.select(elems.filter('.' + className)); // добавляем пользовательскую функцию для выделенных элементов
				});
			    }
			    if (e.shiftKey) { // если нажата клавиша shift
		                block.click(function(){
		        	    first = elems.index(block); // находим элемент, с которого начнётся выделение
		        	    if (first < last) { // выделяем последующие элементы в зависимости от направления
		        		    elems.filter(':gt(' + (first - 1) + ')').addClass(className);
		        		    elems.filter(':lt(' + first + '),:gt(' + last + ')').removeClass(className);
		        	    } else {
			        	    elems.filter(':gt(' + last + ')').addClass(className);
			        	    elems.filter(':lt(' + last + '),:gt(' + first + ')').removeClass(className);
		        	    }
		        	    o.unselect(elems);  // снимаем выделение пользовательской функцией
		        	    o.select(elems.filter('.' + className)); // добавляем пользовательскую функцию для элемента
				});
			    }
        	    });
        	    $(document).keyup(function(e){  // когда клавиша отпущена
        	        this.onselectstart = function(){}; // снимаем запрет выделения с IE
        	        block.unbind('click').click(blockClick).css({'-moz-user-select':'','-webkit-user-select':'','user-select':''}); // и с остальных браузеров
        	    });
        	    block.click(blockClick); // устанавливаем обработчик клика
		});
		function blockClick(){ // обработчик простого клика
		    elems.removeClass(className); // снимаем выделение со всех элементов
		    $(this).addClass(className); // добавляем выделение к текущему элементу
		    o.unselect(elems); // то же самое с пользовательской функцией
		    o.select($(this));
	            last = elems.index($(this));
		}
	};
})(jQuery);

Подключение плагина

<script type="text/javascript" src="/pro/shift/shift.jquery.js"></script>
<script type="text/javascript">$(document).ready(function(){
	$('.block').shifty({
		className:'select', // класс выделенного элемента
		select:function(el){el.find(':checkbox').attr('checked','checked');}, // выделение
		unselect:function(el){el.find(':checkbox').removeAttr('checked');} // снятие выделения
	});
});</script>
При желании вы сами можете написать функции, которые срабатывали бы при выделении и снятии выделения. В предыдущем примере эти функции выполняют нажатие на checkbox, вставленный в строку таблицы.

Поддержка браузерами

Плагин успешно работает в:
  • Firefox
  • IE (начиная с 6 версии)
  • Opera
  • Chrome
  • Safari


Если у вас есть вопросы - добро пожаловать в комментарии.


Комментарии

18 октября 2010, 18:28 (Ответить)
забавный пример, мне нравится )

только есть одно но - зона действия шифта и контрола глобальная на этой (странице по крайней мере), что не правильно
18 октября 2010, 18:29 (Ответить)
обработку keydown нужно вешать не на document а на контейнер с данными скорее всего
20 октября 2010, 11:01 (Ответить)
alexpts, я бы с радостью повесила обработку не на document, но события keyup и keydown не срабатывают на блоках.
Сейчас я слегка изменила код, и плагин не мешает нажимать Ctrl или Shift в сочетании с другими клавишами.
6 ноября 2011, 23:31 (Ответить)
спасибо!

Добавить комментарий