.
This commit is contained in:
318
root/res/zui/lib/selectable/zui.selectable.js
Normal file
318
root/res/zui/lib/selectable/zui.selectable.js
Normal file
@@ -0,0 +1,318 @@
|
||||
/*!
|
||||
* ZUI: 拖拽选择 - v1.8.1 - 2018-01-18
|
||||
* http://zui.sexy
|
||||
* GitHub: https://github.com/easysoft/zui.git
|
||||
* Copyright (c) 2018 cnezsoft.com; Licensed MIT
|
||||
*/
|
||||
|
||||
/* ========================================================================
|
||||
* ZUI: selectable.js [1.5.0+]
|
||||
* http://zui.sexy
|
||||
* ========================================================================
|
||||
* Copyright (c) 2016 cnezsoft.com; Licensed MIT
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
var name = 'zui.selectable'; // module name
|
||||
|
||||
// The selectable modal class
|
||||
var Selectable = function(element, options) {
|
||||
this.name = name;
|
||||
this.$ = $(element);
|
||||
this.id = $.zui.uuid();
|
||||
this.selectOrder = 1;
|
||||
this.selections = {};
|
||||
|
||||
this.getOptions(options);
|
||||
this._init();
|
||||
};
|
||||
|
||||
var isPointInner = function(x, y, a) {
|
||||
return x >= a.left && x <= (a.left + a.width) && y >= a.top && y <= (a.top + a.height);
|
||||
};
|
||||
|
||||
var isIntersectArea = function(a, b) {
|
||||
var x1 = Math.max(a.left, b.left),
|
||||
y1 = Math.max(a.top, b.top),
|
||||
x2 = Math.min(a.left + a.width, b.left + b.width),
|
||||
y2 = Math.min(a.top + a.height, b.top + b.height);
|
||||
|
||||
return isPointInner(x1, y1, a) && isPointInner(x2, y2, a) && isPointInner(x1, y1, b) && isPointInner(x2, y2, b);
|
||||
};
|
||||
|
||||
// default options
|
||||
Selectable.DEFAULTS = {
|
||||
selector: 'li,tr,div',
|
||||
trigger: '',
|
||||
selectClass: 'active',
|
||||
rangeStyle: {
|
||||
border: '1px solid ' + ($.zui.colorset ? $.zui.colorset.primary : '#3280fc'),
|
||||
backgroundColor: $.zui.colorset ? (new $.zui.Color($.zui.colorset.primary).fade(20).toCssStr()) : 'rgba(50, 128, 252, 0.2)'
|
||||
},
|
||||
clickBehavior: 'toggle',
|
||||
ignoreVal: 3
|
||||
// mouseButton: -1 // 0, 1, 2, -1, all, left, right, middle
|
||||
};
|
||||
|
||||
// Get and init options
|
||||
Selectable.prototype.getOptions = function(options) {
|
||||
this.options = $.extend({}, Selectable.DEFAULTS, this.$.data(), options);
|
||||
};
|
||||
|
||||
Selectable.prototype.select = function(elementOrid) {
|
||||
this.toggle(elementOrid, true);
|
||||
};
|
||||
|
||||
Selectable.prototype.unselect = function(elementOrid) {
|
||||
this.toggle(elementOrid, false);
|
||||
};
|
||||
|
||||
Selectable.prototype.toggle = function(elementOrid, isSelect, handle) {
|
||||
var $element, id, selector = this.options.selector, that = this;
|
||||
if(elementOrid === undefined) {
|
||||
this.$.find(selector).each(function() {
|
||||
that.toggle(this, isSelect);
|
||||
});
|
||||
return;
|
||||
} else if(typeof elementOrid === 'object') {
|
||||
$element = $(elementOrid).closest(selector);
|
||||
id = $element.data('id');
|
||||
} else {
|
||||
id = elementOrid;
|
||||
$element = that.$.find('.slectable-item[data-id="' + id + '"]');
|
||||
}
|
||||
if($element && $element.length) {
|
||||
if(!id) {
|
||||
id = $.zui.uuid();
|
||||
$element.attr('data-id', id);
|
||||
}
|
||||
if(isSelect === undefined || isSelect === null) {
|
||||
isSelect = !that.selections[id];
|
||||
}
|
||||
if(!!isSelect !== !!that.selections[id]) {
|
||||
var handleResult;
|
||||
if($.isFunction(handle)) {
|
||||
handleResult = handle(isSelect);
|
||||
}
|
||||
if(handleResult !== true) {
|
||||
that.selections[id] = isSelect ? that.selectOrder++ : false;
|
||||
that.callEvent(isSelect ? 'select' : 'unselect', {id: id, selections: that.selections, target: $element, selected: that.getSelectedArray()}, that);
|
||||
}
|
||||
}
|
||||
if (that.options.selectClass) {
|
||||
$element.toggleClass(that.options.selectClass, isSelect);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Selectable.prototype.getSelectedArray = function() {
|
||||
var selected = [];
|
||||
$.each(this.selections, function(thisId, thisIsSelected) {
|
||||
if(thisIsSelected) selected.push(thisId);
|
||||
});
|
||||
return selected;
|
||||
};
|
||||
|
||||
Selectable.prototype.syncSelectionsFromClass = function() {
|
||||
var that = this;
|
||||
var $children = that.$children = that.$.find(that.options.selector);
|
||||
that.selections = {};
|
||||
that.$children.each(function() {
|
||||
var $item = $(this);
|
||||
that.selections[$item.data('id')] = $item.hasClass(that.options.selectClass);
|
||||
});
|
||||
};
|
||||
|
||||
Selectable.prototype._init = function() {
|
||||
var options = this.options, that = this;
|
||||
var ignoreVal = options.ignoreVal;
|
||||
var isIgnoreMove = true;
|
||||
var eventNamespace = '.' + this.name + '.' + this.id;
|
||||
var startX, startY, $range, range, x, y, checkRangeCall;
|
||||
var checkFunc = $.isFunction(options.checkFunc) ? options.checkFunc : null;
|
||||
var rangeFunc = $.isFunction(options.rangeFunc) ? options.rangeFunc : null;
|
||||
var isMouseDown = false;
|
||||
var mouseDownBackEventCall = null;
|
||||
var mouseDownEventName = 'mousedown' + eventNamespace;
|
||||
|
||||
var checkRange = function() {
|
||||
if(!range) return;
|
||||
that.$children.each(function() {
|
||||
var $item = $(this);
|
||||
var offset = $item.offset();
|
||||
offset.width = $item.outerWidth();
|
||||
offset.height = $item.outerHeight();
|
||||
var isIntersect = rangeFunc ? rangeFunc.call(this, range, offset) : isIntersectArea(range, offset);
|
||||
if(checkFunc) {
|
||||
var result = checkFunc.call(that, {
|
||||
intersect: isIntersect,
|
||||
target: $item,
|
||||
range: range,
|
||||
targetRange: offset
|
||||
});
|
||||
if(result === true) {
|
||||
that.select($item);
|
||||
} else if(result === false) {
|
||||
that.unselect($item);
|
||||
}
|
||||
} else {
|
||||
if(isIntersect) {
|
||||
that.select($item);
|
||||
} else if(!that.multiKey) {
|
||||
that.unselect($item);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var mousemove = function(e) {
|
||||
if(!isMouseDown) return;
|
||||
x = e.pageX;
|
||||
y = e.pageY;
|
||||
range = {
|
||||
width: Math.abs(x - startX),
|
||||
height: Math.abs(y - startY),
|
||||
left: x > startX ? startX : x,
|
||||
top: y > startY ? startY : y
|
||||
};
|
||||
|
||||
if(isIgnoreMove && range.width < ignoreVal && range.height < ignoreVal) return;
|
||||
if(!$range) {
|
||||
$range = $('.selectable-range[data-id="' + that.id + '"]');
|
||||
if(!$range.length) {
|
||||
$range = $('<div class="selectable-range" data-id="' + that.id + '"></div>')
|
||||
.css($.extend({
|
||||
zIndex: 1060,
|
||||
position: 'absolute',
|
||||
top: startX,
|
||||
left: startY,
|
||||
pointerEvents: 'none',
|
||||
}, that.options.rangeStyle))
|
||||
.appendTo($('body'));
|
||||
}
|
||||
}
|
||||
$range.css(range);
|
||||
clearTimeout(checkRangeCall);
|
||||
checkRangeCall = setTimeout(checkRange, 10);
|
||||
isIgnoreMove = false;
|
||||
};
|
||||
|
||||
var mouseup = function(e) {
|
||||
$(document).off(eventNamespace);
|
||||
clearTimeout(mouseDownBackEventCall);
|
||||
if(!isMouseDown) return;
|
||||
isMouseDown = false;
|
||||
if($range) $range.remove();
|
||||
if(!isIgnoreMove)
|
||||
{
|
||||
if(range) {
|
||||
clearTimeout(checkRangeCall);
|
||||
checkRange();
|
||||
range = null;
|
||||
}
|
||||
}
|
||||
that.callEvent('finish', {selections: that.selections, selected: that.getSelectedArray()});
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
var mousedown = function(e) {
|
||||
if(isMouseDown) {
|
||||
return mouseup(e);
|
||||
}
|
||||
|
||||
var mouseButton = $.zui.getMouseButtonCode(options.mouseButton);
|
||||
if(mouseButton > -1 && e.button !== mouseButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(that.altKey || e.which === 3 || that.callEvent('start', e) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $children = that.$children = that.$.find(options.selector);
|
||||
$children.addClass('slectable-item');
|
||||
|
||||
var clickBehavior = that.multiKey ? 'multi' : options.clickBehavior;
|
||||
if(clickBehavior === 'multi') {
|
||||
that.toggle(e.target);
|
||||
} else if(clickBehavior === 'single') {
|
||||
that.unselect();
|
||||
that.select(e.target);
|
||||
} else if(clickBehavior === 'toggle') {
|
||||
that.toggle(e.target, null, function(isSelect) {
|
||||
that.unselect();
|
||||
});
|
||||
}
|
||||
|
||||
if(that.callEvent('startDrag', e) === false) {
|
||||
that.callEvent('finish', {selections: that.selections, selected: that.getSelectedArray()});
|
||||
return;
|
||||
}
|
||||
|
||||
startX = e.pageX;
|
||||
startY = e.pageY;
|
||||
|
||||
$range = null;
|
||||
isIgnoreMove = true;
|
||||
isMouseDown = true;
|
||||
|
||||
$(document).on('mousemove' + eventNamespace, mousemove).on('mouseup' + eventNamespace, mouseup);
|
||||
mouseDownBackEventCall = setTimeout(function() {
|
||||
$(document).on(mouseDownEventName, mouseup);
|
||||
}, 10);
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
var $container = options.container && options.container !== 'default' ? $(options.container) : this.$;
|
||||
if(options.trigger) {
|
||||
$container.on(mouseDownEventName, options.trigger, mousedown);
|
||||
} else {
|
||||
$container.on(mouseDownEventName, mousedown);
|
||||
}
|
||||
|
||||
$(document).on('keydown', function(e) {
|
||||
var code = e.keyCode;
|
||||
if(code === 17 || code == 91) that.multiKey = code;
|
||||
else if(code === 18) that.altKey = true;
|
||||
}).on('keyup', function(e) {
|
||||
that.multiKey = false;
|
||||
that.altKey = false;
|
||||
});
|
||||
};
|
||||
|
||||
// Call event helper
|
||||
Selectable.prototype.callEvent = function(name, params) {
|
||||
var event = $.Event(name + '.' + this.name);
|
||||
this.$.trigger(event, params);
|
||||
var result = event.result;
|
||||
var callback = this.options[name];
|
||||
if($.isFunction(callback)) {
|
||||
result = callback.apply(this, $.isArray(params) ? params : [params]);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Extense jquery element
|
||||
$.fn.selectable = function(option) {
|
||||
return this.each(function() {
|
||||
var $this = $(this);
|
||||
var data = $this.data(name);
|
||||
var options = typeof option == 'object' && option;
|
||||
|
||||
if(!data) $this.data(name, (data = new Selectable(this, options)));
|
||||
|
||||
if(typeof option == 'string') data[option]();
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.selectable.Constructor = Selectable;
|
||||
|
||||
// Auto call selectable after document load complete
|
||||
$(function() {
|
||||
$('[data-ride="selectable"]').selectable();
|
||||
});
|
||||
}(jQuery));
|
||||
|
7
root/res/zui/lib/selectable/zui.selectable.min.js
vendored
Normal file
7
root/res/zui/lib/selectable/zui.selectable.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* ZUI: 拖拽选择 - v1.8.1 - 2018-01-18
|
||||
* http://zui.sexy
|
||||
* GitHub: https://github.com/easysoft/zui.git
|
||||
* Copyright (c) 2018 cnezsoft.com; Licensed MIT
|
||||
*/
|
||||
!function(t){"use strict";var e="zui.selectable",i=function(i,n){this.name=e,this.$=t(i),this.id=t.zui.uuid(),this.selectOrder=1,this.selections={},this.getOptions(n),this._init()},n=function(t,e,i){return t>=i.left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height},o=function(t,e){var i=Math.max(t.left,e.left),o=Math.max(t.top,e.top),s=Math.min(t.left+t.width,e.left+e.width),l=Math.min(t.top+t.height,e.top+e.height);return n(i,o,t)&&n(s,l,t)&&n(i,o,e)&&n(s,l,e)};i.DEFAULTS={selector:"li,tr,div",trigger:"",selectClass:"active",rangeStyle:{border:"1px solid "+(t.zui.colorset?t.zui.colorset.primary:"#3280fc"),backgroundColor:t.zui.colorset?new t.zui.Color(t.zui.colorset.primary).fade(20).toCssStr():"rgba(50, 128, 252, 0.2)"},clickBehavior:"toggle",ignoreVal:3},i.prototype.getOptions=function(e){this.options=t.extend({},i.DEFAULTS,this.$.data(),e)},i.prototype.select=function(t){this.toggle(t,!0)},i.prototype.unselect=function(t){this.toggle(t,!1)},i.prototype.toggle=function(e,i,n){var o,s,l=this.options.selector,c=this;if(void 0===e)return void this.$.find(l).each(function(){c.toggle(this,i)});if("object"==typeof e?(o=t(e).closest(l),s=o.data("id")):(s=e,o=c.$.find('.slectable-item[data-id="'+s+'"]')),o&&o.length){if(s||(s=t.zui.uuid(),o.attr("data-id",s)),void 0!==i&&null!==i||(i=!c.selections[s]),!!i!=!!c.selections[s]){var a;t.isFunction(n)&&(a=n(i)),a!==!0&&(c.selections[s]=!!i&&c.selectOrder++,c.callEvent(i?"select":"unselect",{id:s,selections:c.selections,target:o,selected:c.getSelectedArray()},c))}c.options.selectClass&&o.toggleClass(c.options.selectClass,i)}},i.prototype.getSelectedArray=function(){var e=[];return t.each(this.selections,function(t,i){i&&e.push(t)}),e},i.prototype.syncSelectionsFromClass=function(){var e=this;e.$children=e.$.find(e.options.selector);e.selections={},e.$children.each(function(){var i=t(this);e.selections[i.data("id")]=i.hasClass(e.options.selectClass)})},i.prototype._init=function(){var e,i,n,s,l,c,a,r=this.options,u=this,h=r.ignoreVal,d=!0,g="."+this.name+"."+this.id,f=t.isFunction(r.checkFunc)?r.checkFunc:null,p=t.isFunction(r.rangeFunc)?r.rangeFunc:null,v=!1,y=null,m="mousedown"+g,b=function(){s&&u.$children.each(function(){var e=t(this),i=e.offset();i.width=e.outerWidth(),i.height=e.outerHeight();var n=p?p.call(this,s,i):o(s,i);if(f){var l=f.call(u,{intersect:n,target:e,range:s,targetRange:i});l===!0?u.select(e):l===!1&&u.unselect(e)}else n?u.select(e):u.multiKey||u.unselect(e)})},C=function(o){v&&(l=o.pageX,c=o.pageY,s={width:Math.abs(l-e),height:Math.abs(c-i),left:l>e?e:l,top:c>i?i:c},d&&s.width<h&&s.height<h||(n||(n=t('.selectable-range[data-id="'+u.id+'"]'),n.length||(n=t('<div class="selectable-range" data-id="'+u.id+'"></div>').css(t.extend({zIndex:1060,position:"absolute",top:e,left:i,pointerEvents:"none"},u.options.rangeStyle)).appendTo(t("body")))),n.css(s),clearTimeout(a),a=setTimeout(b,10),d=!1))},$=function(e){t(document).off(g),clearTimeout(y),v&&(v=!1,n&&n.remove(),d||s&&(clearTimeout(a),b(),s=null),u.callEvent("finish",{selections:u.selections,selected:u.getSelectedArray()}),e.preventDefault())},w=function(o){if(v)return $(o);var s=t.zui.getMouseButtonCode(r.mouseButton);if(!(s>-1&&o.button!==s||u.altKey||3===o.which||u.callEvent("start",o)===!1)){var l=u.$children=u.$.find(r.selector);l.addClass("slectable-item");var c=u.multiKey?"multi":r.clickBehavior;if("multi"===c?u.toggle(o.target):"single"===c?(u.unselect(),u.select(o.target)):"toggle"===c&&u.toggle(o.target,null,function(t){u.unselect()}),u.callEvent("startDrag",o)===!1)return void u.callEvent("finish",{selections:u.selections,selected:u.getSelectedArray()});e=o.pageX,i=o.pageY,n=null,d=!0,v=!0,t(document).on("mousemove"+g,C).on("mouseup"+g,$),y=setTimeout(function(){t(document).on(m,$)},10),o.preventDefault()}},F=r.container&&"default"!==r.container?t(r.container):this.$;r.trigger?F.on(m,r.trigger,w):F.on(m,w),t(document).on("keydown",function(t){var e=t.keyCode;17===e||91==e?u.multiKey=e:18===e&&(u.altKey=!0)}).on("keyup",function(t){u.multiKey=!1,u.altKey=!1})},i.prototype.callEvent=function(e,i){var n=t.Event(e+"."+this.name);this.$.trigger(n,i);var o=n.result,s=this.options[e];return t.isFunction(s)&&(o=s.apply(this,t.isArray(i)?i:[i])),o},t.fn.selectable=function(n){return this.each(function(){var o=t(this),s=o.data(e),l="object"==typeof n&&n;s||o.data(e,s=new i(this,l)),"string"==typeof n&&s[n]()})},t.fn.selectable.Constructor=i,t(function(){t('[data-ride="selectable"]').selectable()})}(jQuery);
|
Reference in New Issue
Block a user