| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- // jQuery finderSelect: a jQuery plugin that activates selecting elements
- // within a parent with Ctrl+Click, Command+Click and Shift+Click.
- //
- // Copyright 2013 Mike Angell
- //
- // Please see:
- //
- // https://github.com/evulse/finderselect
- //
- // For complete documentation.
- (function( $ ) {
- var d = $(document);
- var b = $('body');
- var commands = {
- highlight: highlight,
- unHighlight: unHighlight,
- highlightAll: highlightAll,
- unHighlightAll: unHighlightAll,
- selected: selected,
- children: children,
- update: update,
- addHook: addHook
- };
- var hooks = {};
- var o = {};
- var f = $.fn.finderSelect = function() {
- if (typeof arguments[0] === 'string') {
- var args = Array.prototype.slice.call(arguments);
- args.splice(0, 1);
- return commands[arguments[0]].apply(this, args);
- }
- else {
- finderSelect.apply(this, arguments);
- return this;
- }
-
- };
- function finderSelect(opt) {
- var p = $(this);
- var options = {
- selectClass: "selected",
- unSelectClass: "un-selected",
- currentClass: "selected-current",
- lastClass: "selected-last",
- shiftClass: "selected-shift",
- ctrlClass: "selected-ctrl",
- triggerUpdate: "finderSelectUpdate",
- children: false,
- event: "mousedown",
- cursor: "pointer",
- dragEvent: "mouseenter",
- enableClickDrag: true,
- enableShiftClick: true,
- enableCtrlClick: true,
- enableSingleClick: true,
- enableSelectAll: true,
- enableDisableSelection: true,
- enableTouchCtrlDefault: true,
- enableDesktopCtrlDefault: false,
- totalSelector: false,
- menuSelector: false,
- menuXOffset: 0,
- menuYOffset: 0
- };
- $.extend(options, opt);
-
- o = options;
- if(!o.children) {
- o.children = f.detect.children(p);
- }
- f.h.off(f.get.siblings(p,o), o);
- if(o.cursor) {
- f.set.cursor(p,o);
- }
- if(o.enableDisableSelection) {
- f.core.disableSelection(p,o);
- }
- if(o.enableClickDrag) {
- f.core.clickDrag(p,o);
- }
- if(o.enableSelectAll) {
- f.core.selectAll(p,o);
- }
- if(o.enableShiftClick || o.enableCtrlClick || o.enableSingleClick) {
- f.core.click(p,o);
- }
- if(o.totalSelector) {
- f.core.totalUpdate(p,o);
- }
- if(o.menuSelector) {
- f.core.loadMenu(p,o);
- }
- };
-
- function highlight(el) {
- f.h.on(el, o);
- return this;
- }
- function unHighlight(el) {
- f.h.off(el, o);
- return this;
- }
- function highlightAll() {
- var p = $(this);
- f.h.on(p.find(o.children), o);
- return this;
- }
- function unHighlightAll() {
- var p = $(this);
- f.h.off(p.find(o.children), o);
- return this;
- }
- function selected() {
- var p = $(this);
- return p.find(o.children+'.'+o.selectClass);
- }
- function children() {
- var p = $(this);
- return p.find(o.children);
- }
- function update() {
- var p = $(this);
- f.t.update(p, o);
- return this;
- }
- function addHook(hookName, fn) {
- if(!hooks[hookName]){
- hooks[hookName] = [];
- }
- hooks[hookName] = [fn];
- return this;
- }
- f.core = {
- clickDrag: function(p,o) {
- f.set.mouseDown(false);
- b.mousedown(function(e) {
- if(f.detect.leftMouse(e)) { f.set.mouseDown(true);}
- });
- b.mouseup(function(e) {
- if(f.detect.leftMouse(e)) { f.set.mouseDown(false);}
- });
- p.on(o.dragEvent, o.children, function(e){
- var c = f.get.clicks(p,o,$(this));
- if (f.get.mouseDown() && f.detect.ctrl(e)) {
- f.t.deleteSelection(o);
- f.t.toggleDrag(p,c,o);
- }
- });
- return p;
- },
- click: function(p,o) {
- p.on(o.event, o.children, function(e){
- if(f.detect.leftMouse(e)) {
- if ($(e.target).hasClass('ch-toggle') ||
- $(e.target).hasClass('check-label') ||
- ( $(e.target).hasClass('l-unit-toolbar__col--left')) ) {
- var c = f.get.clicks(p,o,$(this));
-
- var ref = $(e.target);
- if (ref.parents('.l-unit').hasClass('selected')/* && $('.l-unit.selected').length == 1*/) {
- ref.parents('.l-unit').find('.ch-toggle').attr('checked', false);
- ref.parents('.l-unit').removeClass('selected');
- ref.parents('.l-unit').removeClass('selected-current');
- $('.toggle-all').removeClass('clicked-on');
- return;
- }
- if (!(f.detect.ctrl(e) && o.enableCtrlClick) && (f.detect.shift(e) && o.enableShiftClick)) {
- f.t.deleteSelection(o);
- f.t.shiftClick(p,c,o);
- }
- if (((f.detect.ctrl(e) && o.enableCtrlClick) || (f.detect.touch() && o.enableTouchCtrlDefault) || o.enableDesktopCtrlDefault) && !(f.detect.shift(e) && o.enableShiftClick)) {
- f.t.toggleClick(p,c,o);
- }
- if (!(f.detect.ctrl(e) && o.enableCtrlClick) && !(f.detect.shift(e) && o.enableShiftClick) && o.enableSingleClick && !o.enableDesktopCtrlDefault) {
- f.t.singleClick(p,c,o);
- }
- }
- }
- o.onFinish(e);
- });
- },
- selectAll: function(p,o) {
- p.on('mouseover', function(){
- //d.on("keydown", turnOff);
- });
- p.on('mouseout', function(){
- //d.off("keydown", turnOff);
- });
-
- function turnOff(e) {
- if (f.detect.ctrl(e)) {
- /*
- shortcut.add("Ctrl+a", function(evt){
- if(jQuery('.ch-toggle:checked').length > 0) {
- f.t.unHAll(p, o);
- jQuery('.ch-toggle:checked').attr('checked', false);
- } else {
- f.t.hAll(p,o);
- }
- }, {
- 'type': 'keyup',
- 'propagate': false,
- 'disable_in_input': true,
- 'target': document
- }
- );
- */
- if (e.keyCode == 65) { // ctrl + a
- e.preventDefault();
- //if(f.detect.alt(e)) {
- if(jQuery('.ch-toggle:checked').length > 0) {
- f.t.unHAll(p, o);
- jQuery('.ch-toggle:checked').attr('checked', false);
- } else {
- f.t.hAll(p,o);
- }
- }
- }
- if (e.keyCode == 38) {
- var last = f.get.click(p, o.shiftClass);
- if(last.length == 0) {
- last = f.get.click(p, o.lastClass);
- }
- var cur = f.get.prev(last,o);
- if(last.length == 0) {
- cur = p.find(o.children).last();
- }
- if(f.detect.alt(e)) {
- cur = p.find(o.children).first();
- }
- e.preventDefault();
- if(cur.length != 0) {
- if(f.detect.shift(e) && o.enableShiftClick) {
- var c = f.get.clicks(p,o,cur);
- f.t.shiftClick(p,c,o);
- } else {
- var c = f.get.clicks(p,o,cur);
- f.t.singleClick(p,c,o);
- }
- }
- }
- if (e.keyCode == 40) {
- var last = f.get.click(p, o.shiftClass);
- if(last.length == 0) {
- last = f.get.click(p, o.lastClass);
- }
- var cur = f.get.next(last,o);
- if(last.length == 0) {
- cur = p.find(o.children).first();
- }
- if(f.detect.alt(e)) {
- cur = p.find(o.children).last();
- }
- e.preventDefault();
- if(cur.length != 0) {
- if(f.detect.shift(e) && o.enableShiftClick) {
- var c = f.get.clicks(p,o,cur);
- f.t.shiftClick(p,c,o);
- } else {
- var c = f.get.clicks(p,o,cur);
- f.t.singleClick(p,c,o);
- }
- }
- }
- }
- },
- totalUpdate: function(p,o) {
- p.on(o.triggerUpdate, function(){
- $(o.totalSelector).html($(this).find(o.children).filter('.'+o.selectClass).length)
- });
- },
- loadMenu: function(p, o) {
- p.bind("contextmenu",function(e){
- $(o.menuSelector).css({left:(e.pageX+o.menuXOffset),top:(e.pageY+o.menuYOffset)}).show();
- return false;
- }).bind("mousedown",function(){
- $(o.menuSelector).hide();
- });
- $(o.menuSelector).bind("click",function(){
- $(this).hide();
- });
- },
- disableSelection: function(p, o) {
- d.on('keydown', function(){
- p.on("selectstart", turnOffSelection);
- }).on('keyup', function(){
- p.off("selectstart", turnOffSelection);
- });
- function turnOffSelection(e) {
- e.preventDefault();
- }
- }
- };
- f.h = {
- on: function(el, o) {
- f.get.hook('highlight:before', [el, o]);
- el.removeClass(o.unSelectClass);
- el.addClass(o.selectClass);
- f.get.hook('highlight:after', [el, o]);
- },
- off: function(el,o) {
- f.get.hook('unHighlight:before', [el, o]);
- el.removeClass(o.selectClass);
- el.addClass(o.unSelectClass);
- f.get.hook('unHighlight:after', [el, o]);
- },
- tog: function(el,o) {
- el.each(function () {
- var child = $(this);
- if(f.detect.h(child, o)) {
- f.h.off(child, o);
- } else {
- f.h.on(child, o);
- }
- });
- },
- reset: function(el,o) {
- el.each(function () {
- var child = $(this);
- if(f.detect.lastH(child, o)) {
- f.h.on(child, o);
- } else {
- f.h.off(child, o);
- }
- });
-
- },
- state: function(el,o) {
- el.each(function () {
- var child = $(this);
- if(f.detect.h(child, o)) {
- child.removeClass('stateUnSelected');
- child.addClass('stateSelected');
- } else {
- child.removeClass('stateSelected');
- child.addClass('stateUnSelected');
- }
- });
-
- }
- };
- f.detect = {
- leftMouse: function(e) {
- return (e.which == 1);
- },
- shift: function(e) {
- return e.shiftKey;
- },
- alt: function(e) {
- return e.altKey;
- },
- ctrl: function(e) {
- return (e.ctrlKey || e.metaKey);
- },
- h: function(el,o) {
- return el.hasClass(o.selectClass);
- },
- lastH: function(el,o) {
- return el.hasClass('stateSelected');
- },
- touch: function() {
- return !!('ontouchstart' in window) // works on most browsers
- || !!('onmsgesturechange' in window); // works on ie10
- },
- children: function(el) {
- return el.children().get(0).tagName;
- }
- };
- f.set = {
- clicks: function(curr, shif, ctrl, p, o) {
- f.set.click(p, false, o.currentClass);
- f.set.click(p, curr, o.lastClass);
- f.set.click(p, shif,o.shiftClass);
- f.set.click(p, ctrl,o.ctrlClass);
- f.t.update(p, o);
- },
- click: function(p,el,c) {
- f.get.click(p,c).removeClass(c);
- if(el) { el.addClass(c); }
- },
- mouseDown: function(bool) {
- return b.data('down', bool);
- },
- cursor: function(p,o) {
- /* do not set cursor pointer inline styles
- var s = f.get.siblings(p,o);
- return s.css('cursor', o.cursor);*/
- }
- };
- f.get = {
- clicks: function(p, o, curr) {
- var c = {};
- f.set.click(p, curr, o.currentClass);
- c.current = {v:curr,c: o.currentClass};
- c.hard = {v:f.get.click(p, o.lastClass),c:o.lastClass};
- c.shift = {v:f.get.click(p, o.shiftClass),c:o.shiftClass};
- c.ctrl = {v:f.get.click(p, o.ctrlClass),c:o.ctrlClass};
- return c;
- },
- click: function(p,c) {
- return p.find('.'+c);
- },
- mouseDown: function() {
- return b.data('down');
- },
- siblings: function(p, o) {
- return p.find(o.children);
- },
- between: function(s,y, z) {
- if(s.index(y.v) < s.index(z.v)) {
- return f.get.elem(true, y.v, false, z.c);
- } else {
- return f.get.elem(false, y.v, false, z.c);
- }
- },
- elem: function(d, el, s, u) {
- var $els = [], $el = (d) ? el.next() : el.prev();
- while( $el.length ) {
- if(typeof u === 'undefined' || !u || !$el.hasClass(u)) {
- if(typeof s === 'undefined' || !s || $el.hasClass(s)) {
- $els.push($el[0]);
- }
- $el = (d) ? $el.next() : $el.prev();
- } else {
- $el = {};
- }
- }
- return $($els)
- },
- next: function(p, o) {
- return p.next(o.children);
- },
- prev: function(p, o) {
- return p.prev(o.children);
- },
- hook: function(hookName, data){
- var hooked = hooks[hookName]
- if(hooked){
- for(i=0; i<hooked.length; i++){
- hooked[i].apply(undefined, data);
- }
- }
- }
- };
- f.t = {
- update: function(el, o) {
- return el.trigger(o.triggerUpdate);
- },
- deleteSelection: function(o) {
- if(o.enableDisableSelection) {
- if(document.getSelection) {
- var sel = document.getSelection();
- if(sel.removeAllRanges) {
- sel.removeAllRanges();
- }
- }
- }
- },
- singleClick: function(p,c,o) {
- var s = f.get.siblings(p,o);
- //f.h.off(s, o);
- f.h.on(c.current.v, o);
- f.set.clicks(c.current.v, null, null, p, o);
- },
- toggleClick: function(p,c,o) {
- var s = f.get.siblings(p,o);
- f.h.tog(c.current.v, o);
- f.h.state(s,o);
- f.set.clicks(c.current.v, null, null, p, o);
- },
- toggleClick: function(p,c,o) {
- var s = f.get.siblings(p,o);
- f.h.tog(c.current.v, o);
- f.h.state(s,o);
- f.set.clicks(c.current.v, null, null, p, o);
- },
- toggleDrag: function(p,c,o) {
- var s = f.get.siblings(p,o);
- f.h.reset(s,o);
- if(s.index(c.current.v) != s.index(c.hard.v)) {
- f.h.tog(f.get.between(s, c.current, c.hard), o);
- f.h.tog(c.current.v, o);
- }
- f.set.clicks(c.hard.v, null, null, p, o);
- },
- shiftClick: function(p, c, o) {
- var s = f.get.siblings(p,o);
- var z = s.index(c.current.v);
- var x = s.index(c.hard.v);
- if(c.hard.v.length != 0 && !f.detect.h(c.hard.v, o)) {
- var start = f.get.elem(true, c.hard.v, o.selectClass);
- if(start.length > 0) {
- c.hard.v = $(start[0]);
- f.set.click(p, c.hard.v, o.lastClass);
- } else {
- var start = f.get.elem(z < x, c.hard.v, o.selectClass);
- if(start.length > 0) {
- start = (z > x ) ? $(start[0]) : $(start[start.length-1]);
- c.hard.v = start;
- f.set.click(p, c.hard.v, o.lastClass);
- } else {
- c.hard.v = s.first();
- f.set.click(p, c.hard.v, o.lastClass);
- f.t.singleClick(s,{current:{v:s.first()}},o);
- }
- }
- }
- var x = s.index(c.hard.v);
- var y = s.index(c.shift.v);
- var z = s.index(c.current.v);
- if(c.hard.v.length == 0){
- f.t.singleClick(s,{current:{v:s.first()}},o);
- }
- if(c.shift.v.length != 0) {
- if((x < y && x < z && z < y) || (x > y && x > z && z > y)) {
- f.h.off(f.get.between(s, c.shift, c.current), o);
- }
- if((x < y && x > z && z < y) || (x > y && x < z && z > y)) {
- f.h.off(f.get.between(s, c.shift, c.hard), o);
- f.h.on(f.get.between(s, c.current, c.hard), o);
- }
- if((x > y && x > z && z < y) || (x < y && x < z && z > y) || (x == y)) {
- f.h.on(f.get.between(s, c.shift, c.current), o);
- } else {
- f.h.off(c.shift.v, o);
- f.t.unHExist(z>y, c.shift.v,o);
- }
- } else {
- f.t.unHExist(z>x,c.hard.v,o);
- f.h.on(f.get.between(s, c.current, c.hard), o);
- }
- f.h.on(c.current.v, o);
- f.set.clicks(c.hard.v, c.current.v, null, p, o);
- },
- unHAll: function(p,o) {
- f.h.off(p.find(o.children), o);
- f.t.update(p, o);
- $('.toggle-all').removeClass('clicked-on');
- },
- hAll: function(p,o) {
- f.h.on(p.find(o.children), o);
- f.t.update(p, o);
- o.toggleAllHook && o.toggleAllHook();
- $('.toggle-all').addClass('clicked-on');
- },
- unHExist: function(bool,el,o) {
- if(bool) {
- f.h.off(f.get.elem(false, el, false, o.unSelectClass), o);
- } else {
- f.h.off(f.get.elem(true, el, false, o.unSelectClass), o);
- }
- }
- };
- })(window.jQuery || window.Zepto);
|