Initial commit,修正
This commit is contained in:
Vendored
+2078
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+3348
File diff suppressed because it is too large
Load Diff
+7
File diff suppressed because one or more lines are too long
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* dragtable
|
||||
*
|
||||
* @Version 2.0.15
|
||||
*
|
||||
* default css
|
||||
*
|
||||
*/
|
||||
/*##### the dragtable stuff #####*/
|
||||
.dragtable-sortable {
|
||||
list-style-type: none; margin: 0; padding: 0; -moz-user-select: none;
|
||||
}
|
||||
.dragtable-sortable li {
|
||||
margin: 0; padding: 0; float: left; font-size: 1em; background: white;
|
||||
}
|
||||
|
||||
.dragtable-sortable th, .dragtable-sortable td{
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
.dragtable-sortable li:first-child th, .dragtable-sortable li:first-child td {
|
||||
border-left: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.ui-sortable-helper {
|
||||
opacity: 0.7;filter: alpha(opacity=70);
|
||||
}
|
||||
.ui-sortable-placeholder {
|
||||
-moz-box-shadow: 4px 5px 4px #C6C6C6 inset;
|
||||
-webkit-box-shadow: 4px 5px 4px #C6C6C6 inset;
|
||||
box-shadow: 4px 5px 4px #C6C6C6 inset;
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
border-top: 1px solid #CCCCCC;
|
||||
visibility: visible !important;
|
||||
background: #EFEFEF !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
.ui-sortable-placeholder * {
|
||||
opacity: 0.0; visibility: hidden;
|
||||
}
|
||||
+403
@@ -0,0 +1,403 @@
|
||||
/*!
|
||||
* dragtable
|
||||
*
|
||||
* @Version 2.0.15
|
||||
*
|
||||
* Copyright (c) 2010-2013, Andres akottr@gmail.com
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* Inspired by the the dragtable from Dan Vanderkam (danvk.org/dragtable/)
|
||||
* Thanks to the jquery and jqueryui comitters
|
||||
*
|
||||
* Any comment, bug report, feature-request is welcome
|
||||
* Feel free to contact me.
|
||||
*/
|
||||
|
||||
/* TOKNOW:
|
||||
* For IE7 you need this css rule:
|
||||
* table {
|
||||
* border-collapse: collapse;
|
||||
* }
|
||||
* Or take a clean reset.css (see http://meyerweb.com/eric/tools/css/reset/)
|
||||
*/
|
||||
|
||||
/* TODO: investigate
|
||||
* Does not work properly with css rule:
|
||||
* html {
|
||||
* overflow: -moz-scrollbars-vertical;
|
||||
* }
|
||||
* Workaround:
|
||||
* Fixing Firefox issues by scrolling down the page
|
||||
* http://stackoverflow.com/questions/2451528/jquery-ui-sortable-scroll-helper-element-offset-firefox-issue
|
||||
*
|
||||
* var start = $.noop;
|
||||
* var beforeStop = $.noop;
|
||||
* if($.browser.mozilla) {
|
||||
* var start = function (event, ui) {
|
||||
* if( ui.helper !== undefined )
|
||||
* ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() );
|
||||
* }
|
||||
* var beforeStop = function (event, ui) {
|
||||
* if( ui.offset !== undefined )
|
||||
* ui.helper.css('margin-top', 0);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* and pass this as start and stop function to the sortable initialisation
|
||||
* start: start,
|
||||
* beforeStop: beforeStop
|
||||
*/
|
||||
/*
|
||||
* Special thx to all pull requests comitters
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.widget("akottr.dragtable", {
|
||||
options: {
|
||||
revert: false, // smooth revert
|
||||
dragHandle: '.table-handle', // handle for moving cols, if not exists the whole 'th' is the handle
|
||||
maxMovingRows: 40, // 1 -> only header. 40 row should be enough, the rest is usually not in the viewport
|
||||
excludeFooter: false, // excludes the footer row(s) while moving other columns. Make sense if there is a footer with a colspan. */
|
||||
onlyHeaderThreshold: 100, // TODO: not implemented yet, switch automatically between entire col moving / only header moving
|
||||
dragaccept: null, // draggable cols -> default all
|
||||
persistState: null, // url or function -> plug in your custom persistState function right here. function call is persistState(originalTable)
|
||||
restoreState: null, // JSON-Object or function: some kind of experimental aka Quick-Hack TODO: do it better
|
||||
exact: true, // removes pixels, so that the overlay table width fits exactly the original table width
|
||||
clickDelay: 10, // ms to wait before rendering sortable list and delegating click event
|
||||
containment: null, // @see http://api.jqueryui.com/sortable/#option-containment, use it if you want to move in 2 dimesnions (together with axis: null)
|
||||
cursor: 'move', // @see http://api.jqueryui.com/sortable/#option-cursor
|
||||
cursorAt: false, // @see http://api.jqueryui.com/sortable/#option-cursorAt
|
||||
distance: 0, // @see http://api.jqueryui.com/sortable/#option-distance, for immediate feedback use "0"
|
||||
tolerance: 'pointer', // @see http://api.jqueryui.com/sortable/#option-tolerance
|
||||
axis: 'x', // @see http://api.jqueryui.com/sortable/#option-axis, Only vertical moving is allowed. Use 'x' or null. Use this in conjunction with the 'containment' setting
|
||||
beforeStart: $.noop, // returning FALSE will stop the execution chain.
|
||||
beforeMoving: $.noop,
|
||||
beforeReorganize: $.noop,
|
||||
beforeStop: $.noop
|
||||
},
|
||||
originalTable: {
|
||||
el: null,
|
||||
selectedHandle: null,
|
||||
sortOrder: null,
|
||||
startIndex: 0,
|
||||
endIndex: 0
|
||||
},
|
||||
sortableTable: {
|
||||
el: $(),
|
||||
selectedHandle: $(),
|
||||
movingRow: $()
|
||||
},
|
||||
persistState: function() {
|
||||
var _this = this;
|
||||
this.originalTable.el.find('th').each(function(i) {
|
||||
if (this.id !== '') {
|
||||
_this.originalTable.sortOrder[this.id] = i;
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: this.options.persistState,
|
||||
data: this.originalTable.sortOrder
|
||||
});
|
||||
},
|
||||
/*
|
||||
* persistObj looks like
|
||||
* {'id1':'2','id3':'3','id2':'1'}
|
||||
* table looks like
|
||||
* | id2 | id1 | id3 |
|
||||
*/
|
||||
_restoreState: function(persistObj) {
|
||||
for (var n in persistObj) {
|
||||
this.originalTable.startIndex = $('#' + n).closest('th').prevAll().length + 1;
|
||||
this.originalTable.endIndex = parseInt(persistObj[n], 10) + 1;
|
||||
this._bubbleCols();
|
||||
}
|
||||
},
|
||||
// bubble the moved col left or right
|
||||
_bubbleCols: function() {
|
||||
var i, j, col1, col2;
|
||||
var from = this.originalTable.startIndex;
|
||||
var to = this.originalTable.endIndex;
|
||||
/* Find children thead and tbody.
|
||||
* Only to process the immediate tr-children. Bugfix for inner tables
|
||||
*/
|
||||
var thtb = this.originalTable.el.children();
|
||||
if (this.options.excludeFooter) {
|
||||
thtb = thtb.not('tfoot');
|
||||
}
|
||||
if (from < to) {
|
||||
for (i = from; i < to; i++) {
|
||||
col1 = thtb.find('> tr > td:nth-child(' + i + ')')
|
||||
.add(thtb.find('> tr > th:nth-child(' + i + ')'));
|
||||
col2 = thtb.find('> tr > td:nth-child(' + (i + 1) + ')')
|
||||
.add(thtb.find('> tr > th:nth-child(' + (i + 1) + ')'));
|
||||
for (j = 0; j < col1.length; j++) {
|
||||
swapNodes(col1[j], col2[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = from; i > to; i--) {
|
||||
col1 = thtb.find('> tr > td:nth-child(' + i + ')')
|
||||
.add(thtb.find('> tr > th:nth-child(' + i + ')'));
|
||||
col2 = thtb.find('> tr > td:nth-child(' + (i - 1) + ')')
|
||||
.add(thtb.find('> tr > th:nth-child(' + (i - 1) + ')'));
|
||||
for (j = 0; j < col1.length; j++) {
|
||||
swapNodes(col1[j], col2[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_rearrangeTableBackroundProcessing: function() {
|
||||
var _this = this;
|
||||
return function() {
|
||||
_this._bubbleCols();
|
||||
_this.options.beforeStop(_this.originalTable);
|
||||
_this.sortableTable.el.remove();
|
||||
restoreTextSelection();
|
||||
// persist state if necessary
|
||||
if (_this.options.persistState !== null) {
|
||||
$.isFunction(_this.options.persistState) ? _this.options.persistState(_this.originalTable) : _this.persistState();
|
||||
}
|
||||
};
|
||||
},
|
||||
_rearrangeTable: function() {
|
||||
var _this = this;
|
||||
return function() {
|
||||
// remove handler-class -> handler is now finished
|
||||
_this.originalTable.selectedHandle.removeClass('dragtable-handle-selected');
|
||||
// add disabled class -> reorgorganisation starts soon
|
||||
_this.sortableTable.el.sortable("disable");
|
||||
_this.sortableTable.el.addClass('dragtable-disabled');
|
||||
_this.options.beforeReorganize(_this.originalTable, _this.sortableTable);
|
||||
// do reorganisation asynchronous
|
||||
// for chrome a little bit more than 1 ms because we want to force a rerender
|
||||
_this.originalTable.endIndex = _this.sortableTable.movingRow.prevAll().length + 1;
|
||||
setTimeout(_this._rearrangeTableBackroundProcessing(), 50);
|
||||
};
|
||||
},
|
||||
/*
|
||||
* Disrupts the table. The original table stays the same.
|
||||
* But on a layer above the original table we are constructing a list (ul > li)
|
||||
* each li with a separate table representig a single col of the original table.
|
||||
*/
|
||||
_generateSortable: function(e) {
|
||||
!e.cancelBubble && (e.cancelBubble = true);
|
||||
var _this = this;
|
||||
// table attributes
|
||||
var attrs = this.originalTable.el[0].attributes;
|
||||
var attrsString = '';
|
||||
for (var i = 0; i < attrs.length; i++) {
|
||||
if (attrs[i].nodeValue && attrs[i].nodeName != 'id' && attrs[i].nodeName != 'width') {
|
||||
attrsString += attrs[i].nodeName + '="' + attrs[i].nodeValue + '" ';
|
||||
}
|
||||
}
|
||||
|
||||
// row attributes
|
||||
var rowAttrsArr = [];
|
||||
//compute height, special handling for ie needed :-(
|
||||
var heightArr = [];
|
||||
this.originalTable.el.find('tr').slice(0, this.options.maxMovingRows).each(function(i, v) {
|
||||
// row attributes
|
||||
var attrs = this.attributes;
|
||||
var attrsString = "";
|
||||
for (var j = 0; j < attrs.length; j++) {
|
||||
if (attrs[j].nodeValue && attrs[j].nodeName != 'id') {
|
||||
attrsString += " " + attrs[j].nodeName + '="' + attrs[j].nodeValue + '"';
|
||||
}
|
||||
}
|
||||
rowAttrsArr.push(attrsString);
|
||||
heightArr.push($(this).height());
|
||||
});
|
||||
|
||||
// compute width, no special handling for ie needed :-)
|
||||
var widthArr = [];
|
||||
// compute total width, needed for not wrapping around after the screen ends (floating)
|
||||
var totalWidth = 0;
|
||||
/* Find children thead and tbody.
|
||||
* Only to process the immediate tr-children. Bugfix for inner tables
|
||||
*/
|
||||
var thtb = _this.originalTable.el.children();
|
||||
if (this.options.excludeFooter) {
|
||||
thtb = thtb.not('tfoot');
|
||||
}
|
||||
thtb.find('> tr > th').each(function(i, v) {
|
||||
var w = $(this).is(':visible') ? $(this).outerWidth() : 0;
|
||||
widthArr.push(w);
|
||||
totalWidth += w;
|
||||
});
|
||||
if(_this.options.exact) {
|
||||
var difference = totalWidth - _this.originalTable.el.outerWidth();
|
||||
widthArr[0] -= difference;
|
||||
}
|
||||
// one extra px on right and left side
|
||||
totalWidth += 2
|
||||
|
||||
var sortableHtml = '<ul class="dragtable-sortable" style="position:absolute; width:' + totalWidth + 'px;">';
|
||||
// assemble the needed html
|
||||
thtb.find('> tr > th').each(function(i, v) {
|
||||
var width_li = $(this).is(':visible') ? $(this).outerWidth() : 0;
|
||||
sortableHtml += '<li style="width:' + width_li + 'px;">';
|
||||
sortableHtml += '<table ' + attrsString + '>';
|
||||
var row = thtb.find('> tr > th:nth-child(' + (i + 1) + ')');
|
||||
if (_this.options.maxMovingRows > 1) {
|
||||
row = row.add(thtb.find('> tr > td:nth-child(' + (i + 1) + ')').slice(0, _this.options.maxMovingRows - 1));
|
||||
}
|
||||
row.each(function(j) {
|
||||
// TODO: May cause duplicate style-Attribute
|
||||
var row_content = $(this).clone().wrap('<div></div>').parent().html();
|
||||
if (row_content.toLowerCase().indexOf('<th') === 0) sortableHtml += "<thead>";
|
||||
sortableHtml += '<tr ' + rowAttrsArr[j] + '" style="height:' + heightArr[j] + 'px;">';
|
||||
sortableHtml += row_content;
|
||||
if (row_content.toLowerCase().indexOf('<th') === 0) sortableHtml += "</thead>";
|
||||
sortableHtml += '</tr>';
|
||||
});
|
||||
sortableHtml += '</table>';
|
||||
sortableHtml += '</li>';
|
||||
});
|
||||
sortableHtml += '</ul>';
|
||||
this.sortableTable.el = this.originalTable.el.before(sortableHtml).prev();
|
||||
// set width if necessary
|
||||
this.sortableTable.el.find('> li > table').each(function(i, v) {
|
||||
$(this).css('width', widthArr[i] + 'px');
|
||||
});
|
||||
|
||||
// assign this.sortableTable.selectedHandle
|
||||
this.sortableTable.selectedHandle = this.sortableTable.el.find('th .dragtable-handle-selected');
|
||||
|
||||
var items = !this.options.dragaccept ? 'li' : 'li:has(' + this.options.dragaccept + ')';
|
||||
this.sortableTable.el.sortable({
|
||||
items: items,
|
||||
stop: this._rearrangeTable(),
|
||||
// pass thru options for sortable widget
|
||||
revert: this.options.revert,
|
||||
tolerance: this.options.tolerance,
|
||||
containment: this.options.containment,
|
||||
cursor: this.options.cursor,
|
||||
cursorAt: this.options.cursorAt,
|
||||
distance: this.options.distance,
|
||||
axis: this.options.axis
|
||||
});
|
||||
|
||||
// assign start index
|
||||
this.originalTable.startIndex = $(e.target).closest('th').prevAll().length + 1;
|
||||
|
||||
this.options.beforeMoving(this.originalTable, this.sortableTable);
|
||||
// Start moving by delegating the original event to the new sortable table
|
||||
this.sortableTable.movingRow = this.sortableTable.el.find('> li:nth-child(' + this.originalTable.startIndex + ')');
|
||||
|
||||
// prevent the user from drag selecting "highlighting" surrounding page elements
|
||||
disableTextSelection();
|
||||
// clone the initial event and trigger the sort with it
|
||||
this.sortableTable.movingRow.trigger($.extend($.Event(e.type), {
|
||||
which: 1,
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY,
|
||||
pageX: e.pageX,
|
||||
pageY: e.pageY,
|
||||
screenX: e.screenX,
|
||||
screenY: e.screenY
|
||||
}));
|
||||
|
||||
// Some inner divs to deliver the posibillity to style the placeholder more sophisticated
|
||||
var placeholder = this.sortableTable.el.find('.ui-sortable-placeholder');
|
||||
if(!placeholder.height() <= 0) {
|
||||
placeholder.css('height', this.sortableTable.el.find('.ui-sortable-helper').height());
|
||||
}
|
||||
|
||||
placeholder.html('<div class="outer" style="height:100%;"><div class="inner" style="height:100%;"></div></div>');
|
||||
},
|
||||
bindTo: {},
|
||||
_create: function() {
|
||||
this.originalTable = {
|
||||
el: this.element,
|
||||
selectedHandle: $(),
|
||||
sortOrder: {},
|
||||
startIndex: 0,
|
||||
endIndex: 0
|
||||
};
|
||||
// bind draggable to 'th' by default
|
||||
this.bindTo = this.originalTable.el.find('th');
|
||||
// filter only the cols that are accepted
|
||||
if (this.options.dragaccept) {
|
||||
this.bindTo = this.bindTo.filter(this.options.dragaccept);
|
||||
}
|
||||
// bind draggable to handle if exists
|
||||
if (this.bindTo.find(this.options.dragHandle).length > 0) {
|
||||
this.bindTo = this.bindTo.find(this.options.dragHandle);
|
||||
}
|
||||
// restore state if necessary
|
||||
if (this.options.restoreState !== null) {
|
||||
$.isFunction(this.options.restoreState) ? this.options.restoreState(this.originalTable) : this._restoreState(this.options.restoreState);
|
||||
}
|
||||
var _this = this;
|
||||
this.bindTo.mousedown(function(evt) {
|
||||
// listen only to left mouse click
|
||||
if(evt.which!==1) return;
|
||||
if (_this.options.beforeStart(_this.originalTable) === false) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(this.downTimer);
|
||||
this.downTimer = setTimeout(function() {
|
||||
_this.originalTable.selectedHandle = $(this);
|
||||
_this.originalTable.selectedHandle.addClass('dragtable-handle-selected');
|
||||
_this._generateSortable(evt);
|
||||
}, _this.options.clickDelay);
|
||||
}).mouseup(function(evt) {
|
||||
clearTimeout(this.downTimer);
|
||||
});
|
||||
},
|
||||
redraw: function(){
|
||||
this.destroy();
|
||||
this._create();
|
||||
},
|
||||
destroy: function() {
|
||||
this.bindTo.unbind('mousedown');
|
||||
$.Widget.prototype.destroy.apply(this, arguments); // default destroy
|
||||
// now do other stuff particular to this widget
|
||||
}
|
||||
});
|
||||
|
||||
/** closure-scoped "private" functions **/
|
||||
|
||||
var body_onselectstart_save = $(document.body).attr('onselectstart'),
|
||||
body_unselectable_save = $(document.body).attr('unselectable');
|
||||
|
||||
// css properties to disable user-select on the body tag by appending a <style> tag to the <head>
|
||||
// remove any current document selections
|
||||
|
||||
function disableTextSelection() {
|
||||
// jQuery doesn't support the element.text attribute in MSIE 8
|
||||
// http://stackoverflow.com/questions/2692770/style-style-textcss-appendtohead-does-not-work-in-ie
|
||||
var $style = $('<style id="__dragtable_disable_text_selection__" type="text/css">body { -ms-user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;user-select:none; }</style>');
|
||||
$(document.head).append($style);
|
||||
$(document.body).attr('onselectstart', 'return false;').attr('unselectable', 'on');
|
||||
if (window.getSelection) {
|
||||
window.getSelection().removeAllRanges();
|
||||
} else {
|
||||
document.selection.empty(); // MSIE http://msdn.microsoft.com/en-us/library/ms535869%28v=VS.85%29.aspx
|
||||
}
|
||||
}
|
||||
|
||||
// remove the <style> tag, and restore the original <body> onselectstart attribute
|
||||
|
||||
function restoreTextSelection() {
|
||||
$('#__dragtable_disable_text_selection__').remove();
|
||||
if (body_onselectstart_save) {
|
||||
$(document.body).attr('onselectstart', body_onselectstart_save);
|
||||
} else {
|
||||
$(document.body).removeAttr('onselectstart');
|
||||
}
|
||||
if (body_unselectable_save) {
|
||||
$(document.body).attr('unselectable', body_unselectable_save);
|
||||
} else {
|
||||
$(document.body).removeAttr('unselectable');
|
||||
}
|
||||
}
|
||||
|
||||
function swapNodes(a, b) {
|
||||
var aparent = a.parentNode;
|
||||
var asibling = a.nextSibling === b ? a : a.nextSibling;
|
||||
b.parentNode.insertBefore(a, b);
|
||||
aparent.insertBefore(b, asibling);
|
||||
}
|
||||
})(jQuery);
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
.rc-handle-container {
|
||||
position: relative;
|
||||
}
|
||||
.rc-handle {
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
cursor: ew-resize;
|
||||
margin-left: -3px;
|
||||
z-index: 2;
|
||||
}
|
||||
table.rc-table-resizing {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
table.rc-table-resizing thead,
|
||||
table.rc-table-resizing thead > th,
|
||||
table.rc-table-resizing thead > th > a {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
+679
@@ -0,0 +1,679 @@
|
||||
/**
|
||||
* jquery-resizable-columns - Resizable table columns for jQuery
|
||||
* @date Sat May 16 2015 19:03:57 GMT+0100 (BST)
|
||||
* @version v0.1.0
|
||||
* @link http://dobtco.github.io/jquery-resizable-columns/
|
||||
* @license MIT
|
||||
*/
|
||||
(function e(t, n, r) {
|
||||
function s(o, u) {
|
||||
if (!n[o]) {
|
||||
if (!t[o]) {
|
||||
var a = typeof require == "function" && require;
|
||||
if (!u && a) return a(o, !0);
|
||||
if (i) return i(o, !0);
|
||||
var f = new Error("Cannot find module '" + o + "'");
|
||||
throw f.code = "MODULE_NOT_FOUND", f
|
||||
}
|
||||
var l = n[o] = {
|
||||
exports: {}
|
||||
};
|
||||
t[o][0].call(l.exports, function(e) {
|
||||
var n = t[o][1][e];
|
||||
return s(n ? n : e)
|
||||
}, l, l.exports, e, t, n, r)
|
||||
}
|
||||
return n[o].exports
|
||||
}
|
||||
var i = typeof require == "function" && require;
|
||||
for (var o = 0; o < r.length; o++) s(r[o]);
|
||||
return s
|
||||
})({
|
||||
1: [function(require, module, exports) {
|
||||
'use strict';
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
'default': obj
|
||||
};
|
||||
}
|
||||
|
||||
var _class = require('./class');
|
||||
|
||||
var _class2 = _interopRequireDefault(_class);
|
||||
|
||||
var _constants = require('./constants');
|
||||
|
||||
$.fn.resizableColumns = function(optionsOrMethod) {
|
||||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
args[_key - 1] = arguments[_key];
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
var $table = $(this);
|
||||
|
||||
var api = $table.data(_constants.DATA_API);
|
||||
if (!api) {
|
||||
api = new _class2['default']($table, optionsOrMethod);
|
||||
$table.data(_constants.DATA_API, api);
|
||||
} else if (typeof optionsOrMethod === 'string') {
|
||||
return api[optionsOrMethod].apply(api, args);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.resizableColumns = _class2['default'];
|
||||
|
||||
}, {
|
||||
"./class": 2,
|
||||
"./constants": 3
|
||||
}],
|
||||
2: [function(require, module, exports) {
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = (function() {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ('value' in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
return function(Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
})();
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError('Cannot call a class as a function');
|
||||
}
|
||||
}
|
||||
|
||||
var _constants = require('./constants');
|
||||
|
||||
/**
|
||||
Takes a <table /> element and makes it's columns resizable across both
|
||||
mobile and desktop clients.
|
||||
|
||||
@class ResizableColumns
|
||||
@param $table {jQuery} jQuery-wrapped <table> element to make resizable
|
||||
@param options {Object} Configuration object
|
||||
**/
|
||||
|
||||
var ResizableColumns = (function() {
|
||||
function ResizableColumns($table, options) {
|
||||
_classCallCheck(this, ResizableColumns);
|
||||
|
||||
this.ns = '.rc' + this.count++;
|
||||
|
||||
this.options = $.extend({}, ResizableColumns.defaults, options);
|
||||
|
||||
this.$window = $(window);
|
||||
this.$ownerDocument = $($table[0].ownerDocument);
|
||||
this.$table = $table;
|
||||
|
||||
this.refreshHeaders();
|
||||
this.restoreColumnWidths();
|
||||
this.syncHandleWidths();
|
||||
|
||||
this.bindEvents(this.$window, 'resize', this.syncHandleWidths.bind(this));
|
||||
|
||||
if (this.options.start) {
|
||||
this.bindEvents(this.$table, _constants.EVENT_RESIZE_START, this.options.start);
|
||||
}
|
||||
if (this.options.resize) {
|
||||
this.bindEvents(this.$table, _constants.EVENT_RESIZE, this.options.resize);
|
||||
}
|
||||
if (this.options.stop) {
|
||||
this.bindEvents(this.$table, _constants.EVENT_RESIZE_STOP, this.options.stop);
|
||||
}
|
||||
}
|
||||
|
||||
_createClass(ResizableColumns, [{
|
||||
key: 'refreshHeaders',
|
||||
|
||||
/**
|
||||
Refreshes the headers associated with this instances <table/> element and
|
||||
generates handles for them. Also assigns percentage widths.
|
||||
@method refreshHeaders
|
||||
**/
|
||||
value: function refreshHeaders() {
|
||||
// Allow the selector to be both a regular selctor string as well as
|
||||
// a dynamic callback
|
||||
var selector = this.options.selector;
|
||||
if (typeof selector === 'function') {
|
||||
selector = selector.call(this, this.$table);
|
||||
}
|
||||
|
||||
// Select all table headers
|
||||
this.$tableHeaders = this.$table.find(selector);
|
||||
|
||||
// Assign percentage widths first, then create drag handles
|
||||
this.assignPercentageWidths();
|
||||
this.createHandles();
|
||||
}
|
||||
}, {
|
||||
key: 'createHandles',
|
||||
|
||||
/**
|
||||
Creates dummy handle elements for all table header columns
|
||||
@method createHandles
|
||||
**/
|
||||
value: function createHandles() {
|
||||
var _this = this;
|
||||
|
||||
var ref = this.$handleContainer;
|
||||
if (ref != null) {
|
||||
ref.remove();
|
||||
}
|
||||
|
||||
this.$handleContainer = $('<div class=\'' + _constants.CLASS_HANDLE_CONTAINER + '\' />');
|
||||
this.$table.before(this.$handleContainer);
|
||||
|
||||
this.$tableHeaders.each(function(i, el) {
|
||||
var $current = _this.$tableHeaders.eq(i);
|
||||
var $next = _this.$tableHeaders.eq(i + 1);
|
||||
|
||||
if ($next.length === 0 || $current.is(_constants.SELECTOR_UNRESIZABLE) || $next.is(_constants.SELECTOR_UNRESIZABLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $handle = $('<div class=\'' + _constants.CLASS_HANDLE + '\' />').data(_constants.DATA_TH, $(el)).appendTo(_this.$handleContainer);
|
||||
});
|
||||
|
||||
this.bindEvents(this.$handleContainer, ['mousedown', 'touchstart'], '.' + _constants.CLASS_HANDLE, this.onPointerDown.bind(this));
|
||||
}
|
||||
}, {
|
||||
key: 'assignPercentageWidths',
|
||||
|
||||
/**
|
||||
Assigns a percentage width to all columns based on their current pixel width(s)
|
||||
@method assignPercentageWidths
|
||||
**/
|
||||
value: function assignPercentageWidths() {
|
||||
var _this2 = this;
|
||||
|
||||
this.$tableHeaders.each(function(_, el) {
|
||||
var $el = $(el);
|
||||
_this2.setWidth($el[0], $el.outerWidth() / _this2.$table.width() * 100);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'syncHandleWidths',
|
||||
|
||||
/**
|
||||
|
||||
@method syncHandleWidths
|
||||
**/
|
||||
value: function syncHandleWidths() {
|
||||
var _this3 = this;
|
||||
|
||||
var $container = this.$handleContainer;
|
||||
|
||||
$container.width(this.$table.width());
|
||||
|
||||
$container.find('.' + _constants.CLASS_HANDLE).each(function(_, el) {
|
||||
var $el = $(el);
|
||||
|
||||
var height = _this3.options.resizeFromBody ? _this3.$table.height() : _this3.$table.find('thead').height();
|
||||
|
||||
var left = $el.data(_constants.DATA_TH).outerWidth() + ($el.data(_constants.DATA_TH).offset().left - _this3.$handleContainer.offset().left);
|
||||
|
||||
$el.css({
|
||||
left: left,
|
||||
height: height
|
||||
});
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'saveColumnWidths',
|
||||
|
||||
/**
|
||||
Persists the column widths in localStorage
|
||||
@method saveColumnWidths
|
||||
**/
|
||||
value: function saveColumnWidths() {
|
||||
var _this4 = this;
|
||||
|
||||
this.$tableHeaders.each(function(_, el) {
|
||||
var $el = $(el);
|
||||
if (_this4.options.store && !$el.is(_constants.SELECTOR_UNRESIZABLE)) {
|
||||
_this4.options.store.set(_this4.generateColumnId($el), _this4.parseWidth(el));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'restoreColumnWidths',
|
||||
|
||||
/**
|
||||
Retrieves and sets the column widths from localStorage
|
||||
@method restoreColumnWidths
|
||||
**/
|
||||
value: function restoreColumnWidths() {
|
||||
var _this5 = this;
|
||||
|
||||
this.$tableHeaders.each(function(_, el) {
|
||||
var $el = $(el);
|
||||
|
||||
if (_this5.options.store && !$el.is(_constants.SELECTOR_UNRESIZABLE)) {
|
||||
var width = _this5.options.store.get(_this5.generateColumnId($el));
|
||||
|
||||
if (width != null) {
|
||||
_this5.setWidth(el, width);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'onPointerDown',
|
||||
|
||||
/**
|
||||
Pointer/mouse down handler
|
||||
@method onPointerDown
|
||||
@param event {Object} Event object associated with the interaction
|
||||
**/
|
||||
value: function onPointerDown(event) {
|
||||
// Only applies to left-click dragging
|
||||
if (event.which !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If a previous operation is defined, we missed the last mouseup.
|
||||
// Probably gobbled up by user mousing out the window then releasing.
|
||||
// We'll simulate a pointerup here prior to it
|
||||
if (this.operation) {
|
||||
this.onPointerUp(event);
|
||||
}
|
||||
|
||||
// Ignore non-resizable columns
|
||||
var $currentGrip = $(event.currentTarget);
|
||||
if ($currentGrip.is(_constants.SELECTOR_UNRESIZABLE)) {
|
||||
return;
|
||||
}
|
||||
console.log('鼠标单击')
|
||||
|
||||
var gripIndex = $currentGrip.index();
|
||||
var $leftColumn = this.$tableHeaders.eq(gripIndex).not(_constants.SELECTOR_UNRESIZABLE);
|
||||
var $rightColumn = this.$tableHeaders.eq(gripIndex + 1).not(_constants.SELECTOR_UNRESIZABLE);
|
||||
|
||||
var leftWidth = this.parseWidth($leftColumn[0]);
|
||||
var rightWidth = this.parseWidth($rightColumn[0]);
|
||||
|
||||
this.operation = {
|
||||
$leftColumn: $leftColumn,
|
||||
$rightColumn: $rightColumn,
|
||||
$currentGrip: $currentGrip,
|
||||
|
||||
startX: this.getPointerX(event),
|
||||
|
||||
widths: {
|
||||
left: leftWidth,
|
||||
right: rightWidth
|
||||
},
|
||||
newWidths: {
|
||||
left: leftWidth,
|
||||
right: rightWidth
|
||||
}
|
||||
};
|
||||
|
||||
this.bindEvents(this.$ownerDocument, ['mousemove', 'touchmove'], this.onPointerMove.bind(this));
|
||||
this.bindEvents(this.$ownerDocument, ['mouseup', 'touchend'], this.onPointerUp.bind(this));
|
||||
|
||||
this.$handleContainer.add(this.$table).addClass(_constants.CLASS_TABLE_RESIZING);
|
||||
|
||||
$leftColumn.add($rightColumn).add($currentGrip).addClass(_constants.CLASS_COLUMN_RESIZING);
|
||||
|
||||
this.triggerEvent(_constants.EVENT_RESIZE_START, [$leftColumn, $rightColumn, leftWidth, rightWidth], event);
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
}, {
|
||||
key: 'onPointerMove',
|
||||
|
||||
/**
|
||||
Pointer/mouse movement handler
|
||||
@method onPointerMove
|
||||
@param event {Object} Event object associated with the interaction
|
||||
**/
|
||||
value: function onPointerMove(event) {
|
||||
var op = this.operation;
|
||||
if (!this.operation) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the delta change between start and new mouse position, as a percentage of the table width
|
||||
var difference = (this.getPointerX(event) - op.startX) / this.$table.width() * 100;
|
||||
if (difference === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var leftColumn = op.$leftColumn[0];
|
||||
var rightColumn = op.$rightColumn[0];
|
||||
var widthLeft = undefined,
|
||||
widthRight = undefined;
|
||||
|
||||
if (difference > 0) {
|
||||
widthLeft = this.constrainWidth(op.widths.left + (op.widths.right - op.newWidths.right));
|
||||
widthRight = this.constrainWidth(op.widths.right - difference);
|
||||
} else if (difference < 0) {
|
||||
widthLeft = this.constrainWidth(op.widths.left + difference);
|
||||
widthRight = this.constrainWidth(op.widths.right + (op.widths.left - op.newWidths.left));
|
||||
}
|
||||
|
||||
if (leftColumn) {
|
||||
this.setWidth(leftColumn, widthLeft);
|
||||
}
|
||||
if (rightColumn) {
|
||||
this.setWidth(rightColumn, widthRight);
|
||||
}
|
||||
|
||||
op.newWidths.left = widthLeft;
|
||||
op.newWidths.right = widthRight;
|
||||
|
||||
return this.triggerEvent(_constants.EVENT_RESIZE, [op.$leftColumn, op.$rightColumn, widthLeft, widthRight], event);
|
||||
}
|
||||
}, {
|
||||
key: 'onPointerUp',
|
||||
|
||||
/**
|
||||
Pointer/mouse release handler
|
||||
@method onPointerUp
|
||||
@param event {Object} Event object associated with the interaction
|
||||
**/
|
||||
value: function onPointerUp(event) {
|
||||
var op = this.operation;
|
||||
if (!this.operation) {
|
||||
return;
|
||||
}
|
||||
this.unbindEvents(this.$ownerDocument, ['mouseup', 'touchend', 'mousemove', 'touchmove']);
|
||||
this.$handleContainer.add(this.$table).removeClass(_constants.CLASS_TABLE_RESIZING);
|
||||
|
||||
op.$leftColumn.add(op.$rightColumn).add(op.$currentGrip).removeClass(_constants.CLASS_COLUMN_RESIZING);
|
||||
this.syncHandleWidths();
|
||||
this.saveColumnWidths();
|
||||
|
||||
this.operation = null;
|
||||
// event.which = 0;
|
||||
console.log('鼠标抬起', event)
|
||||
this.onPointerDown(event);
|
||||
return this.triggerEvent(_constants.EVENT_RESIZE_STOP, [op.$leftColumn, op.$rightColumn, op.newWidths.left, op.newWidths.right], event);
|
||||
}
|
||||
}, {
|
||||
key: 'destroy',
|
||||
|
||||
/**
|
||||
Removes all event listeners, data, and added DOM elements. Takes
|
||||
the <table/> element back to how it was, and returns it
|
||||
@method destroy
|
||||
@return {jQuery} Original jQuery-wrapped <table> element
|
||||
**/
|
||||
value: function destroy() {
|
||||
var $table = this.$table;
|
||||
var $handles = this.$handleContainer.find('.' + _constants.CLASS_HANDLE);
|
||||
|
||||
this.unbindEvents(this.$window.add(this.$ownerDocument).add(this.$table).add($handles));
|
||||
|
||||
$handles.removeData(_constants.DATA_TH);
|
||||
$table.removeData(_constants.DATA_API);
|
||||
|
||||
this.$handleContainer.remove();
|
||||
this.$handleContainer = null;
|
||||
this.$tableHeaders = null;
|
||||
this.$table = null;
|
||||
|
||||
return $table;
|
||||
}
|
||||
}, {
|
||||
key: 'bindEvents',
|
||||
|
||||
/**
|
||||
Binds given events for this instance to the given target DOMElement
|
||||
@private
|
||||
@method bindEvents
|
||||
@param target {jQuery} jQuery-wrapped DOMElement to bind events to
|
||||
@param events {String|Array} Event name (or array of) to bind
|
||||
@param selectorOrCallback {String|Function} Selector string or callback
|
||||
@param [callback] {Function} Callback method
|
||||
**/
|
||||
value: function bindEvents($target, events, selectorOrCallback, callback) {
|
||||
if (typeof events === 'string') {
|
||||
events = events + this.ns;
|
||||
} else {
|
||||
events = events.join(this.ns + ' ') + this.ns;
|
||||
}
|
||||
|
||||
if (arguments.length > 3) {
|
||||
$target.on(events, selectorOrCallback, callback);
|
||||
} else {
|
||||
$target.on(events, selectorOrCallback);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'unbindEvents',
|
||||
|
||||
/**
|
||||
Unbinds events specific to this instance from the given target DOMElement
|
||||
@private
|
||||
@method unbindEvents
|
||||
@param target {jQuery} jQuery-wrapped DOMElement to unbind events from
|
||||
@param events {String|Array} Event name (or array of) to unbind
|
||||
**/
|
||||
value: function unbindEvents($target, events) {
|
||||
if (typeof events === 'string') {
|
||||
events = events + this.ns;
|
||||
} else if (events != null) {
|
||||
events = events.join(this.ns + ' ') + this.ns;
|
||||
} else {
|
||||
events = this.ns;
|
||||
}
|
||||
|
||||
$target.off(events);
|
||||
}
|
||||
}, {
|
||||
key: 'triggerEvent',
|
||||
|
||||
/**
|
||||
Triggers an event on the <table/> element for a given type with given
|
||||
arguments, also setting and allowing access to the originalEvent if
|
||||
given. Returns the result of the triggered event.
|
||||
@private
|
||||
@method triggerEvent
|
||||
@param type {String} Event name
|
||||
@param args {Array} Array of arguments to pass through
|
||||
@param [originalEvent] If given, is set on the event object
|
||||
@return {Mixed} Result of the event trigger action
|
||||
**/
|
||||
value: function triggerEvent(type, args, originalEvent) {
|
||||
var event = $.Event(type);
|
||||
if (event.originalEvent) {
|
||||
event.originalEvent = $.extend({}, originalEvent);
|
||||
}
|
||||
|
||||
return this.$table.trigger(event, [this].concat(args || []));
|
||||
}
|
||||
}, {
|
||||
key: 'generateColumnId',
|
||||
|
||||
/**
|
||||
Calculates a unique column ID for a given column DOMElement
|
||||
@private
|
||||
@method generateColumnId
|
||||
@param $el {jQuery} jQuery-wrapped column element
|
||||
@return {String} Column ID
|
||||
**/
|
||||
value: function generateColumnId($el) {
|
||||
return this.$table.data(_constants.DATA_COLUMNS_ID) + '-' + $el.data(_constants.DATA_COLUMN_ID);
|
||||
}
|
||||
}, {
|
||||
key: 'parseWidth',
|
||||
|
||||
/**
|
||||
Parses a given DOMElement's width into a float
|
||||
@private
|
||||
@method parseWidth
|
||||
@param element {DOMElement} Element to get width of
|
||||
@return {Number} Element's width as a float
|
||||
**/
|
||||
value: function parseWidth(element) {
|
||||
return element ? parseFloat(element.style.width.replace('%', '')) : 0;
|
||||
}
|
||||
}, {
|
||||
key: 'setWidth',
|
||||
|
||||
/**
|
||||
Sets the percentage width of a given DOMElement
|
||||
@private
|
||||
@method setWidth
|
||||
@param element {DOMElement} Element to set width on
|
||||
@param width {Number} Width, as a percentage, to set
|
||||
**/
|
||||
value: function setWidth(element, width) {
|
||||
width = width.toFixed(2);
|
||||
width = width > 0 ? width : 0;
|
||||
element.style.width = width + '%';
|
||||
}
|
||||
}, {
|
||||
key: 'constrainWidth',
|
||||
|
||||
/**
|
||||
Constrains a given width to the minimum and maximum ranges defined in
|
||||
the `minWidth` and `maxWidth` configuration options, respectively.
|
||||
@private
|
||||
@method constrainWidth
|
||||
@param width {Number} Width to constrain
|
||||
@return {Number} Constrained width
|
||||
**/
|
||||
value: function constrainWidth(width) {
|
||||
if (this.options.minWidth != undefined) {
|
||||
width = Math.max(this.options.minWidth, width);
|
||||
}
|
||||
|
||||
if (this.options.maxWidth != undefined) {
|
||||
width = Math.min(this.options.maxWidth, width);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
}, {
|
||||
key: 'getPointerX',
|
||||
|
||||
/**
|
||||
Given a particular Event object, retrieves the current pointer offset along
|
||||
the horizontal direction. Accounts for both regular mouse clicks as well as
|
||||
pointer-like systems (mobiles, tablets etc.)
|
||||
@private
|
||||
@method getPointerX
|
||||
@param event {Object} Event object associated with the interaction
|
||||
@return {Number} Horizontal pointer offset
|
||||
**/
|
||||
value: function getPointerX(event) {
|
||||
if (event.type.indexOf('touch') === 0) {
|
||||
return (event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]).pageX;
|
||||
}
|
||||
return event.pageX;
|
||||
}
|
||||
}]);
|
||||
|
||||
return ResizableColumns;
|
||||
})();
|
||||
|
||||
exports['default'] = ResizableColumns;
|
||||
|
||||
ResizableColumns.defaults = {
|
||||
selector: function selector($table) {
|
||||
if ($table.find('thead').length) {
|
||||
return _constants.SELECTOR_TH;
|
||||
}
|
||||
|
||||
return _constants.SELECTOR_TD;
|
||||
},
|
||||
store: window.store,
|
||||
syncHandlers: true,
|
||||
resizeFromBody: true,
|
||||
maxWidth: null,
|
||||
minWidth: 0.01
|
||||
};
|
||||
|
||||
ResizableColumns.count = 0;
|
||||
module.exports = exports['default'];
|
||||
|
||||
}, {
|
||||
"./constants": 3
|
||||
}],
|
||||
3: [function(require, module, exports) {
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
var DATA_API = 'resizableColumns';
|
||||
exports.DATA_API = DATA_API;
|
||||
var DATA_COLUMNS_ID = 'resizable-columns-id';
|
||||
exports.DATA_COLUMNS_ID = DATA_COLUMNS_ID;
|
||||
var DATA_COLUMN_ID = 'resizable-column-id';
|
||||
exports.DATA_COLUMN_ID = DATA_COLUMN_ID;
|
||||
var DATA_TH = 'th';
|
||||
|
||||
exports.DATA_TH = DATA_TH;
|
||||
var CLASS_TABLE_RESIZING = 'rc-table-resizing';
|
||||
exports.CLASS_TABLE_RESIZING = CLASS_TABLE_RESIZING;
|
||||
var CLASS_COLUMN_RESIZING = 'rc-column-resizing';
|
||||
exports.CLASS_COLUMN_RESIZING = CLASS_COLUMN_RESIZING;
|
||||
var CLASS_HANDLE = 'rc-handle';
|
||||
exports.CLASS_HANDLE = CLASS_HANDLE;
|
||||
var CLASS_HANDLE_CONTAINER = 'rc-handle-container';
|
||||
|
||||
exports.CLASS_HANDLE_CONTAINER = CLASS_HANDLE_CONTAINER;
|
||||
var EVENT_RESIZE_START = 'column:resize:start';
|
||||
exports.EVENT_RESIZE_START = EVENT_RESIZE_START;
|
||||
var EVENT_RESIZE = 'column:resize';
|
||||
exports.EVENT_RESIZE = EVENT_RESIZE;
|
||||
var EVENT_RESIZE_STOP = 'column:resize:stop';
|
||||
|
||||
exports.EVENT_RESIZE_STOP = EVENT_RESIZE_STOP;
|
||||
var SELECTOR_TH = 'tr:first > th:visible';
|
||||
exports.SELECTOR_TH = SELECTOR_TH;
|
||||
var SELECTOR_TD = 'tr:first > td:visible';
|
||||
exports.SELECTOR_TD = SELECTOR_TD;
|
||||
var SELECTOR_UNRESIZABLE = '[data-noresize]';
|
||||
exports.SELECTOR_UNRESIZABLE = SELECTOR_UNRESIZABLE;
|
||||
|
||||
}, {}],
|
||||
4: [function(require, module, exports) {
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
'default': obj
|
||||
};
|
||||
}
|
||||
|
||||
var _class = require('./class');
|
||||
|
||||
var _class2 = _interopRequireDefault(_class);
|
||||
|
||||
var _adapter = require('./adapter');
|
||||
|
||||
var _adapter2 = _interopRequireDefault(_adapter);
|
||||
|
||||
exports['default'] = _class2['default'];
|
||||
module.exports = exports['default'];
|
||||
|
||||
}, {
|
||||
"./adapter": 1,
|
||||
"./class": 2
|
||||
}]
|
||||
}, {}, [4])
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
.treegrid-indent {width:16px; height: 16px; display: inline-block; position: relative;}
|
||||
|
||||
.treegrid-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;}
|
||||
|
||||
.treegrid-expander-expanded{background-image: url(../img/collapse.png); }
|
||||
.treegrid-expander-collapsed{background-image: url(../img/expand.png);}
|
||||
Vendored
+2
File diff suppressed because one or more lines are too long
+13
File diff suppressed because one or more lines are too long
Vendored
+374
@@ -0,0 +1,374 @@
|
||||
$.fn.editableTable = function(options) {
|
||||
// Default options
|
||||
let defaultOptions = {
|
||||
cloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right',
|
||||
'text-align', 'font', 'font-size', 'font-family', 'font-weight',
|
||||
'border', 'border-top', 'border-bottom', 'border-left', 'border-right', 'color', 'background-color', 'border-radius'
|
||||
],
|
||||
columns: []
|
||||
}
|
||||
|
||||
// Overlay default options on user options
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
// The instance reference we'll pass to the user
|
||||
let _instance;
|
||||
|
||||
// Class to put on the editor to denote an error
|
||||
let errorClass = 'error';
|
||||
|
||||
// Something to tag the hidden input with
|
||||
let identifierAttribute = 'table-editor-input';
|
||||
|
||||
// Keycodes
|
||||
let ARROW_LEFT = 37,
|
||||
ARROW_UP = 38,
|
||||
ARROW_RIGHT = 39,
|
||||
ARROW_DOWN = 40,
|
||||
ENTER = 13,
|
||||
ESC = 27,
|
||||
TAB = 9,
|
||||
CONTROL = 17,
|
||||
LEFT_WINDOWS = 91,
|
||||
SELECT_KEY = 93;
|
||||
|
||||
// The table element
|
||||
let element = $(this);
|
||||
|
||||
// Show all columns and then hide any hidden ones
|
||||
element.find('th').show();
|
||||
options.columns.forEach((col, i) => {
|
||||
if (col.isHidden !== undefined && col.isHidden) element.find('th').eq(i).hide();
|
||||
});
|
||||
|
||||
// If there are actions, add a final blank table header
|
||||
if (options.actions !== undefined && options.actions.length > 0) {
|
||||
// Add header if we don't already have one
|
||||
if (!element.find('thead tr th[actions]').length) {
|
||||
element.find('thead tr').append($('<th actions=""></th>'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The textbox allowing user input. Only add if there's not already an editor input control around
|
||||
let editor;
|
||||
let existingEditor = element.parent().find(`input[${identifierAttribute}]`);
|
||||
if (existingEditor.length) {
|
||||
editor = existingEditor.first();
|
||||
} else {
|
||||
editor = $('<input>');
|
||||
}
|
||||
|
||||
// Add it to the DOM
|
||||
editor.attr(identifierAttribute, '')
|
||||
.css('position', 'absolute')
|
||||
.hide()
|
||||
.appendTo(element.parent());
|
||||
|
||||
// The `td` being "edited"
|
||||
let activeCell;
|
||||
|
||||
// Function to show the editor
|
||||
function showEditor(select) {
|
||||
// Set the active cell
|
||||
activeCell = element.find('td:focus:not([action])');
|
||||
if (activeCell.length) {
|
||||
// Get column def
|
||||
let currentColIndex = $(activeCell).parent().children('td').index($(activeCell));
|
||||
let columnDef = options.columns[currentColIndex];
|
||||
|
||||
// Prepare input control
|
||||
editor.val(activeCell.text()) // Throw the value in
|
||||
.removeClass(errorClass) // remove any error classes
|
||||
.show() // show it
|
||||
.offset(activeCell.offset()) // position it
|
||||
.css(activeCell.css(options.cloneProperties)) // make it look similar by cloning properties
|
||||
.width(activeCell.width()) // size it
|
||||
.height(activeCell.height()) // size it
|
||||
.focus(); // focus user input into it
|
||||
|
||||
// Set max length, if it's specified
|
||||
if (columnDef.maxLength !== undefined) editor.attr('maxlength', columnDef.maxLength);
|
||||
else editor.removeAttr('maxlength');
|
||||
|
||||
if (select) {
|
||||
editor.select();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function setActiveText() {
|
||||
let text = editor.val(),
|
||||
evt = $.Event('change'),
|
||||
originalContent;
|
||||
if (activeCell.text() === text || editor.hasClass(errorClass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
originalContent = activeCell.html();
|
||||
activeCell.text(text).trigger(evt, text);
|
||||
if (evt.result === false) {
|
||||
activeCell.html(originalContent);
|
||||
}
|
||||
};
|
||||
|
||||
// For traversing the table up/down/left/right by returning the adjacent cell
|
||||
function handleMovement(element, keycode) {
|
||||
if (keycode === ARROW_RIGHT) {
|
||||
return element.next('td');
|
||||
} else if (keycode === ARROW_LEFT) {
|
||||
return element.prev('td');
|
||||
} else if (keycode === ARROW_UP) {
|
||||
return element.parent().prev().children().eq(element.index());
|
||||
} else if (keycode === ARROW_DOWN) {
|
||||
return element.parent().next().children().eq(element.index());
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
// On the editor losing focus, hide the input
|
||||
editor.blur(function() {
|
||||
setActiveText();
|
||||
editor.hide();
|
||||
});
|
||||
|
||||
// Handle typing into the input
|
||||
editor.keydown(function(e) {
|
||||
if (e.which === ENTER) {
|
||||
setActiveText();
|
||||
editor.hide();
|
||||
activeCell.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
} else if (e.which === ESC) {
|
||||
editor.val(activeCell.text());
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
editor.hide();
|
||||
activeCell.focus();
|
||||
} else if (e.which === TAB) {
|
||||
activeCell.focus();
|
||||
} else if (this.selectionEnd - this.selectionStart === this.value.length) {
|
||||
let possibleMove = handleMovement(activeCell, e.which);
|
||||
if (possibleMove.length > 0) {
|
||||
possibleMove.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Validate cell input on typing or pasting
|
||||
editor.on('input paste', function() {
|
||||
let evt = $.Event('validate');
|
||||
activeCell.trigger(evt, editor.val());
|
||||
if (evt.result !== undefined) {
|
||||
if (evt.result === false) {
|
||||
editor.addClass(errorClass);
|
||||
} else {
|
||||
editor.removeClass(errorClass);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// On table clicking, move around cells
|
||||
element.on('click keypress dblclick', showEditor);
|
||||
element.keydown(function(e) {
|
||||
let prevent = true,
|
||||
possibleMove = handleMovement($(e.target), e.which);
|
||||
if (possibleMove.length > 0) {
|
||||
possibleMove.focus();
|
||||
} else if (e.which === ENTER) {
|
||||
showEditor(false);
|
||||
} else if (e.which === CONTROL || e.which === LEFT_WINDOWS || e.which === SELECT_KEY) {
|
||||
showEditor(true);
|
||||
prevent = false;
|
||||
} else {
|
||||
prevent = false;
|
||||
}
|
||||
if (prevent) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
element.find('td').prop('tabindex', 1);
|
||||
|
||||
$(window).on('resize', function() {
|
||||
if (editor.is(':visible')) {
|
||||
editor.offset(activeCell.offset())
|
||||
.width(activeCell.width())
|
||||
.height(activeCell.height());
|
||||
}
|
||||
});
|
||||
|
||||
function refresh() {
|
||||
$(element).editableTable(options);
|
||||
}
|
||||
|
||||
// Validate based on options
|
||||
$('table td').on('validate', function(evt, newValue) {
|
||||
let currentColIndex = $(evt.currentTarget).parent().children('td').index($(evt.currentTarget));
|
||||
let columnDef = options.columns[currentColIndex];
|
||||
let currentData = _instance.getData({
|
||||
convert: false
|
||||
}); // current data to allow user to validate based on existing data
|
||||
let isValid = columnDef.isValid && columnDef.isValid(newValue, currentData);
|
||||
return isValid;
|
||||
});
|
||||
|
||||
$('table td').on('change', function(evt, newValue) {
|
||||
let td = $(this);
|
||||
let currentColIndex = $(evt.currentTarget).parent().children('td').index($(evt.currentTarget));
|
||||
let columnDef = options.columns[currentColIndex];
|
||||
|
||||
if (columnDef.removeRowIfCleared && newValue == '') {
|
||||
td.parent('tr').remove();
|
||||
}
|
||||
|
||||
// Bind user-specified events if they exist
|
||||
if (typeof columnDef.afterChange == 'function') {
|
||||
columnDef.afterChange(newValue, td);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Set up the instance reference
|
||||
_instance = {
|
||||
// Get table back out as JSON
|
||||
getData: function(opts) {
|
||||
opts = $.extend({}, {
|
||||
convert: true
|
||||
}, opts);
|
||||
|
||||
let rowData = [];
|
||||
element.find('tbody tr').toArray().forEach(row => {
|
||||
let newRow = {};
|
||||
|
||||
$(row).find('td:not([action])').toArray().forEach(col => {
|
||||
let columnsDef = options.columns[
|
||||
$(col).parent().children('td').index($(col)) // only index at cells, or "td"s
|
||||
];
|
||||
|
||||
let value = $(col).text();
|
||||
|
||||
// Check if the cell was marked as having a null value, and if so, extract as null and not
|
||||
// as a blank string
|
||||
let isNull = $(col).attr('data-is-null');
|
||||
if (typeof isNull !== 'undefined' && isNull !== false) {
|
||||
value = null;
|
||||
}
|
||||
|
||||
// Convert if requried
|
||||
if (opts.convert && typeof columnsDef.convertOut == 'function') {
|
||||
value = columnsDef.convertOut(value);
|
||||
}
|
||||
|
||||
newRow[columnsDef.name] = value;
|
||||
});
|
||||
|
||||
rowData.push(newRow);
|
||||
});
|
||||
return rowData;
|
||||
},
|
||||
|
||||
// Add a new row with JSON
|
||||
addRow: function(row) {
|
||||
let newRow = $(`<tr></tr>`);
|
||||
|
||||
if (row !== undefined && row !== null) {
|
||||
let props = Object.keys(row);
|
||||
|
||||
let columnsToAdd = [];
|
||||
props.forEach(prop => {
|
||||
let columnDef = options.columns.filter(col => col.name === prop);
|
||||
if (columnDef.length) {
|
||||
columnDef = columnDef[0];
|
||||
columnsToAdd.push({
|
||||
order: columnDef.index,
|
||||
value: row[prop],
|
||||
prop: prop,
|
||||
def: columnDef
|
||||
});
|
||||
}
|
||||
})
|
||||
columnsToAdd.sort((a, b) => a.order - b.order).forEach((colToAdd, index) => {
|
||||
let newCell;
|
||||
if (colToAdd.value !== null)
|
||||
newCell = $(`<td>${colToAdd.value}</td>`);
|
||||
else
|
||||
newCell = $(`<td data-is-null></td>`);
|
||||
|
||||
// Apply any classes
|
||||
if (colToAdd.def.classes !== undefined && colToAdd.def.classes.length) {
|
||||
colToAdd.def.classes.forEach(classToAdd => newCell.addClass(classToAdd));
|
||||
}
|
||||
|
||||
// Apply any style
|
||||
if (colToAdd.def.style !== undefined && colToAdd.def.style.length) {
|
||||
newCell.attr("style", newCell.attr("style") + "; " + colToAdd.def.style);
|
||||
}
|
||||
|
||||
// Hide if hidden
|
||||
if (colToAdd.def.isHidden !== undefined && colToAdd.def.isHidden) {
|
||||
newCell.hide();
|
||||
}
|
||||
|
||||
// Add to the column
|
||||
newRow.append(newCell);
|
||||
|
||||
// Trigger any events
|
||||
let columnDef = options.columns.filter(col => col.name === colToAdd.prop)[0];
|
||||
if (typeof columnDef.afterAdd == 'function') {
|
||||
columnDef.afterAdd(colToAdd.value, newCell);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
newRow = $(`<tr></tr>`);
|
||||
activeOptions.columns.forEach(x => {
|
||||
newRow.append(`<td></td>`);
|
||||
});
|
||||
}
|
||||
|
||||
// Add actions if any
|
||||
if (options.actions !== undefined && options.actions.length > 0) {
|
||||
let actionsCell = $(`<td action></td>`);
|
||||
options.actions.forEach(a => {
|
||||
let actionElement = $(a.label);
|
||||
actionElement.css('cursor', 'pointer');
|
||||
actionElement.click(e => a.action(e, newRow))
|
||||
actionsCell.append(actionElement);
|
||||
});
|
||||
newRow.append(actionsCell);
|
||||
}
|
||||
|
||||
// Add the new row
|
||||
let lastRow = element.find('tbody tr:last');
|
||||
if (lastRow.length > 0)
|
||||
lastRow.after(newRow);
|
||||
else
|
||||
element.find('tbody').append(newRow);
|
||||
|
||||
refresh();
|
||||
},
|
||||
|
||||
// Clear the table
|
||||
clear: function() {
|
||||
element.find('tbody tr').remove();
|
||||
},
|
||||
|
||||
// Set the table's data with JSON
|
||||
setData: function(data) {
|
||||
if (data) {
|
||||
this.clear();
|
||||
data.forEach(datum => {
|
||||
this.addRow(datum);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return _instance;
|
||||
};
|
||||
+2
File diff suppressed because one or more lines are too long
+248
@@ -0,0 +1,248 @@
|
||||
/*! jquery.tablednd.js 20-11-2020 */ ! function(a, b, c, d) {
|
||||
var e = "touchstart mousedown",
|
||||
f = "touchmove mousemove",
|
||||
g = "touchend mouseup";
|
||||
a(c).ready(function() {
|
||||
function b(a) {
|
||||
for (var b = {}, c = a.match(/([^;:]+)/g) || []; c.length;) b[c.shift()] = c.shift().trim();
|
||||
return b
|
||||
}
|
||||
a("table").each(function() {
|
||||
"dnd" === a(this).data("table") && a(this).tableDnD({
|
||||
onDragStyle: a(this).data("ondragstyle") && b(a(this).data("ondragstyle")) || null,
|
||||
onDropStyle: a(this).data("ondropstyle") && b(a(this).data("ondropstyle")) || null,
|
||||
onDragClass: a(this).data("ondragclass") === d && "tDnD_whileDrag" || a(this).data("ondragclass"),
|
||||
onDrop: a(this).data("ondrop") && new Function("table", "row", a(this).data("ondrop")),
|
||||
onDragStart: a(this).data("ondragstart") && new Function("table", "row", a(this).data("ondragstart")),
|
||||
onDragStop: a(this).data("ondragstop") && new Function("table", "row", a(this).data("ondragstop")),
|
||||
scrollAmount: a(this).data("scrollamount") || 5,
|
||||
sensitivity: a(this).data("sensitivity") || 10,
|
||||
hierarchyLevel: a(this).data("hierarchylevel") || 0,
|
||||
indentArtifact: a(this).data("indentartifact") || '<div class="indent"> </div>',
|
||||
autoWidthAdjust: a(this).data("autowidthadjust") || !0,
|
||||
autoCleanRelations: a(this).data("autocleanrelations") || !0,
|
||||
jsonPretifySeparator: a(this).data("jsonpretifyseparator") || "\t",
|
||||
serializeRegexp: a(this).data("serializeregexp") && new RegExp(a(this).data("serializeregexp")) || /[^\-]*$/,
|
||||
serializeParamName: a(this).data("serializeparamname") || !1,
|
||||
dragHandle: a(this).data("draghandle") || null
|
||||
})
|
||||
})
|
||||
}), jQuery.tableDnD = {
|
||||
currentTable: null,
|
||||
dragObject: null,
|
||||
mouseOffset: null,
|
||||
oldX: 0,
|
||||
oldY: 0,
|
||||
build: function(b) {
|
||||
return this.each(function() {
|
||||
this.tableDnDConfig = a.extend({
|
||||
onDragStyle: null,
|
||||
onDropStyle: null,
|
||||
onDragClass: "tDnD_whileDrag",
|
||||
onDrop: null,
|
||||
onDragStart: null,
|
||||
onDragStop: null,
|
||||
scrollAmount: 5,
|
||||
sensitivity: 10,
|
||||
hierarchyLevel: 0,
|
||||
indentArtifact: '<div class="indent"> </div>',
|
||||
autoWidthAdjust: !0,
|
||||
autoCleanRelations: !0,
|
||||
jsonPretifySeparator: "\t",
|
||||
serializeRegexp: /[^\-]*$/,
|
||||
serializeParamName: !1,
|
||||
dragHandle: null
|
||||
}, b || {}), a.tableDnD.makeDraggable(this), this.tableDnDConfig.hierarchyLevel && a.tableDnD.makeIndented(this)
|
||||
}), this
|
||||
},
|
||||
makeIndented: function(b) {
|
||||
var c, d, e = b.tableDnDConfig,
|
||||
f = b.rows,
|
||||
g = a(f).first().find("td:first")[0],
|
||||
h = 0,
|
||||
i = 0;
|
||||
if (a(b).hasClass("indtd")) return null;
|
||||
d = a(b).addClass("indtd").attr("style"), a(b).css({
|
||||
whiteSpace: "nowrap"
|
||||
});
|
||||
for (var j = 0; j < f.length; j++) i < a(f[j]).find("td:first").text().length && (i = a(f[j]).find("td:first").text().length, c = j);
|
||||
for (a(g).css({
|
||||
width: "auto"
|
||||
}), j = 0; j < e.hierarchyLevel; j++) a(f[c]).find("td:first").prepend(e.indentArtifact);
|
||||
for (g && a(g).css({
|
||||
width: g.offsetWidth
|
||||
}), d && a(b).css(d), j = 0; j < e.hierarchyLevel; j++) a(f[c]).find("td:first").children(":first").remove();
|
||||
return e.hierarchyLevel && a(f).each(function() {
|
||||
(h = a(this).data("level") || 0) <= e.hierarchyLevel && a(this).data("level", h) || a(this).data("level", 0);
|
||||
for (var b = 0; b < a(this).data("level"); b++) a(this).find("td:first").prepend(e.indentArtifact)
|
||||
}), this
|
||||
},
|
||||
makeDraggable: function(b) {
|
||||
var c = b.tableDnDConfig;
|
||||
c.dragHandle && a(c.dragHandle, b).each(function() {
|
||||
a(this).bind(e, function(d) {
|
||||
return a.tableDnD.initialiseDrag(a(this).parents("tr")[0], b, this, d, c), !1
|
||||
})
|
||||
}) || a(b.rows).each(function() {
|
||||
a(this).hasClass("nodrag") ? a(this).css("cursor", "") : a(this).bind(e, function(d) {
|
||||
if ("TD" === d.target.tagName) return a.tableDnD.initialiseDrag(this, b, this, d, c), !1
|
||||
}).css("cursor", "move")
|
||||
})
|
||||
},
|
||||
currentOrder: function() {
|
||||
var b = this.currentTable.rows;
|
||||
return a.map(b, function(b) {
|
||||
return (a(b).data("level") + b.id).replace(/\s/g, "")
|
||||
}).join("")
|
||||
},
|
||||
initialiseDrag: function(b, d, e, h, i) {
|
||||
this.dragObject = b, this.currentTable = d, this.mouseOffset = this.getMouseOffset(e, h), this.originalOrder = this.currentOrder(), a(c).bind(f, this.mousemove).bind(g, this.mouseup), i.onDragStart && i.onDragStart(d, e)
|
||||
},
|
||||
updateTables: function() {
|
||||
this.each(function() {
|
||||
this.tableDnDConfig && a.tableDnD.makeDraggable(this)
|
||||
})
|
||||
},
|
||||
mouseCoords: function(a) {
|
||||
return a.originalEvent.changedTouches ? {
|
||||
x: a.originalEvent.changedTouches[0].clientX,
|
||||
y: a.originalEvent.changedTouches[0].clientY
|
||||
} : a.pageX || a.pageY ? {
|
||||
x: a.pageX,
|
||||
y: a.pageY
|
||||
} : {
|
||||
x: a.clientX + c.body.scrollLeft - c.body.clientLeft,
|
||||
y: a.clientY + c.body.scrollTop - c.body.clientTop
|
||||
}
|
||||
},
|
||||
getMouseOffset: function(a, c) {
|
||||
var d, e;
|
||||
return c = c || b.event, e = this.getPosition(a), d = this.mouseCoords(c), {
|
||||
x: d.x - e.x,
|
||||
y: d.y - e.y
|
||||
}
|
||||
},
|
||||
getPosition: function(a) {
|
||||
for (var b = 0, c = 0; a.offsetParent;) b += a.offsetLeft, c += a.offsetTop, a = a.offsetParent;
|
||||
return b += a.offsetLeft, c += a.offsetTop, {
|
||||
x: b,
|
||||
y: c
|
||||
}
|
||||
},
|
||||
autoScroll: function(a) {
|
||||
var d = this.currentTable.tableDnDConfig,
|
||||
e = b.pageYOffset,
|
||||
f = b.innerHeight ? b.innerHeight : c.documentElement.clientHeight ? c.documentElement.clientHeight : c.body.clientHeight;
|
||||
c.all && (void 0 !== c.compatMode && "BackCompat" !== c.compatMode ? e = c.documentElement.scrollTop : void 0 !== c.body && (e = c.body.scrollTop)), a.y - e < d.scrollAmount && b.scrollBy(0, -d.scrollAmount) || f - (a.y - e) < d.scrollAmount && b.scrollBy(0, d.scrollAmount)
|
||||
},
|
||||
moveVerticle: function(a, b) {
|
||||
0 !== a.vertical && b && this.dragObject !== b && this.dragObject.parentNode === b.parentNode && (0 > a.vertical && this.dragObject.parentNode.insertBefore(this.dragObject, b.nextSibling) || 0 < a.vertical && this.dragObject.parentNode.insertBefore(this.dragObject, b))
|
||||
},
|
||||
moveHorizontal: function(b, c) {
|
||||
var d, e = this.currentTable.tableDnDConfig;
|
||||
if (!e.hierarchyLevel || 0 === b.horizontal || !c || this.dragObject !== c) return null;
|
||||
d = a(c).data("level"), 0 < b.horizontal && d > 0 && a(c).find("td:first").children(":first").remove() && a(c).data("level", --d), 0 > b.horizontal && d < e.hierarchyLevel && a(c).prev().data("level") >= d && a(c).children(":first").prepend(e.indentArtifact) && a(c).data("level", ++d)
|
||||
},
|
||||
mousemove: function(b) {
|
||||
var c, d, e, f, g, h = a(a.tableDnD.dragObject),
|
||||
i = a.tableDnD.currentTable.tableDnDConfig;
|
||||
return b && b.preventDefault(), !!a.tableDnD.dragObject && ("touchmove" === b.type && event.preventDefault(), i.onDragClass && h.addClass(i.onDragClass) || h.css(i.onDragStyle), d = a.tableDnD.mouseCoords(b), f = d.x - a.tableDnD.mouseOffset.x, g = d.y - a.tableDnD.mouseOffset.y, a.tableDnD.autoScroll(d), c = a.tableDnD.findDropTargetRow(h, g), e = a.tableDnD.findDragDirection(f, g), a.tableDnD.moveVerticle(e, c), a.tableDnD.moveHorizontal(e, c), !1)
|
||||
},
|
||||
findDragDirection: function(a, b) {
|
||||
var c = this.currentTable.tableDnDConfig.sensitivity,
|
||||
d = this.oldX,
|
||||
e = this.oldY,
|
||||
f = d - c,
|
||||
g = d + c,
|
||||
h = e - c,
|
||||
i = e + c,
|
||||
j = {
|
||||
horizontal: a >= f && a <= g ? 0 : a > d ? -1 : 1,
|
||||
vertical: b >= h && b <= i ? 0 : b > e ? -1 : 1
|
||||
};
|
||||
return 0 !== j.horizontal && (this.oldX = a), 0 !== j.vertical && (this.oldY = b), j
|
||||
},
|
||||
findDropTargetRow: function(b, c) {
|
||||
for (var d = 0, e = this.currentTable.rows, f = this.currentTable.tableDnDConfig, g = 0, h = null, i = 0; i < e.length; i++)
|
||||
if (h = e[i], g = this.getPosition(h).y, d = parseInt(h.offsetHeight) / 2, 0 === h.offsetHeight && (g = this.getPosition(h.firstChild).y, d = parseInt(h.firstChild.offsetHeight) / 2), c > g - d && c < g + d) return b.is(h) || f.onAllowDrop && !f.onAllowDrop(b, h) || a(h).hasClass("nodrop") ? null : h;
|
||||
return null
|
||||
},
|
||||
processMouseup: function() {
|
||||
if (!this.currentTable || !this.dragObject) return null;
|
||||
var b = this.currentTable.tableDnDConfig,
|
||||
d = this.dragObject,
|
||||
e = 0,
|
||||
h = 0;
|
||||
a(c).unbind(f, this.mousemove).unbind(g, this.mouseup), b.hierarchyLevel && b.autoCleanRelations && a(this.currentTable.rows).first().find("td:first").children().each(function() {
|
||||
(h = a(this).parents("tr:first").data("level")) && a(this).parents("tr:first").data("level", --h) && a(this).remove()
|
||||
}) && b.hierarchyLevel > 1 && a(this.currentTable.rows).each(function() {
|
||||
if ((h = a(this).data("level")) > 1)
|
||||
for (e = a(this).prev().data("level"); h > e + 1;) a(this).find("td:first").children(":first").remove(), a(this).data("level", --h)
|
||||
}), b.onDragClass && a(d).removeClass(b.onDragClass) || a(d).css(b.onDropStyle), this.dragObject = null, b.onDrop && this.originalOrder !== this.currentOrder() && a(d).hide().fadeIn("fast") && b.onDrop(this.currentTable, d), b.onDragStop && b.onDragStop(this.currentTable, d), this.currentTable = null
|
||||
},
|
||||
mouseup: function(b) {
|
||||
return b && b.preventDefault(), a.tableDnD.processMouseup(), !1
|
||||
},
|
||||
jsonize: function(a) {
|
||||
var b = this.currentTable;
|
||||
return a ? JSON.stringify(this.tableData(b), null, b.tableDnDConfig.jsonPretifySeparator) : JSON.stringify(this.tableData(b))
|
||||
},
|
||||
serialize: function() {
|
||||
return a.param(this.tableData(this.currentTable))
|
||||
},
|
||||
serializeTable: function(a) {
|
||||
for (var b = "", c = a.tableDnDConfig.serializeParamName || a.id, d = a.rows, e = 0; e < d.length; e++) {
|
||||
b.length > 0 && (b += "&");
|
||||
var f = d[e].id;
|
||||
f && a.tableDnDConfig && a.tableDnDConfig.serializeRegexp && (f = f.match(a.tableDnDConfig.serializeRegexp)[0], b += c + "[]=" + f)
|
||||
}
|
||||
return b
|
||||
},
|
||||
serializeTables: function() {
|
||||
var b = [];
|
||||
return a("table").each(function() {
|
||||
this.id && b.push(a.param(a.tableDnD.tableData(this)))
|
||||
}), b.join("&")
|
||||
},
|
||||
tableData: function(b) {
|
||||
var c, d, e, f, g = b.tableDnDConfig,
|
||||
h = [],
|
||||
i = 0,
|
||||
j = 0,
|
||||
k = null,
|
||||
l = {};
|
||||
if (b || (b = this.currentTable), !b || !b.rows || !b.rows.length) return {
|
||||
error: {
|
||||
code: 500,
|
||||
message: "Not a valid table."
|
||||
}
|
||||
};
|
||||
if (!b.id && !g.serializeParamName) return {
|
||||
error: {
|
||||
code: 500,
|
||||
message: "No serializable unique id provided."
|
||||
}
|
||||
};
|
||||
f = g.autoCleanRelations && b.rows || a.makeArray(b.rows), d = g.serializeParamName || b.id, e = d, c = function(a) {
|
||||
return a && g && g.serializeRegexp ? a.match(g.serializeRegexp)[0] : a
|
||||
}, l[e] = [], !g.autoCleanRelations && a(f[0]).data("level") && f.unshift({
|
||||
id: "undefined"
|
||||
});
|
||||
for (var m = 0; m < f.length; m++)
|
||||
if (g.hierarchyLevel) {
|
||||
if (0 === (j = a(f[m]).data("level") || 0)) e = d, h = [];
|
||||
else if (j > i) h.push([e, i]), e = c(f[m - 1].id);
|
||||
else if (j < i)
|
||||
for (var n = 0; n < h.length; n++) h[n][1] === j && (e = h[n][0]), h[n][1] >= i && (h[n][1] = 0);
|
||||
i = j, a.isArray(l[e]) || (l[e] = []), k = c(f[m].id), k && l[e].push(k)
|
||||
} else(k = c(f[m].id)) && l[e].push(k);
|
||||
return l
|
||||
}
|
||||
}, jQuery.fn.extend({
|
||||
tableDnD: a.tableDnD.build,
|
||||
tableDnDUpdate: a.tableDnD.updateTables,
|
||||
tableDnDSerialize: a.proxy(a.tableDnD.serialize, a.tableDnD),
|
||||
tableDnDSerializeAll: a.tableDnD.serializeTables,
|
||||
tableDnDData: a.proxy(a.tableDnD.tableData, a.tableDnD)
|
||||
})
|
||||
}(jQuery, window, window.document);
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+74130
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+8
File diff suppressed because one or more lines are too long
+6
File diff suppressed because one or more lines are too long
+12587
File diff suppressed because one or more lines are too long
Vendored
+3394
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user