mirror of https://gitee.com/y_project/RuoYi.git
新增表格拖拽示例
parent
080c66d12b
commit
911fb59e56
|
@ -185,6 +185,15 @@ public class DemoTableController extends BaseController
|
||||||
return prefix + "/curd";
|
return prefix + "/curd";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格拖拽操作
|
||||||
|
*/
|
||||||
|
@GetMapping("/reorder")
|
||||||
|
public String reorder()
|
||||||
|
{
|
||||||
|
return prefix + "/reorder";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格其他操作
|
* 表格其他操作
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* @author: Dennis Hernández
|
||||||
|
* 实现表格拖拽功能
|
||||||
|
* @version: v1.0.1
|
||||||
|
*/
|
||||||
|
(function ($) {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var isSearch = false;
|
||||||
|
|
||||||
|
var rowAttr = function (row, index) {
|
||||||
|
return {
|
||||||
|
id: 'customId_' + index
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
reorderableRows: false,
|
||||||
|
onDragStyle: null,
|
||||||
|
onDropStyle: null,
|
||||||
|
onDragClass: "reorder_rows_onDragClass",
|
||||||
|
dragHandle: null,
|
||||||
|
useRowAttrFunc: false,
|
||||||
|
onReorderRowsDrag: function (table, row) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onReorderRowsDrop: function (table, row) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onReorderRow: function (newData) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'reorder-row.bs.table': 'onReorderRow'
|
||||||
|
});
|
||||||
|
|
||||||
|
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
||||||
|
_init = BootstrapTable.prototype.init,
|
||||||
|
_initSearch = BootstrapTable.prototype.initSearch;
|
||||||
|
|
||||||
|
BootstrapTable.prototype.init = function () {
|
||||||
|
|
||||||
|
if (!this.options.reorderableRows) {
|
||||||
|
_init.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
if (this.options.useRowAttrFunc) {
|
||||||
|
this.options.rowAttributes = rowAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
var onPostBody = this.options.onPostBody;
|
||||||
|
this.options.onPostBody = function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
that.makeRowsReorderable();
|
||||||
|
onPostBody.apply();
|
||||||
|
}, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
_init.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.initSearch = function () {
|
||||||
|
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
|
||||||
|
|
||||||
|
if (!this.options.reorderableRows) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Known issue after search if you reorder the rows the data is not display properly
|
||||||
|
//isSearch = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.makeRowsReorderable = function () {
|
||||||
|
if (this.options.cardView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
this.$el.tableDnD({
|
||||||
|
onDragStyle: that.options.onDragStyle,
|
||||||
|
onDropStyle: that.options.onDropStyle,
|
||||||
|
onDragClass: that.options.onDragClass,
|
||||||
|
onDrop: that.onDrop,
|
||||||
|
onDragStart: that.options.onReorderRowsDrag,
|
||||||
|
dragHandle: that.options.dragHandle
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BootstrapTable.prototype.onDrop = function (table, droppedRow) {
|
||||||
|
var tableBs = $(table),
|
||||||
|
tableBsData = tableBs.data('bootstrap.table'),
|
||||||
|
tableBsOptions = tableBs.data('bootstrap.table').options,
|
||||||
|
row = null,
|
||||||
|
newData = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < table.tBodies[0].rows.length; i++) {
|
||||||
|
row = $(table.tBodies[0].rows[i]);
|
||||||
|
newData.push(tableBsOptions.data[row.data('index')]);
|
||||||
|
row.data('index', i).attr('data-index', i);
|
||||||
|
}
|
||||||
|
|
||||||
|
tableBsOptions.data = tableBsOptions.data.slice(0, tableBsData.pageFrom - 1)
|
||||||
|
.concat(newData)
|
||||||
|
.concat(tableBsOptions.data.slice(tableBsData.pageTo));
|
||||||
|
|
||||||
|
//Call the user defined function
|
||||||
|
tableBsOptions.onReorderRowsDrop.apply(table, [table, droppedRow]);
|
||||||
|
|
||||||
|
//Call the event reorder-row
|
||||||
|
tableBsData.trigger('reorder-row', newData);
|
||||||
|
};
|
||||||
|
})(jQuery);
|
|
@ -0,0 +1,598 @@
|
||||||
|
/**
|
||||||
|
* TableDnD plug-in for JQuery, allows you to drag and drop table rows
|
||||||
|
* You can set up various options to control how the system will work
|
||||||
|
* Copyright (c) Denis Howlett <denish@isocra.com>
|
||||||
|
* License: MIT.
|
||||||
|
* See https://github.com/isocra/TableDnD
|
||||||
|
*/
|
||||||
|
!function ($, window, document, undefined) {
|
||||||
|
|
||||||
|
var startEvent = 'touchstart mousedown',
|
||||||
|
moveEvent = 'touchmove mousemove',
|
||||||
|
endEvent = 'touchend mouseup';
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
function parseStyle(css) {
|
||||||
|
var objMap = {},
|
||||||
|
parts = css.match(/([^;:]+)/g) || [];
|
||||||
|
while (parts.length)
|
||||||
|
objMap[parts.shift()] = parts.shift().trim();
|
||||||
|
|
||||||
|
return objMap;
|
||||||
|
}
|
||||||
|
$('table').each(function () {
|
||||||
|
if ($(this).data('table') === 'dnd') {
|
||||||
|
|
||||||
|
$(this).tableDnD({
|
||||||
|
onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null,
|
||||||
|
onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null,
|
||||||
|
onDragClass: $(this).data('ondragclass') === undefined && "tDnD_whileDrag" || $(this).data('ondragclass'),
|
||||||
|
onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null,
|
||||||
|
onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null,
|
||||||
|
onDragStop: $(this).data('ondragstop') && new Function('table', 'row' ,$(this).data('ondragstop')),
|
||||||
|
scrollAmount: $(this).data('scrollamount') || 5,
|
||||||
|
sensitivity: $(this).data('sensitivity') || 10,
|
||||||
|
hierarchyLevel: $(this).data('hierarchylevel') || 0,
|
||||||
|
indentArtifact: $(this).data('indentartifact') || '<div class="indent"> </div>',
|
||||||
|
autoWidthAdjust: $(this).data('autowidthadjust') || true,
|
||||||
|
autoCleanRelations: $(this).data('autocleanrelations') || true,
|
||||||
|
jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t',
|
||||||
|
serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/,
|
||||||
|
serializeParamName: $(this).data('serializeparamname') || false,
|
||||||
|
dragHandle: $(this).data('draghandle') || null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.tableDnD = {
|
||||||
|
/** Keep hold of the current table being dragged */
|
||||||
|
currentTable: null,
|
||||||
|
/** Keep hold of the current drag object if any */
|
||||||
|
dragObject: null,
|
||||||
|
/** The current mouse offset */
|
||||||
|
mouseOffset: null,
|
||||||
|
/** Remember the old value of X and Y so that we don't do too much processing */
|
||||||
|
oldX: 0,
|
||||||
|
oldY: 0,
|
||||||
|
|
||||||
|
/** Actually build the structure */
|
||||||
|
build: function(options) {
|
||||||
|
// Set up the defaults if any
|
||||||
|
|
||||||
|
this.each(function() {
|
||||||
|
// This is bound to each matching table, set up the defaults and override with user options
|
||||||
|
this.tableDnDConfig = $.extend({
|
||||||
|
onDragStyle: null,
|
||||||
|
onDropStyle: null,
|
||||||
|
// Add in the default class for whileDragging
|
||||||
|
onDragClass: "tDnD_whileDrag",
|
||||||
|
onDrop: null,
|
||||||
|
onDragStart: null,
|
||||||
|
onDragStop: null,
|
||||||
|
scrollAmount: 5,
|
||||||
|
/** Sensitivity setting will throttle the trigger rate for movement detection */
|
||||||
|
sensitivity: 10,
|
||||||
|
/** Hierarchy level to support parent child. 0 switches this functionality off */
|
||||||
|
hierarchyLevel: 0,
|
||||||
|
/** The html artifact to prepend the first cell with as indentation */
|
||||||
|
indentArtifact: '<div class="indent"> </div>',
|
||||||
|
/** Automatically adjust width of first cell */
|
||||||
|
autoWidthAdjust: true,
|
||||||
|
/** Automatic clean-up to ensure relationship integrity */
|
||||||
|
autoCleanRelations: true,
|
||||||
|
/** Specify a number (4) as number of spaces or any indent string for JSON.stringify */
|
||||||
|
jsonPretifySeparator: '\t',
|
||||||
|
/** The regular expression to use to trim row IDs */
|
||||||
|
serializeRegexp: /[^\-]*$/,
|
||||||
|
/** If you want to specify another parameter name instead of the table ID */
|
||||||
|
serializeParamName: false,
|
||||||
|
/** If you give the name of a class here, then only Cells with this class will be draggable */
|
||||||
|
dragHandle: null
|
||||||
|
}, options || {});
|
||||||
|
|
||||||
|
// Now make the rows draggable
|
||||||
|
$.tableDnD.makeDraggable(this);
|
||||||
|
// Prepare hierarchy support
|
||||||
|
this.tableDnDConfig.hierarchyLevel
|
||||||
|
&& $.tableDnD.makeIndented(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Don't break the chain
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
makeIndented: function (table) {
|
||||||
|
var config = table.tableDnDConfig,
|
||||||
|
rows = table.rows,
|
||||||
|
firstCell = $(rows).first().find('td:first')[0],
|
||||||
|
indentLevel = 0,
|
||||||
|
cellWidth = 0,
|
||||||
|
longestCell,
|
||||||
|
tableStyle;
|
||||||
|
|
||||||
|
if ($(table).hasClass('indtd'))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
tableStyle = $(table).addClass('indtd').attr('style');
|
||||||
|
$(table).css({whiteSpace: "nowrap"});
|
||||||
|
|
||||||
|
for (var w = 0; w < rows.length; w++) {
|
||||||
|
if (cellWidth < $(rows[w]).find('td:first').text().length) {
|
||||||
|
cellWidth = $(rows[w]).find('td:first').text().length;
|
||||||
|
longestCell = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(firstCell).css({width: 'auto'});
|
||||||
|
for (w = 0; w < config.hierarchyLevel; w++)
|
||||||
|
$(rows[longestCell]).find('td:first').prepend(config.indentArtifact);
|
||||||
|
firstCell && $(firstCell).css({width: firstCell.offsetWidth});
|
||||||
|
tableStyle && $(table).css(tableStyle);
|
||||||
|
|
||||||
|
for (w = 0; w < config.hierarchyLevel; w++)
|
||||||
|
$(rows[longestCell]).find('td:first').children(':first').remove();
|
||||||
|
|
||||||
|
config.hierarchyLevel
|
||||||
|
&& $(rows).each(function () {
|
||||||
|
indentLevel = $(this).data('level') || 0;
|
||||||
|
indentLevel <= config.hierarchyLevel
|
||||||
|
&& $(this).data('level', indentLevel)
|
||||||
|
|| $(this).data('level', 0);
|
||||||
|
for (var i = 0; i < $(this).data('level'); i++)
|
||||||
|
$(this).find('td:first').prepend(config.indentArtifact);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
/** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
|
||||||
|
makeDraggable: function(table) {
|
||||||
|
var config = table.tableDnDConfig;
|
||||||
|
|
||||||
|
config.dragHandle
|
||||||
|
// We only need to add the event to the specified cells
|
||||||
|
&& $(config.dragHandle, table).each(function() {
|
||||||
|
// The cell is bound to "this"
|
||||||
|
$(this).bind(startEvent, function(e) {
|
||||||
|
$.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
// For backwards compatibility, we add the event to the whole row
|
||||||
|
// get all the rows as a wrapped set
|
||||||
|
|| $(table.rows).each(function() {
|
||||||
|
// Iterate through each row, the row is bound to "this"
|
||||||
|
if (! $(this).hasClass("nodrag")) {
|
||||||
|
$(this).bind(startEvent, function(e) {
|
||||||
|
if (e.target.tagName === "TD") {
|
||||||
|
$.tableDnD.initialiseDrag(this, table, this, e, config);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}).css("cursor", "move"); // Store the tableDnD object
|
||||||
|
} else {
|
||||||
|
$(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
currentOrder: function() {
|
||||||
|
var rows = this.currentTable.rows;
|
||||||
|
return $.map(rows, function (val) {
|
||||||
|
return ($(val).data('level') + val.id).replace(/\s/g, '');
|
||||||
|
}).join('');
|
||||||
|
},
|
||||||
|
initialiseDrag: function(dragObject, table, target, e, config) {
|
||||||
|
this.dragObject = dragObject;
|
||||||
|
this.currentTable = table;
|
||||||
|
this.mouseOffset = this.getMouseOffset(target, e);
|
||||||
|
this.originalOrder = this.currentOrder();
|
||||||
|
|
||||||
|
// Now we need to capture the mouse up and mouse move event
|
||||||
|
// We can use bind so that we don't interfere with other event handlers
|
||||||
|
$(document)
|
||||||
|
.bind(moveEvent, this.mousemove)
|
||||||
|
.bind(endEvent, this.mouseup);
|
||||||
|
|
||||||
|
// Call the onDragStart method if there is one
|
||||||
|
config.onDragStart
|
||||||
|
&& config.onDragStart(table, target);
|
||||||
|
},
|
||||||
|
updateTables: function() {
|
||||||
|
this.each(function() {
|
||||||
|
// this is now bound to each matching table
|
||||||
|
if (this.tableDnDConfig)
|
||||||
|
$.tableDnD.makeDraggable(this);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** Get the mouse coordinates from the event (allowing for browser differences) */
|
||||||
|
mouseCoords: function(e) {
|
||||||
|
if (e.originalEvent.changedTouches)
|
||||||
|
return {
|
||||||
|
x: e.originalEvent.changedTouches[0].clientX,
|
||||||
|
y: e.originalEvent.changedTouches[0].clientY
|
||||||
|
};
|
||||||
|
|
||||||
|
if(e.pageX || e.pageY)
|
||||||
|
return {
|
||||||
|
x: e.pageX,
|
||||||
|
y: e.pageY
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: e.clientX + document.body.scrollLeft - document.body.clientLeft,
|
||||||
|
y: e.clientY + document.body.scrollTop - document.body.clientTop
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/** Given a target element and a mouse eent, get the mouse offset from that element.
|
||||||
|
To do this we need the element's position and the mouse position */
|
||||||
|
getMouseOffset: function(target, e) {
|
||||||
|
var mousePos,
|
||||||
|
docPos;
|
||||||
|
|
||||||
|
e = e || window.event;
|
||||||
|
|
||||||
|
docPos = this.getPosition(target);
|
||||||
|
mousePos = this.mouseCoords(e);
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: mousePos.x - docPos.x,
|
||||||
|
y: mousePos.y - docPos.y
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/** Get the position of an element by going up the DOM tree and adding up all the offsets */
|
||||||
|
getPosition: function(element) {
|
||||||
|
var left = 0,
|
||||||
|
top = 0;
|
||||||
|
|
||||||
|
// Safari fix -- thanks to Luis Chato for this!
|
||||||
|
// Safari 2 doesn't correctly grab the offsetTop of a table row
|
||||||
|
// this is detailed here:
|
||||||
|
// http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
|
||||||
|
// the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
|
||||||
|
// note that firefox will return a text node as a first child, so designing a more thorough
|
||||||
|
// solution may need to take that into account, for now this seems to work in firefox, safari, ie
|
||||||
|
if (element.offsetHeight === 0)
|
||||||
|
element = element.firstChild; // a table cell
|
||||||
|
|
||||||
|
while (element.offsetParent) {
|
||||||
|
left += element.offsetLeft;
|
||||||
|
top += element.offsetTop;
|
||||||
|
element = element.offsetParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
left += element.offsetLeft;
|
||||||
|
top += element.offsetTop;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: left,
|
||||||
|
y: top
|
||||||
|
};
|
||||||
|
},
|
||||||
|
autoScroll: function (mousePos) {
|
||||||
|
var config = this.currentTable.tableDnDConfig,
|
||||||
|
yOffset = window.pageYOffset,
|
||||||
|
windowHeight = window.innerHeight
|
||||||
|
? window.innerHeight
|
||||||
|
: document.documentElement.clientHeight
|
||||||
|
? document.documentElement.clientHeight
|
||||||
|
: document.body.clientHeight;
|
||||||
|
|
||||||
|
// Windows version
|
||||||
|
// yOffset=document.body.scrollTop;
|
||||||
|
if (document.all)
|
||||||
|
if (typeof document.compatMode !== 'undefined'
|
||||||
|
&& document.compatMode !== 'BackCompat')
|
||||||
|
yOffset = document.documentElement.scrollTop;
|
||||||
|
else if (typeof document.body !== 'undefined')
|
||||||
|
yOffset = document.body.scrollTop;
|
||||||
|
|
||||||
|
mousePos.y - yOffset < config.scrollAmount
|
||||||
|
&& window.scrollBy(0, - config.scrollAmount)
|
||||||
|
|| windowHeight - (mousePos.y - yOffset) < config.scrollAmount
|
||||||
|
&& window.scrollBy(0, config.scrollAmount);
|
||||||
|
|
||||||
|
},
|
||||||
|
moveVerticle: function (moving, currentRow) {
|
||||||
|
|
||||||
|
if (0 !== moving.vertical
|
||||||
|
// If we're over a row then move the dragged row to there so that the user sees the
|
||||||
|
// effect dynamically
|
||||||
|
&& currentRow
|
||||||
|
&& this.dragObject !== currentRow
|
||||||
|
&& this.dragObject.parentNode === currentRow.parentNode)
|
||||||
|
0 > moving.vertical
|
||||||
|
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling)
|
||||||
|
|| 0 < moving.vertical
|
||||||
|
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow);
|
||||||
|
|
||||||
|
},
|
||||||
|
moveHorizontal: function (moving, currentRow) {
|
||||||
|
var config = this.currentTable.tableDnDConfig,
|
||||||
|
currentLevel;
|
||||||
|
|
||||||
|
if (!config.hierarchyLevel
|
||||||
|
|| 0 === moving.horizontal
|
||||||
|
// We only care if moving left or right on the current row
|
||||||
|
|| !currentRow
|
||||||
|
|| this.dragObject !== currentRow)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
currentLevel = $(currentRow).data('level');
|
||||||
|
|
||||||
|
0 < moving.horizontal
|
||||||
|
&& currentLevel > 0
|
||||||
|
&& $(currentRow).find('td:first').children(':first').remove()
|
||||||
|
&& $(currentRow).data('level', --currentLevel);
|
||||||
|
|
||||||
|
0 > moving.horizontal
|
||||||
|
&& currentLevel < config.hierarchyLevel
|
||||||
|
&& $(currentRow).prev().data('level') >= currentLevel
|
||||||
|
&& $(currentRow).children(':first').prepend(config.indentArtifact)
|
||||||
|
&& $(currentRow).data('level', ++currentLevel);
|
||||||
|
|
||||||
|
},
|
||||||
|
mousemove: function(e) {
|
||||||
|
var dragObj = $($.tableDnD.dragObject),
|
||||||
|
config = $.tableDnD.currentTable.tableDnDConfig,
|
||||||
|
currentRow,
|
||||||
|
mousePos,
|
||||||
|
moving,
|
||||||
|
x,
|
||||||
|
y;
|
||||||
|
|
||||||
|
e && e.preventDefault();
|
||||||
|
|
||||||
|
if (!$.tableDnD.dragObject)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// prevent touch device screen scrolling
|
||||||
|
e.type === 'touchmove'
|
||||||
|
&& event.preventDefault(); // TODO verify this is event and not really e
|
||||||
|
|
||||||
|
// update the style to show we're dragging
|
||||||
|
config.onDragClass
|
||||||
|
&& dragObj.addClass(config.onDragClass)
|
||||||
|
|| dragObj.css(config.onDragStyle);
|
||||||
|
|
||||||
|
mousePos = $.tableDnD.mouseCoords(e);
|
||||||
|
x = mousePos.x - $.tableDnD.mouseOffset.x;
|
||||||
|
y = mousePos.y - $.tableDnD.mouseOffset.y;
|
||||||
|
|
||||||
|
// auto scroll the window
|
||||||
|
$.tableDnD.autoScroll(mousePos);
|
||||||
|
|
||||||
|
currentRow = $.tableDnD.findDropTargetRow(dragObj, y);
|
||||||
|
moving = $.tableDnD.findDragDirection(x, y);
|
||||||
|
|
||||||
|
$.tableDnD.moveVerticle(moving, currentRow);
|
||||||
|
$.tableDnD.moveHorizontal(moving, currentRow);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
findDragDirection: function (x,y) {
|
||||||
|
var sensitivity = this.currentTable.tableDnDConfig.sensitivity,
|
||||||
|
oldX = this.oldX,
|
||||||
|
oldY = this.oldY,
|
||||||
|
xMin = oldX - sensitivity,
|
||||||
|
xMax = oldX + sensitivity,
|
||||||
|
yMin = oldY - sensitivity,
|
||||||
|
yMax = oldY + sensitivity,
|
||||||
|
moving = {
|
||||||
|
horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1,
|
||||||
|
vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// update the old value
|
||||||
|
if (moving.horizontal !== 0)
|
||||||
|
this.oldX = x;
|
||||||
|
if (moving.vertical !== 0)
|
||||||
|
this.oldY = y;
|
||||||
|
|
||||||
|
return moving;
|
||||||
|
},
|
||||||
|
/** We're only worried about the y position really, because we can only move rows up and down */
|
||||||
|
findDropTargetRow: function(draggedRow, y) {
|
||||||
|
var rowHeight = 0,
|
||||||
|
rows = this.currentTable.rows,
|
||||||
|
config = this.currentTable.tableDnDConfig,
|
||||||
|
rowY = 0,
|
||||||
|
row = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < rows.length; i++) {
|
||||||
|
row = rows[i];
|
||||||
|
rowY = this.getPosition(row).y;
|
||||||
|
rowHeight = parseInt(row.offsetHeight) / 2;
|
||||||
|
if (row.offsetHeight === 0) {
|
||||||
|
rowY = this.getPosition(row.firstChild).y;
|
||||||
|
rowHeight = parseInt(row.firstChild.offsetHeight) / 2;
|
||||||
|
}
|
||||||
|
// Because we always have to insert before, we need to offset the height a bit
|
||||||
|
if (y > (rowY - rowHeight) && y < (rowY + rowHeight))
|
||||||
|
// that's the row we're over
|
||||||
|
// If it's the same as the current row, ignore it
|
||||||
|
if (draggedRow.is(row)
|
||||||
|
|| (config.onAllowDrop
|
||||||
|
&& !config.onAllowDrop(draggedRow, row))
|
||||||
|
// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
|
||||||
|
|| $(row).hasClass("nodrop"))
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
processMouseup: function() {
|
||||||
|
if (!this.currentTable || !this.dragObject)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var config = this.currentTable.tableDnDConfig,
|
||||||
|
droppedRow = this.dragObject,
|
||||||
|
parentLevel = 0,
|
||||||
|
myLevel = 0;
|
||||||
|
|
||||||
|
// Unbind the event handlers
|
||||||
|
$(document)
|
||||||
|
.unbind(moveEvent, this.mousemove)
|
||||||
|
.unbind(endEvent, this.mouseup);
|
||||||
|
|
||||||
|
config.hierarchyLevel
|
||||||
|
&& config.autoCleanRelations
|
||||||
|
&& $(this.currentTable.rows).first().find('td:first').children().each(function () {
|
||||||
|
myLevel = $(this).parents('tr:first').data('level');
|
||||||
|
myLevel
|
||||||
|
&& $(this).parents('tr:first').data('level', --myLevel)
|
||||||
|
&& $(this).remove();
|
||||||
|
})
|
||||||
|
&& config.hierarchyLevel > 1
|
||||||
|
&& $(this.currentTable.rows).each(function () {
|
||||||
|
myLevel = $(this).data('level');
|
||||||
|
if (myLevel > 1) {
|
||||||
|
parentLevel = $(this).prev().data('level');
|
||||||
|
while (myLevel > parentLevel + 1) {
|
||||||
|
$(this).find('td:first').children(':first').remove();
|
||||||
|
$(this).data('level', --myLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we have a dragObject, then we need to release it,
|
||||||
|
// The row will already have been moved to the right place so we just reset stuff
|
||||||
|
config.onDragClass
|
||||||
|
&& $(droppedRow).removeClass(config.onDragClass)
|
||||||
|
|| $(droppedRow).css(config.onDropStyle);
|
||||||
|
|
||||||
|
this.dragObject = null;
|
||||||
|
// Call the onDrop method if there is one
|
||||||
|
config.onDrop
|
||||||
|
&& this.originalOrder !== this.currentOrder()
|
||||||
|
&& $(droppedRow).hide().fadeIn('fast')
|
||||||
|
&& config.onDrop(this.currentTable, droppedRow);
|
||||||
|
|
||||||
|
// Call the onDragStop method if there is one
|
||||||
|
config.onDragStop
|
||||||
|
&& config.onDragStop(this.currentTable, droppedRow);
|
||||||
|
|
||||||
|
this.currentTable = null; // let go of the table too
|
||||||
|
},
|
||||||
|
mouseup: function(e) {
|
||||||
|
e && e.preventDefault();
|
||||||
|
$.tableDnD.processMouseup();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
jsonize: function(pretify) {
|
||||||
|
var table = this.currentTable;
|
||||||
|
if (pretify)
|
||||||
|
return JSON.stringify(
|
||||||
|
this.tableData(table),
|
||||||
|
null,
|
||||||
|
table.tableDnDConfig.jsonPretifySeparator
|
||||||
|
);
|
||||||
|
return JSON.stringify(this.tableData(table));
|
||||||
|
},
|
||||||
|
serialize: function() {
|
||||||
|
return $.param(this.tableData(this.currentTable));
|
||||||
|
},
|
||||||
|
serializeTable: function(table) {
|
||||||
|
var result = "";
|
||||||
|
var paramName = table.tableDnDConfig.serializeParamName || table.id;
|
||||||
|
var rows = table.rows;
|
||||||
|
for (var i=0; i<rows.length; i++) {
|
||||||
|
if (result.length > 0) result += "&";
|
||||||
|
var rowId = rows[i].id;
|
||||||
|
if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
|
||||||
|
rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
|
||||||
|
result += paramName + '[]=' + rowId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
serializeTables: function() {
|
||||||
|
var result = [];
|
||||||
|
$('table').each(function() {
|
||||||
|
this.id && result.push($.param($.tableDnD.tableData(this)));
|
||||||
|
});
|
||||||
|
return result.join('&');
|
||||||
|
},
|
||||||
|
tableData: function (table) {
|
||||||
|
var config = table.tableDnDConfig,
|
||||||
|
previousIDs = [],
|
||||||
|
currentLevel = 0,
|
||||||
|
indentLevel = 0,
|
||||||
|
rowID = null,
|
||||||
|
data = {},
|
||||||
|
getSerializeRegexp,
|
||||||
|
paramName,
|
||||||
|
currentID,
|
||||||
|
rows;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
table = this.currentTable;
|
||||||
|
if (!table || !table.rows || !table.rows.length)
|
||||||
|
return {error: { code: 500, message: "Not a valid table."}};
|
||||||
|
if (!table.id && !config.serializeParamName)
|
||||||
|
return {error: { code: 500, message: "No serializable unique id provided."}};
|
||||||
|
|
||||||
|
rows = config.autoCleanRelations
|
||||||
|
&& table.rows
|
||||||
|
|| $.makeArray(table.rows);
|
||||||
|
paramName = config.serializeParamName || table.id;
|
||||||
|
currentID = paramName;
|
||||||
|
|
||||||
|
getSerializeRegexp = function (rowId) {
|
||||||
|
if (rowId && config && config.serializeRegexp)
|
||||||
|
return rowId.match(config.serializeRegexp)[0];
|
||||||
|
return rowId;
|
||||||
|
};
|
||||||
|
|
||||||
|
data[currentID] = [];
|
||||||
|
!config.autoCleanRelations
|
||||||
|
&& $(rows[0]).data('level')
|
||||||
|
&& rows.unshift({id: 'undefined'});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (var i=0; i < rows.length; i++) {
|
||||||
|
if (config.hierarchyLevel) {
|
||||||
|
indentLevel = $(rows[i]).data('level') || 0;
|
||||||
|
if (indentLevel === 0) {
|
||||||
|
currentID = paramName;
|
||||||
|
previousIDs = [];
|
||||||
|
}
|
||||||
|
else if (indentLevel > currentLevel) {
|
||||||
|
previousIDs.push([currentID, currentLevel]);
|
||||||
|
currentID = getSerializeRegexp(rows[i-1].id);
|
||||||
|
}
|
||||||
|
else if (indentLevel < currentLevel) {
|
||||||
|
for (var h = 0; h < previousIDs.length; h++) {
|
||||||
|
if (previousIDs[h][1] === indentLevel)
|
||||||
|
currentID = previousIDs[h][0];
|
||||||
|
if (previousIDs[h][1] >= currentLevel)
|
||||||
|
previousIDs[h][1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentLevel = indentLevel;
|
||||||
|
|
||||||
|
if (!$.isArray(data[currentID]))
|
||||||
|
data[currentID] = [];
|
||||||
|
rowID = getSerializeRegexp(rows[i].id);
|
||||||
|
rowID && data[currentID].push(rowID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rowID = getSerializeRegexp(rows[i].id);
|
||||||
|
rowID && data[currentID].push(rowID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.fn.extend(
|
||||||
|
{
|
||||||
|
tableDnD : $.tableDnD.build,
|
||||||
|
tableDnDUpdate : $.tableDnD.updateTables,
|
||||||
|
tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD),
|
||||||
|
tableDnDSerializeAll : $.tableDnD.serializeTables,
|
||||||
|
tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}(jQuery, window, window.document);
|
|
@ -917,4 +917,12 @@ label {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
display: block;
|
display: block;
|
||||||
float:left;
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表格拖拽样式 **/
|
||||||
|
.reorder_rows_onDragClass td {
|
||||||
|
color:yellow!important;
|
||||||
|
background-color:#999!important;
|
||||||
|
text-shadow:0 0 10px black,0 0 10px black,0 0 8px black,0 0 6px black,0 0 6px black;
|
||||||
|
box-shadow:0 12px 14px -12px #111 inset,0 -2px 2px -1px #333 inset
|
||||||
}
|
}
|
|
@ -86,6 +86,7 @@
|
||||||
fixedNumber: options.fixedNumber, // 列冻结的个数(左侧)
|
fixedNumber: options.fixedNumber, // 列冻结的个数(左侧)
|
||||||
rightFixedColumns: options.rightFixedColumns, // 是否启用冻结列(右侧)
|
rightFixedColumns: options.rightFixedColumns, // 是否启用冻结列(右侧)
|
||||||
rightFixedNumber: options.rightFixedNumber, // 列冻结的个数(右侧)
|
rightFixedNumber: options.rightFixedNumber, // 列冻结的个数(右侧)
|
||||||
|
onReorderRow: options.onReorderRow, // 当拖拽结束后处理函数
|
||||||
queryParams: options.queryParams, // 传递参数(*)
|
queryParams: options.queryParams, // 传递参数(*)
|
||||||
rowStyle: options.rowStyle, // 通过自定义函数设置行样式
|
rowStyle: options.rowStyle, // 通过自定义函数设置行样式
|
||||||
columns: options.columns, // 显示列信息(*)
|
columns: options.columns, // 显示列信息(*)
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('表格拖拽操作')" />
|
||||||
|
</head>
|
||||||
|
<body class="gray-bg">
|
||||||
|
<div class="container-div">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 select-table table-striped">
|
||||||
|
<p class="select-title">按住表格拖拽</p>
|
||||||
|
<table id="bootstrap-table" data-mobile-responsive="true"
|
||||||
|
data-use-row-attr-func="true"
|
||||||
|
data-reorderable-rows="true"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:include="include :: footer"></div>
|
||||||
|
<th:block th:include="include :: bootstrap-table-reorder-js" />
|
||||||
|
<script th:inline="javascript">
|
||||||
|
var prefix = ctx + "demo/table";
|
||||||
|
var datas = [[${@dict.getType('sys_normal_disable')}]];
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
var options = {
|
||||||
|
url: prefix + "/list",
|
||||||
|
showSearch: false,
|
||||||
|
showRefresh: false,
|
||||||
|
showToggle: false,
|
||||||
|
showColumns: false,
|
||||||
|
onReorderRow: function (data) {
|
||||||
|
//当拖拽结束后,data为整个表格的数据
|
||||||
|
console.log('拖拽结束' + JSON.stringify(data))
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
columns: [{
|
||||||
|
checkbox: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userId',
|
||||||
|
title : '用户ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userCode',
|
||||||
|
title : '用户编号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userName',
|
||||||
|
title : '用户姓名'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userPhone',
|
||||||
|
title : '用户手机'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userEmail',
|
||||||
|
title : '用户邮箱'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field : 'userBalance',
|
||||||
|
title : '用户余额'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '用户状态',
|
||||||
|
align: 'center',
|
||||||
|
formatter: function(value, row, index) {
|
||||||
|
return $.table.selectDictLabel(datas, value);
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
$.table.init(options);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -166,4 +166,10 @@
|
||||||
<!-- sparkline线状图插件 -->
|
<!-- sparkline线状图插件 -->
|
||||||
<div th:fragment="sparkline-js">
|
<div th:fragment="sparkline-js">
|
||||||
<script th:src="@{/ajax/libs/report/sparkline/jquery.sparkline.min.js}"></script>
|
<script th:src="@{/ajax/libs/report/sparkline/jquery.sparkline.min.js}"></script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格拖拽插件 -->
|
||||||
|
<div th:fragment="bootstrap-table-reorder-js">
|
||||||
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/bootstrap-table-reorder.js}"></script>
|
||||||
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/jquery.tablednd.js}"></script>
|
||||||
</div>
|
</div>
|
|
@ -105,6 +105,7 @@
|
||||||
<li><a class="menuItem" th:href="@{/demo/table/detail}">表格细节视图</a></li>
|
<li><a class="menuItem" th:href="@{/demo/table/detail}">表格细节视图</a></li>
|
||||||
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
|
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
|
||||||
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
|
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
|
||||||
|
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
|
||||||
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
|
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue