dragselect
Advanced tools
Comparing version 1.5.0 to 1.6.0
/* | ||
@TODO: rewrite it in a OOP manner so that people can extend/mixin the dragselect | ||
@TODO: test in older browsers | ||
@@ -29,2 +30,3 @@ __ _____ __ __ | ||
** @customStyles boolean if set to true, no styles (except for position absolute) will be applied by default | ||
** @multiSelectKeys array These key will allow the user add more elements to the selection instead of clearing the selection. The only possible values are keys that are provided via the event object. So far: <kbd>ctrlKey</kbd>, <kbd>shiftKey</kbd>, <kbd>metaKey</kbd> and <kbd>altKey</kbd>. Provide an empty array `[]` if you want to turn off the funcionality. Default: `['ctrlKey', 'shiftKey', 'metaKey']` | | ||
** @onElementSelect function this is optional, it is fired every time an element is selected. This callback gets a property which is the just selected node | ||
@@ -80,2 +82,4 @@ ** @onElementUnselect function this is optional, it is fired every time an element is de-selected. This callback gets a property which is the just de-selected node | ||
selectables, | ||
multiSelectKeys, | ||
multiSelectKeyPressed, | ||
selectCallback, | ||
@@ -87,2 +91,3 @@ unselectCallback, | ||
selected, | ||
customStyles, | ||
initialScroll; | ||
@@ -92,2 +97,3 @@ | ||
selectables = toArray(options.selectables) || []; | ||
multiSelectKeys = options.multiSelectKeys || ['ctrlKey', 'shiftKey', 'metaKey']; | ||
selectCallback = options.onElementSelect || function() {}; | ||
@@ -97,3 +103,4 @@ unselectCallback = options.onElementUnselect || function() {}; | ||
area = options.area || document; | ||
customStyles = options.customStyles || false; | ||
selector = options.selector || _createSelection(); | ||
@@ -109,3 +116,3 @@ addClass(selector, 'ds-selector'); | ||
selector.style.position = 'absolute'; | ||
if(!options.customStyles) { | ||
if(!customStyles) { | ||
selector.style.background = 'rgba(0, 0, 255, 0.2)'; | ||
@@ -133,8 +140,15 @@ selector.style.border = '1px solid rgba(0, 0, 255, 0.5)'; | ||
function _startUp(event) { | ||
function _startUp( event ) { | ||
selector.style.display = 'block'; | ||
// check if some multiselection modifier key is pressed | ||
multiSelectKeyPressed = false; | ||
for (var index = 0; index < multiSelectKeys.length; index++) { | ||
var mKey = multiSelectKeys[index]; | ||
if(event[mKey]) { multiSelectKeyPressed = true; } | ||
} | ||
// move element on location | ||
_getStartingPositions(event); | ||
checkIfInsideSelection(); | ||
checkIfInsideSelection(true); | ||
@@ -226,3 +240,2 @@ area.removeEventListener('mousedown', _startUp); | ||
// console.log('yala', cursorPosNew.y, initialCursorPos.y, scrollAmount.y, initialScroll.y); | ||
// right | ||
@@ -255,28 +268,54 @@ if(cursorPosNew.x > initialCursorPos.x - scrollAmount.x) { // 1. | ||
function checkIfInsideSelection() { | ||
/* startup handles first clicks. Here is user is clicking directly onto | ||
* some element at start, (contrary to later hovers) we can assume that he | ||
* really wants to select/deselect that item. So we force it through. */ | ||
function checkIfInsideSelection( startup ) { | ||
for(var i = 0, il = selectables.length; i < il; i++) { | ||
var selectable = selectables[i]; | ||
var posInSelectedArray = selected.indexOf(selectable); | ||
if( isElementTouching(selectable, selector) ) { | ||
_handleSelection( selectable, startup ); | ||
} else { | ||
_handleUnselection( selectable, startup ); | ||
} | ||
if( posInSelectedArray < 0 ) { | ||
selected.push(selectable); | ||
addClass(selectable, 'selected'); | ||
selectCallback(selectable); | ||
} | ||
} | ||
} | ||
} else { | ||
function _handleSelection( item, startup ) { | ||
if( hasClass( item, 'ds-hover' ) && !startup ) { return false; } | ||
var posInSelectedArray = selected.indexOf( item ); | ||
if( posInSelectedArray > -1 ) { | ||
selected.splice(posInSelectedArray, 1); | ||
removeClass(selectable, 'selected'); | ||
unselectCallback(selectable); | ||
} | ||
if( posInSelectedArray < 0 ) { | ||
_select( item ); | ||
} else if( posInSelectedArray > -1 && multiSelectKeyPressed ) { | ||
_unselect( item ); | ||
} | ||
} | ||
addClass( item, 'ds-hover' ); | ||
} | ||
function _handleUnselection( item, startup ) { | ||
if( !hasClass( item, 'ds-hover' ) && !startup ) { return false; } | ||
var posInSelectedArray = selected.indexOf( item ); | ||
if( posInSelectedArray > -1 && !multiSelectKeyPressed ) { | ||
_unselect( item ); | ||
} | ||
removeClass( item, 'ds-hover' ); | ||
} | ||
function _select( item ) { | ||
selected.push(item); | ||
addClass(item, 'ds-selected'); | ||
selectCallback(item); | ||
} | ||
function _unselect( item ) { | ||
selected.splice(selected.indexOf(item), 1); | ||
removeClass(item, 'ds-selected'); | ||
unselectCallback(item); | ||
} | ||
//- Is Element touching Selection? (and vice-versa) | ||
@@ -455,2 +494,15 @@ function isElementTouching(element, container) { | ||
/** | ||
* Checks if an element has a class | ||
* sadly legacy phones/browsers don’t support .classlist so we use this workaround | ||
* @param {*} element | ||
* @param {*} classname | ||
* @return {node} element | ||
*/ | ||
function hasClass( element, classname ) { | ||
var cn = element.className; | ||
if( cn.indexOf( classname ) > -1 ) { return true; } | ||
else { return false; } | ||
} | ||
/** | ||
* Transforms an Object to an array | ||
@@ -571,2 +623,20 @@ * this is mainly used to transform Nodelists | ||
// Polyfills | ||
////////////////////////////////////////////////////////////////////////////////////// | ||
// indexOf polyfill for <IE9 all credits to https://stackoverflow.com/a/9768663/3712591 | ||
if (!Array.prototype.indexOf) { | ||
Array.prototype.indexOf = function (elt /*, from*/) { | ||
var len = this.length >>> 0; | ||
var from = Number(arguments[1]) || 0; | ||
from = (from < 0) ? Math.ceil(from) : Math.floor(from); | ||
if (from < 0) { from += len; } | ||
for (; from < len; from++) { | ||
if (from in this && this[from] === elt) { return from; } | ||
} | ||
return -1; | ||
}; | ||
} | ||
// Return | ||
@@ -584,2 +654,6 @@ ////////////////////////////////////////////////////////////////////////////////////// | ||
checkIfInsideSelection: checkIfInsideSelection, | ||
_handleSelection: _handleSelection, | ||
_handleUnselection: _handleUnselection, | ||
_select: _select, | ||
_unselect: _unselect, | ||
isElementTouching: isElementTouching, | ||
@@ -593,2 +667,3 @@ autoScroll: autoScroll, | ||
removeSelectables: removeSelectables, | ||
hasClass: hasClass, | ||
addClass: addClass, | ||
@@ -595,0 +670,0 @@ removeClass: removeClass, |
@@ -1,1 +0,1 @@ | ||
var dragSelect=function(e){function t(){R=v(e.selectables)||[],B=e.onElementSelect||function(){},T=e.onElementUnselect||function(){},H=e.callback||function(){},_=e.area||document,C=e.selector||n(),m(C,"ds-selector"),N=[]}function n(){var t=document.createElement("div");return t.style.position="absolute",e.customStyles||(t.style.background="rgba(0, 0, 255, 0.2)",t.style.border="1px solid rgba(0, 0, 255, 0.5)",t.style.display="none"),(_===document?document.body:_).appendChild(t),t}function o(){_.addEventListener("mousedown",i)}function i(e){C.style.display="block",r(e),s(),_.removeEventListener("mousedown",i),_.addEventListener("mousemove",l),document.addEventListener("mouseup",f)}function r(e){W=b(e),O=E(_);var t={};t.x=W.x+O.x,t.y=W.y+O.y,t.w=0,t.h=0,S(C,t)}function l(e){var t=c(e);S(C,t),s(),d(e)}function c(e){var t=b(e),n=E(_),o={x:n.x-O.x,y:n.y-O.y},i={};return t.x>W.x-o.x?(i.x=W.x+O.x,i.w=t.x-W.x+o.x):(i.x=t.x+n.x,i.w=W.x-t.x-o.x),t.y>W.y-o.y?(i.y=W.y+O.y,i.h=t.y-W.y+o.y):(i.y=t.y+n.y,i.h=W.y-t.y-o.y),i}function s(){for(var e=0,t=R.length;e<t;e++){var n=R[e],o=N.indexOf(n);u(n,C)?o<0&&(N.push(n),m(n,"selected"),B(n)):o>-1&&(N.splice(o,1),p(n,"selected"),T(n))}}function u(e,t){var n=E(_),o={y:t.getBoundingClientRect().top+n.y,x:t.getBoundingClientRect().left+n.x,h:t.offsetHeight,w:t.offsetWidth},i={y:e.getBoundingClientRect().top+n.y,x:e.getBoundingClientRect().left+n.x,h:e.offsetHeight,w:e.offsetWidth};return o.x<i.x+i.w&&o.x+o.w>i.x&&o.y<i.y+i.h&&o.h+o.y>i.y}function d(e){var t=a(e),n=_===document?_.body:_;"top"===t&&n.scrollTop>0?n.scrollTop-=1:"bottom"===t?n.scrollTop+=1:"left"===t&&n.scrollLeft>0?n.scrollLeft-=1:"right"===t&&(n.scrollLeft+=1)}function a(e){var t=b(e),n=L(_),o={x:Math.max(n.width/10,20),y:Math.max(n.height/10,20)},i=_===document?E(document.body):{x:0,y:0};return t.y<o.y+i.y?"top":n.height-t.y+i.y<o.y?"bottom":n.width-t.x+i.x<o.x?"right":t.x<o.x+i.x&&"left"}function f(){C.style.width="0",C.style.height="0",C.style.display="none",H(N),_.removeEventListener("mousemove",l),_.addEventListener("mousedown",i)}function y(){f(),_.removeEventListener("mousedown",i),document.removeEventListener("mouseup",f)}function g(){return N}function x(e){for(var t=v(e),n=0,o=t.length;n<o;n++){var i=t[n];R.indexOf(i)<0&&R.push(i)}}function h(e){for(var t=v(e),n=0,o=t.length;n<o;n++){var i=t[n];R.indexOf(i)>0&&(p(i,"selected"),R.splice(R.indexOf(i),1))}}function m(e,t){var n=e.className;return-1!==n.indexOf(t)?e:(""!==n&&(t=" "+t),e.className=n+t,e)}function p(e,t){var n=e.className,o=new RegExp(t+"\\b","g");n=n.replace(o,""),e.className=n}function v(e){if(!e)return!1;if(!e.length&&w(e))return[e];for(var t=[],n=e.length-1;n>=0;n--)t[n]=e[n];return t}function w(e){try{return e instanceof HTMLElement}catch(t){return"object"==typeof e&&1===e.nodeType&&"object"==typeof e.style&&"object"==typeof e.ownerDocument}}function b(e){var t={x:e.pageX||e.clientX,y:e.pageY||e.clientY},n=L(_);return{x:t.x-n.left,y:t.y-n.top}}function E(e){return{y:e&&e.scrollTop>=0?e.scrollTop:0,x:e&&e.scrollLeft>=0?e.scrollLeft:0}}function L(e){if(e===document){var t={y:e.documentElement.clientHeight>0?e.documentElement.clientHeight:window.innerHeight,x:e.documentElement.clientWidth>0?e.documentElement.clientWidth:window.innerWidth};return{top:0,left:0,bottom:0,right:0,width:t.x,height:t.y}}return{top:e.getBoundingClientRect().top,left:e.getBoundingClientRect().left,bottom:e.getBoundingClientRect().bottom,right:e.getBoundingClientRect().right,width:e.offsetWidth,height:e.offsetHeight}}function S(e,t){return e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e}var C,R,B,T,H,W,_,N,O;return t(),o(),{_setup:t,_createSelection:n,start:o,_startUp:i,_getStartingPositions:r,_handleMove:l,getPosition:c,checkIfInsideSelection:s,isElementTouching:u,autoScroll:d,isCursorNearEdge:a,reset:f,stop:y,getSelection:g,addSelectables:x,removeSelectables:h,addClass:m,removeClass:p,toArray:v,isElement:w,getCursorPos:b,getScroll:E,getAreaRect:L,_updatePos:S}};"undefined"!=typeof module&&null!==module?module.exports=dragSelect:window.dragSelect=dragSelect; | ||
var dragSelect=function(e){function t(){H=C(e.selectables)||[],N=e.multiSelectKeys||["ctrlKey","shiftKey","metaKey"],W=e.onElementSelect||function(){},k=e.onElementUnselect||function(){},A=e.callback||function(){},P=e.area||document,U=e.customStyles||!1,T=e.selector||n(),b(T,"ds-selector"),j=[]}function n(){var e=document.createElement("div");return e.style.position="absolute",U||(e.style.background="rgba(0, 0, 255, 0.2)",e.style.border="1px solid rgba(0, 0, 255, 0.5)",e.style.display="none"),(P===document?document.body:P).appendChild(e),e}function o(){P.addEventListener("mousedown",r)}function r(e){T.style.display="block",M=!1;for(var t=0;t<N.length;t++){e[N[t]]&&(M=!0)}i(e),s(!0),P.removeEventListener("mousedown",r),P.addEventListener("mousemove",l),document.addEventListener("mouseup",g)}function i(e){K=O(e),I=R(P);var t={};t.x=K.x+I.x,t.y=K.y+I.y,t.w=0,t.h=0,B(T,t)}function l(e){var t=c(e);B(T,t),s(),h(e)}function c(e){var t=O(e),n=R(P),o={x:n.x-I.x,y:n.y-I.y},r={};return t.x>K.x-o.x?(r.x=K.x+I.x,r.w=t.x-K.x+o.x):(r.x=t.x+n.x,r.w=K.x-t.x-o.x),t.y>K.y-o.y?(r.y=K.y+I.y,r.h=t.y-K.y+o.y):(r.y=t.y+n.y,r.h=K.y-t.y-o.y),r}function s(e){for(var t=0,n=H.length;t<n;t++){var o=H[t];y(o,T)?u(o,e):d(o,e)}}function u(e,t){if(S(e,"ds-hover")&&!t)return!1;var n=j.indexOf(e);n<0?f(e):n>-1&&M&&a(e),b(e,"ds-hover")}function d(e,t){if(!S(e,"ds-hover")&&!t)return!1;j.indexOf(e)>-1&&!M&&a(e),E(e,"ds-hover")}function f(e){j.push(e),b(e,"ds-selected"),W(e)}function a(e){j.splice(j.indexOf(e),1),E(e,"ds-selected"),k(e)}function y(e,t){var n=R(P),o={y:t.getBoundingClientRect().top+n.y,x:t.getBoundingClientRect().left+n.x,h:t.offsetHeight,w:t.offsetWidth},r={y:e.getBoundingClientRect().top+n.y,x:e.getBoundingClientRect().left+n.x,h:e.offsetHeight,w:e.offsetWidth};return o.x<r.x+r.w&&o.x+o.w>r.x&&o.y<r.y+r.h&&o.h+o.y>r.y}function h(e){var t=x(e),n=P===document?P.body:P;"top"===t&&n.scrollTop>0?n.scrollTop-=1:"bottom"===t?n.scrollTop+=1:"left"===t&&n.scrollLeft>0?n.scrollLeft-=1:"right"===t&&(n.scrollLeft+=1)}function x(e){var t=O(e),n=_(P),o={x:Math.max(n.width/10,20),y:Math.max(n.height/10,20)},r=P===document?R(document.body):{x:0,y:0};return t.y<o.y+r.y?"top":n.height-t.y+r.y<o.y?"bottom":n.width-t.x+r.x<o.x?"right":t.x<o.x+r.x&&"left"}function g(){T.style.width="0",T.style.height="0",T.style.display="none",A(j),P.removeEventListener("mousemove",l),P.addEventListener("mousedown",r)}function m(){g(),P.removeEventListener("mousedown",r),document.removeEventListener("mouseup",g)}function p(){return j}function v(e){for(var t=C(e),n=0,o=t.length;n<o;n++){var r=t[n];H.indexOf(r)<0&&H.push(r)}}function w(e){for(var t=C(e),n=0,o=t.length;n<o;n++){var r=t[n];H.indexOf(r)>0&&(E(r,"selected"),H.splice(H.indexOf(r),1))}}function b(e,t){var n=e.className;return-1!==n.indexOf(t)?e:(""!==n&&(t=" "+t),e.className=n+t,e)}function E(e,t){var n=e.className,o=new RegExp(t+"\\b","g");n=n.replace(o,""),e.className=n}function S(e,t){return e.className.indexOf(t)>-1}function C(e){if(!e)return!1;if(!e.length&&L(e))return[e];for(var t=[],n=e.length-1;n>=0;n--)t[n]=e[n];return t}function L(e){try{return e instanceof HTMLElement}catch(t){return"object"==typeof e&&1===e.nodeType&&"object"==typeof e.style&&"object"==typeof e.ownerDocument}}function O(e){var t={x:e.pageX||e.clientX,y:e.pageY||e.clientY},n=_(P);return{x:t.x-n.left,y:t.y-n.top}}function R(e){return{y:e&&e.scrollTop>=0?e.scrollTop:0,x:e&&e.scrollLeft>=0?e.scrollLeft:0}}function _(e){if(e===document){var t={y:e.documentElement.clientHeight>0?e.documentElement.clientHeight:window.innerHeight,x:e.documentElement.clientWidth>0?e.documentElement.clientWidth:window.innerWidth};return{top:0,left:0,bottom:0,right:0,width:t.x,height:t.y}}return{top:e.getBoundingClientRect().top,left:e.getBoundingClientRect().left,bottom:e.getBoundingClientRect().bottom,right:e.getBoundingClientRect().right,width:e.offsetWidth,height:e.offsetHeight}}function B(e,t){return e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e}var T,H,N,M,W,k,A,K,P,j,U,I;return t(),o(),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){var t=this.length>>>0,n=Number(arguments[1])||0;for(n=n<0?Math.ceil(n):Math.floor(n),n<0&&(n+=t);n<t;n++)if(n in this&&this[n]===e)return n;return-1}),{_setup:t,_createSelection:n,start:o,_startUp:r,_getStartingPositions:i,_handleMove:l,getPosition:c,checkIfInsideSelection:s,_handleSelection:u,_handleUnselection:d,_select:f,_unselect:a,isElementTouching:y,autoScroll:h,isCursorNearEdge:x,reset:g,stop:m,getSelection:p,addSelectables:v,removeSelectables:w,hasClass:S,addClass:b,removeClass:E,toArray:C,isElement:L,getCursorPos:O,getScroll:R,getAreaRect:_,_updatePos:B}};"undefined"!=typeof module&&null!==module?module.exports=dragSelect:window.dragSelect=dragSelect; |
{ | ||
"name": "dragselect", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "easy javascript drag select functionality to your projects", | ||
@@ -5,0 +5,0 @@ "main": "./dist/ds.min.js", |
@@ -76,2 +76,3 @@ ``` | ||
customStyles: false, // If set to true, no styles (except for position absolute) will be applied by default. | ||
multiSelectKeys: ['ctrlKey', 'shiftKey', 'metaKey'], // special keys that allow multiselection. | ||
onElementSelect: function(element) {}, // fired every time an element is selected. (element) = just selected node | ||
@@ -88,4 +89,7 @@ onElementUnselect: function(element) {}, // fired every time an element is de-selected. (element) = just de-selected node. | ||
ds.start(); // reset the functionality after a teardown | ||
``` | ||
``` | ||
You can also use the "shift", "ctrl" or "command" key to make multiple independent selections. | ||
## Properties: | ||
@@ -97,3 +101,4 @@ | property | type | usage | | ||
|area |single DOM element (node) |OPTIONAL. The square in which you are able to select | | ||
|customStyles |boolean |OPTIONAL. If true, no styles will be automatically applied (except position: absolute). Default: false | | ||
|customStyles |boolean |OPTIONAL. If true, no styles will be automatically applied (except position: absolute). Default: `false` | | ||
|multiSelectKeys |array |OPTIONAL. These key will allow the user add more elements to the selection instead of clearing the selection. The only possible values are keys that are provided via the event object. So far: <kbd>ctrlKey</kbd>, <kbd>shiftKey</kbd>, <kbd>metaKey</kbd> and <kbd>altKey</kbd>. Provide an empty array `[]` if you want to turn off the funcionality. Default: `['ctrlKey', 'shiftKey', 'metaKey']` | | ||
|onElementSelect |function |OPTIONAL. Fired every time an element is selected. This callback gets a property which is the selected node | | ||
@@ -118,2 +123,3 @@ |onElementUnselect |function |OPTIONAL. Fired every time an element is de-selected. This callback gets a property which is the de-selected node | | ||
|.ds-selected |On elements that are selected | ||
|.ds-hover |On elements that are currently hovered | ||
|.ds-selector |On the selector element | ||
@@ -120,0 +126,0 @@ |
/* | ||
@TODO: rewrite it in a OOP manner so that people can extend/mixin the dragselect | ||
@TODO: test in older browsers | ||
@@ -29,2 +30,3 @@ __ _____ __ __ | ||
** @customStyles boolean if set to true, no styles (except for position absolute) will be applied by default | ||
** @multiSelectKeys array These key will allow the user add more elements to the selection instead of clearing the selection. The only possible values are keys that are provided via the event object. So far: <kbd>ctrlKey</kbd>, <kbd>shiftKey</kbd>, <kbd>metaKey</kbd> and <kbd>altKey</kbd>. Provide an empty array `[]` if you want to turn off the funcionality. Default: `['ctrlKey', 'shiftKey', 'metaKey']` | | ||
** @onElementSelect function this is optional, it is fired every time an element is selected. This callback gets a property which is the just selected node | ||
@@ -80,2 +82,4 @@ ** @onElementUnselect function this is optional, it is fired every time an element is de-selected. This callback gets a property which is the just de-selected node | ||
selectables, | ||
multiSelectKeys, | ||
multiSelectKeyPressed, | ||
selectCallback, | ||
@@ -87,2 +91,3 @@ unselectCallback, | ||
selected, | ||
customStyles, | ||
initialScroll; | ||
@@ -92,2 +97,3 @@ | ||
selectables = toArray(options.selectables) || []; | ||
multiSelectKeys = options.multiSelectKeys || ['ctrlKey', 'shiftKey', 'metaKey']; | ||
selectCallback = options.onElementSelect || function() {}; | ||
@@ -97,3 +103,4 @@ unselectCallback = options.onElementUnselect || function() {}; | ||
area = options.area || document; | ||
customStyles = options.customStyles || false; | ||
selector = options.selector || _createSelection(); | ||
@@ -109,3 +116,3 @@ addClass(selector, 'ds-selector'); | ||
selector.style.position = 'absolute'; | ||
if(!options.customStyles) { | ||
if(!customStyles) { | ||
selector.style.background = 'rgba(0, 0, 255, 0.2)'; | ||
@@ -133,8 +140,15 @@ selector.style.border = '1px solid rgba(0, 0, 255, 0.5)'; | ||
function _startUp(event) { | ||
function _startUp( event ) { | ||
selector.style.display = 'block'; | ||
// check if some multiselection modifier key is pressed | ||
multiSelectKeyPressed = false; | ||
for (var index = 0; index < multiSelectKeys.length; index++) { | ||
var mKey = multiSelectKeys[index]; | ||
if(event[mKey]) { multiSelectKeyPressed = true; } | ||
} | ||
// move element on location | ||
_getStartingPositions(event); | ||
checkIfInsideSelection(); | ||
checkIfInsideSelection(true); | ||
@@ -226,3 +240,2 @@ area.removeEventListener('mousedown', _startUp); | ||
// console.log('yala', cursorPosNew.y, initialCursorPos.y, scrollAmount.y, initialScroll.y); | ||
// right | ||
@@ -255,28 +268,54 @@ if(cursorPosNew.x > initialCursorPos.x - scrollAmount.x) { // 1. | ||
function checkIfInsideSelection() { | ||
/* startup handles first clicks. Here is user is clicking directly onto | ||
* some element at start, (contrary to later hovers) we can assume that he | ||
* really wants to select/deselect that item. So we force it through. */ | ||
function checkIfInsideSelection( startup ) { | ||
for(var i = 0, il = selectables.length; i < il; i++) { | ||
var selectable = selectables[i]; | ||
var posInSelectedArray = selected.indexOf(selectable); | ||
if( isElementTouching(selectable, selector) ) { | ||
_handleSelection( selectable, startup ); | ||
} else { | ||
_handleUnselection( selectable, startup ); | ||
} | ||
if( posInSelectedArray < 0 ) { | ||
selected.push(selectable); | ||
addClass(selectable, 'selected'); | ||
selectCallback(selectable); | ||
} | ||
} | ||
} | ||
} else { | ||
function _handleSelection( item, startup ) { | ||
if( hasClass( item, 'ds-hover' ) && !startup ) { return false; } | ||
var posInSelectedArray = selected.indexOf( item ); | ||
if( posInSelectedArray > -1 ) { | ||
selected.splice(posInSelectedArray, 1); | ||
removeClass(selectable, 'selected'); | ||
unselectCallback(selectable); | ||
} | ||
if( posInSelectedArray < 0 ) { | ||
_select( item ); | ||
} else if( posInSelectedArray > -1 && multiSelectKeyPressed ) { | ||
_unselect( item ); | ||
} | ||
} | ||
addClass( item, 'ds-hover' ); | ||
} | ||
function _handleUnselection( item, startup ) { | ||
if( !hasClass( item, 'ds-hover' ) && !startup ) { return false; } | ||
var posInSelectedArray = selected.indexOf( item ); | ||
if( posInSelectedArray > -1 && !multiSelectKeyPressed ) { | ||
_unselect( item ); | ||
} | ||
removeClass( item, 'ds-hover' ); | ||
} | ||
function _select( item ) { | ||
selected.push(item); | ||
addClass(item, 'ds-selected'); | ||
selectCallback(item); | ||
} | ||
function _unselect( item ) { | ||
selected.splice(selected.indexOf(item), 1); | ||
removeClass(item, 'ds-selected'); | ||
unselectCallback(item); | ||
} | ||
//- Is Element touching Selection? (and vice-versa) | ||
@@ -455,2 +494,15 @@ function isElementTouching(element, container) { | ||
/** | ||
* Checks if an element has a class | ||
* sadly legacy phones/browsers don’t support .classlist so we use this workaround | ||
* @param {*} element | ||
* @param {*} classname | ||
* @return {node} element | ||
*/ | ||
function hasClass( element, classname ) { | ||
var cn = element.className; | ||
if( cn.indexOf( classname ) > -1 ) { return true; } | ||
else { return false; } | ||
} | ||
/** | ||
* Transforms an Object to an array | ||
@@ -571,2 +623,20 @@ * this is mainly used to transform Nodelists | ||
// Polyfills | ||
////////////////////////////////////////////////////////////////////////////////////// | ||
// indexOf polyfill for <IE9 all credits to https://stackoverflow.com/a/9768663/3712591 | ||
if (!Array.prototype.indexOf) { | ||
Array.prototype.indexOf = function (elt /*, from*/) { | ||
var len = this.length >>> 0; | ||
var from = Number(arguments[1]) || 0; | ||
from = (from < 0) ? Math.ceil(from) : Math.floor(from); | ||
if (from < 0) { from += len; } | ||
for (; from < len; from++) { | ||
if (from in this && this[from] === elt) { return from; } | ||
} | ||
return -1; | ||
}; | ||
} | ||
// Return | ||
@@ -584,2 +654,6 @@ ////////////////////////////////////////////////////////////////////////////////////// | ||
checkIfInsideSelection: checkIfInsideSelection, | ||
_handleSelection: _handleSelection, | ||
_handleUnselection: _handleUnselection, | ||
_select: _select, | ||
_unselect: _unselect, | ||
isElementTouching: isElementTouching, | ||
@@ -593,2 +667,3 @@ autoScroll: autoScroll, | ||
removeSelectables: removeSelectables, | ||
hasClass: hasClass, | ||
addClass: addClass, | ||
@@ -595,0 +670,0 @@ removeClass: removeClass, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1253984
4469
125