/*jshint evil:true, eqeqeq:false, eqnull:true, devel:true */
|
/*global jQuery, define */
|
(function( factory ) {
|
"use strict";
|
if ( typeof define === "function" && define.amd ) {
|
// AMD. Register as an anonymous module.
|
define([
|
"jquery",
|
"./grid.base",
|
"jquery-ui/dialog",
|
"jquery-ui/draggable",
|
"jquery-ui/droppable",
|
"jquery-ui/resizable",
|
"jquery-ui/sortable",
|
"./addons/ui.multiselect"
|
], factory );
|
} else {
|
// Browser globals
|
factory( jQuery );
|
}
|
}(function( $ ) {/*
|
**
|
* jqGrid addons using jQuery UI
|
* Author: Mark Williams
|
* Dual licensed under the MIT and GPL licenses:
|
* http://www.opensource.org/licenses/mit-license.php
|
* http://www.gnu.org/licenses/gpl-2.0.html
|
* depends on jQuery UI
|
**/
|
"use strict";
|
//module begin
|
if ($.jgrid.msie && $.jgrid.msiever()===8) {
|
$.expr[":"].hidden = function(elem) {
|
return elem.offsetWidth === 0 || elem.offsetHeight === 0 ||
|
elem.style.display === "none";
|
};
|
}
|
// requiere load multiselect before grid
|
$.jgrid._multiselect = false;
|
if($.ui) {
|
if ($.ui.multiselect ) {
|
if($.ui.multiselect.prototype._setSelected) {
|
var setSelected = $.ui.multiselect.prototype._setSelected;
|
$.ui.multiselect.prototype._setSelected = function(item,selected) {
|
var ret = setSelected.call(this,item,selected);
|
if (selected && this.selectedList) {
|
var elt = this.element;
|
this.selectedList.find('li').each(function() {
|
if ($(this).data('optionLink')) {
|
$(this).data('optionLink').remove().appendTo(elt);
|
}
|
});
|
}
|
return ret;
|
};
|
}
|
if($.ui.multiselect.prototype.destroy) {
|
$.ui.multiselect.prototype.destroy = function() {
|
this.element.show();
|
this.container.remove();
|
if ($.Widget === undefined) {
|
$.widget.prototype.destroy.apply(this, arguments);
|
} else {
|
$.Widget.prototype.destroy.apply(this, arguments);
|
}
|
};
|
}
|
$.jgrid._multiselect = true;
|
}
|
}
|
|
$.jgrid.extend({
|
sortableColumns : function (tblrow)
|
{
|
return this.each(function (){
|
var ts = this, tid= $.jgrid.jqID( ts.p.id );
|
function start() {ts.p.disableClick = true;}
|
var sortable_opts = {
|
"tolerance" : "pointer",
|
"axis" : "x",
|
"scrollSensitivity": "1",
|
"items": '>th:not(:has(#jqgh_'+tid+'_cb'+',#jqgh_'+tid+'_rn'+',#jqgh_'+tid+'_subgrid),:hidden)',
|
"placeholder": {
|
element: function(item) {
|
var el = $(document.createElement(item[0].nodeName))
|
.addClass(item[0].className+" ui-sortable-placeholder ui-state-highlight")
|
.removeClass("ui-sortable-helper")[0];
|
return el;
|
},
|
update: function(self, p) {
|
p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10));
|
p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10));
|
}
|
},
|
"update": function(event, ui) {
|
var p = $(ui.item).parent(),
|
th = $(">th", p),
|
colModel = ts.p.colModel,
|
cmMap = {}, tid= ts.p.id+"_";
|
$.each(colModel, function(i) { cmMap[this.name]=i; });
|
var permutation = [];
|
th.each(function() {
|
var id = $(">div", this).get(0).id.replace(/^jqgh_/, "").replace(tid,"");
|
if (cmMap.hasOwnProperty(id)) {
|
permutation.push(cmMap[id]);
|
}
|
});
|
|
$(ts).jqGrid("remapColumns",permutation, true, true);
|
if ($.isFunction(ts.p.sortable.update)) {
|
ts.p.sortable.update(permutation);
|
}
|
setTimeout(function(){ts.p.disableClick=false;}, 50);
|
}
|
};
|
if (ts.p.sortable.options) {
|
$.extend(sortable_opts, ts.p.sortable.options);
|
} else if ($.isFunction(ts.p.sortable)) {
|
ts.p.sortable = { "update" : ts.p.sortable };
|
}
|
if (sortable_opts.start) {
|
var s = sortable_opts.start;
|
sortable_opts.start = function(e,ui) {
|
start();
|
s.call(this,e,ui);
|
};
|
} else {
|
sortable_opts.start = start;
|
}
|
if (ts.p.sortable.exclude) {
|
sortable_opts.items += ":not("+ts.p.sortable.exclude+")";
|
}
|
var $e = tblrow.sortable(sortable_opts), dataObj = $e.data("sortable") || $e.data("uiSortable");
|
if (dataObj != null) {
|
dataObj.data("sortable").floating = true;
|
}
|
});
|
},
|
columnChooser : function(opts) {
|
var self = this, selector, select, colMap = {}, fixedCols = [], dopts, mopts, $dialogContent, multiselectData, listHeight,
|
colModel = self.jqGrid("getGridParam", "colModel"),
|
colNames = self.jqGrid("getGridParam", "colNames"),
|
getMultiselectWidgetData = function ($elem) {
|
return ($.ui.multiselect.prototype && $elem.data($.ui.multiselect.prototype.widgetFullName || $.ui.multiselect.prototype.widgetName)) ||
|
$elem.data("ui-multiselect") || $elem.data("multiselect");
|
},
|
regional = $.jgrid.getRegional(this[0], 'col');
|
|
if ($("#colchooser_" + $.jgrid.jqID(self[0].p.id)).length) { return; }
|
selector = $('<div id="colchooser_'+self[0].p.id+'" style="position:relative;overflow:hidden"><div><select multiple="multiple"></select></div></div>');
|
select = $('select', selector);
|
|
function insert(perm,i,v) {
|
var a, b;
|
if(i>=0){
|
a = perm.slice();
|
b = a.splice(i,Math.max(perm.length-i,i));
|
if(i>perm.length) { i = perm.length; }
|
a[i] = v;
|
return a.concat(b);
|
}
|
return perm;
|
}
|
function call(fn, obj) {
|
if (!fn) { return; }
|
if (typeof fn === 'string') {
|
if ($.fn[fn]) {
|
$.fn[fn].apply(obj, $.makeArray(arguments).slice(2));
|
}
|
} else if ($.isFunction(fn)) {
|
fn.apply(obj, $.makeArray(arguments).slice(2));
|
}
|
}
|
|
opts = $.extend({
|
width : 400,
|
height : 240,
|
classname : null,
|
done : function(perm) { if (perm) { self.jqGrid("remapColumns", perm, true); } },
|
/* msel is either the name of a ui widget class that
|
extends a multiselect, or a function that supports
|
creating a multiselect object (with no argument,
|
or when passed an object), and destroying it (when
|
passed the string "destroy"). */
|
msel : "multiselect",
|
/* "msel_opts" : {}, */
|
|
/* dlog is either the name of a ui widget class that
|
behaves in a dialog-like way, or a function, that
|
supports creating a dialog (when passed dlog_opts)
|
or destroying a dialog (when passed the string
|
"destroy")
|
*/
|
dlog : "dialog",
|
dialog_opts : {
|
minWidth: 470,
|
dialogClass: "ui-jqdialog"
|
},
|
/* dlog_opts is either an option object to be passed
|
to "dlog", or (more likely) a function that creates
|
the options object.
|
The default produces a suitable options object for
|
ui.dialog */
|
dlog_opts : function(options) {
|
var buttons = {};
|
buttons[options.bSubmit] = function() {
|
options.apply_perm();
|
options.cleanup(false);
|
};
|
buttons[options.bCancel] = function() {
|
options.cleanup(true);
|
};
|
return $.extend(true, {
|
buttons: buttons,
|
close: function() {
|
options.cleanup(true);
|
},
|
modal: options.modal || false,
|
resizable: options.resizable || true,
|
width: options.width + 70,
|
resize: function () {
|
var widgetData = getMultiselectWidgetData(select),
|
$thisDialogContent = widgetData.container.closest(".ui-dialog-content");
|
|
if ($thisDialogContent.length > 0 && typeof $thisDialogContent[0].style === "object") {
|
$thisDialogContent[0].style.width = "";
|
} else {
|
$thisDialogContent.css("width", ""); // or just remove width style
|
}
|
|
widgetData.selectedList.height(Math.max(widgetData.selectedContainer.height() - widgetData.selectedActions.outerHeight() - 1, 1));
|
widgetData.availableList.height(Math.max(widgetData.availableContainer.height() - widgetData.availableActions.outerHeight() - 1, 1));
|
}
|
}, options.dialog_opts || {});
|
},
|
/* Function to get the permutation array, and pass it to the
|
"done" function */
|
apply_perm : function() {
|
var perm = [];
|
$('option',select).each(function() {
|
if ($(this).is(":selected")) {
|
self.jqGrid("showCol", colModel[this.value].name);
|
} else {
|
self.jqGrid("hideCol", colModel[this.value].name);
|
}
|
});
|
|
//fixedCols.slice(0);
|
$('option[selected]',select).each(function() { perm.push(parseInt(this.value,10)); });
|
$.each(perm, function() { delete colMap[colModel[parseInt(this,10)].name]; });
|
$.each(colMap, function() {
|
var ti = parseInt(this,10);
|
perm = insert(perm,ti,ti);
|
});
|
if (opts.done) {
|
opts.done.call(self, perm);
|
}
|
self.jqGrid("setGridWidth", self[0].p.width, self[0].p.shrinkToFit);
|
},
|
/* Function to cleanup the dialog, and select. Also calls the
|
done function with no permutation (to indicate that the
|
columnChooser was aborted */
|
cleanup : function(calldone) {
|
call(opts.dlog, selector, 'destroy');
|
call(opts.msel, select, 'destroy');
|
selector.remove();
|
if (calldone && opts.done) {
|
opts.done.call(self);
|
}
|
},
|
msel_opts : {}
|
}, regional, opts || {} );
|
if($.ui) {
|
if ($.ui.multiselect && $.ui.multiselect.defaults) {
|
if (!$.jgrid._multiselect) {
|
// should be in language file
|
alert("Multiselect plugin loaded after jqGrid. Please load the plugin before the jqGrid!");
|
return;
|
}
|
// ??? the next line uses $.ui.multiselect.defaults which will be typically undefined
|
opts.msel_opts = $.extend($.ui.multiselect.defaults, opts.msel_opts);
|
}
|
}
|
if (opts.caption) {
|
selector.attr("title", opts.caption);
|
}
|
if (opts.classname) {
|
selector.addClass(opts.classname);
|
select.addClass(opts.classname);
|
}
|
if (opts.width) {
|
$(">div",selector).css({width: opts.width,margin:"0 auto"});
|
select.css("width", opts.width);
|
}
|
if (opts.height) {
|
$(">div",selector).css("height", opts.height);
|
select.css("height", opts.height - 10);
|
}
|
|
select.empty();
|
$.each(colModel, function(i) {
|
colMap[this.name] = i;
|
if (this.hidedlg) {
|
if (!this.hidden) {
|
fixedCols.push(i);
|
}
|
return;
|
}
|
|
select.append("<option value='"+i+"' "+
|
(this.hidden?"":"selected='selected'")+">"+$.jgrid.stripHtml(colNames[i])+"</option>");
|
});
|
|
dopts = $.isFunction(opts.dlog_opts) ? opts.dlog_opts.call(self, opts) : opts.dlog_opts;
|
call(opts.dlog, selector, dopts);
|
mopts = $.isFunction(opts.msel_opts) ? opts.msel_opts.call(self, opts) : opts.msel_opts;
|
call(opts.msel, select, mopts);
|
|
// fix height of elements of the multiselect widget
|
$dialogContent = $("#colchooser_" + $.jgrid.jqID(self[0].p.id));
|
|
$dialogContent.css({ margin: "auto" });
|
$dialogContent.find(">div").css({ width: "100%", height: "100%", margin: "auto" });
|
|
multiselectData = getMultiselectWidgetData(select);
|
multiselectData.container.css({ width: "100%", height: "100%", margin: "auto" });
|
|
multiselectData.selectedContainer.css({ width: multiselectData.options.dividerLocation * 100 + "%", height: "100%", margin: "auto", boxSizing: "border-box" });
|
multiselectData.availableContainer.css({ width: (100 - multiselectData.options.dividerLocation * 100) + "%", height: "100%", margin: "auto", boxSizing: "border-box" });
|
|
// set height for both selectedList and availableList
|
multiselectData.selectedList.css("height", "auto");
|
multiselectData.availableList.css("height", "auto");
|
listHeight = Math.max(multiselectData.selectedList.height(), multiselectData.availableList.height());
|
listHeight = Math.min(listHeight, $(window).height());
|
multiselectData.selectedList.css("height", listHeight);
|
multiselectData.availableList.css("height", listHeight);
|
},
|
sortableRows : function (opts) {
|
// Can accept all sortable options and events
|
return this.each(function(){
|
var $t = this;
|
if(!$t.grid) { return; }
|
// Currently we disable a treeGrid sortable
|
if($t.p.treeGrid) { return; }
|
if($.fn.sortable) {
|
opts = $.extend({
|
"cursor":"move",
|
"axis" : "y",
|
"items": " > .jqgrow"
|
},
|
opts || {});
|
if(opts.start && $.isFunction(opts.start)) {
|
opts._start_ = opts.start;
|
delete opts.start;
|
} else {opts._start_=false;}
|
if(opts.update && $.isFunction(opts.update)) {
|
opts._update_ = opts.update;
|
delete opts.update;
|
} else {opts._update_ = false;}
|
opts.start = function(ev,ui) {
|
$(ui.item).css("border-width","0");
|
$("td",ui.item).each(function(i){
|
this.style.width = $t.grid.cols[i].style.width;
|
});
|
if($t.p.subGrid) {
|
var subgid = $(ui.item).attr("id");
|
try {
|
$($t).jqGrid('collapseSubGridRow',subgid);
|
} catch (e) {}
|
}
|
if(opts._start_) {
|
opts._start_.apply(this,[ev,ui]);
|
}
|
};
|
opts.update = function (ev,ui) {
|
$(ui.item).css("border-width","");
|
if($t.p.rownumbers === true) {
|
$("td.jqgrid-rownum",$t.rows).each(function( i ){
|
$(this).html( i+1+(parseInt($t.p.page,10)-1)*parseInt($t.p.rowNum,10) );
|
});
|
}
|
if(opts._update_) {
|
opts._update_.apply(this,[ev,ui]);
|
}
|
};
|
$("tbody:first",$t).sortable(opts);
|
$("tbody:first > .jqgrow",$t).disableSelection();
|
}
|
});
|
},
|
gridDnD : function(opts) {
|
return this.each(function(){
|
var $t = this, i, cn;
|
if(!$t.grid) { return; }
|
// Currently we disable a treeGrid drag and drop
|
if($t.p.treeGrid) { return; }
|
if(!$.fn.draggable || !$.fn.droppable) { return; }
|
function updateDnD ()
|
{
|
var datadnd = $.data($t,"dnd");
|
$("tr.jqgrow:not(.ui-draggable)",$t).draggable($.isFunction(datadnd.drag) ? datadnd.drag.call($($t),datadnd) : datadnd.drag);
|
}
|
var appender = "<table id='jqgrid_dnd' class='ui-jqgrid-dnd'></table>";
|
if($("#jqgrid_dnd")[0] === undefined) {
|
$('body').append(appender);
|
}
|
|
if(typeof opts === 'string' && opts === 'updateDnD' && $t.p.jqgdnd===true) {
|
updateDnD();
|
return;
|
}
|
opts = $.extend({
|
"drag" : function (opts) {
|
return $.extend({
|
start : function (ev, ui) {
|
var i, subgid;
|
// if we are in subgrid mode try to collapse the node
|
if($t.p.subGrid) {
|
subgid = $(ui.helper).attr("id");
|
try {
|
$($t).jqGrid('collapseSubGridRow',subgid);
|
} catch (e) {}
|
}
|
// hack
|
// drag and drop does not insert tr in table, when the table has no rows
|
// we try to insert new empty row on the target(s)
|
for (i=0;i<$.data($t,"dnd").connectWith.length;i++){
|
if($($.data($t,"dnd").connectWith[i]).jqGrid('getGridParam','reccount') === 0 ){
|
$($.data($t,"dnd").connectWith[i]).jqGrid('addRowData','jqg_empty_row',{});
|
}
|
}
|
ui.helper.addClass("ui-state-highlight");
|
$("td",ui.helper).each(function(i) {
|
this.style.width = $t.grid.headers[i].width+"px";
|
});
|
if(opts.onstart && $.isFunction(opts.onstart) ) { opts.onstart.call($($t),ev,ui); }
|
},
|
stop :function(ev,ui) {
|
var i, ids;
|
if(ui.helper.dropped && !opts.dragcopy) {
|
ids = $(ui.helper).attr("id");
|
if(ids === undefined) { ids = $(this).attr("id"); }
|
$($t).jqGrid('delRowData',ids );
|
}
|
// if we have a empty row inserted from start event try to delete it
|
for (i=0;i<$.data($t,"dnd").connectWith.length;i++){
|
$($.data($t,"dnd").connectWith[i]).jqGrid('delRowData','jqg_empty_row');
|
}
|
if(opts.onstop && $.isFunction(opts.onstop) ) { opts.onstop.call($($t),ev,ui); }
|
}
|
},opts.drag_opts || {});
|
},
|
"drop" : function (opts) {
|
return $.extend({
|
accept: function(d) {
|
if (!$(d).hasClass('jqgrow')) { return d;}
|
var tid = $(d).closest("table.ui-jqgrid-btable");
|
if(tid.length > 0 && $.data(tid[0],"dnd") !== undefined) {
|
var cn = $.data(tid[0],"dnd").connectWith;
|
return $.inArray('#'+$.jgrid.jqID(this.id),cn) !== -1 ? true : false;
|
}
|
return false;
|
},
|
drop: function(ev, ui) {
|
if (!$(ui.draggable).hasClass('jqgrow')) { return; }
|
var accept = $(ui.draggable).attr("id");
|
var getdata = ui.draggable.parent().parent().jqGrid('getRowData',accept);
|
if(!opts.dropbyname) {
|
var j =0, tmpdata = {}, nm, key;
|
var dropmodel = $("#"+$.jgrid.jqID(this.id)).jqGrid('getGridParam','colModel');
|
try {
|
for (key in getdata) {
|
if (getdata.hasOwnProperty(key)) {
|
nm = dropmodel[j].name;
|
if( !(nm === 'cb' || nm === 'rn' || nm === 'subgrid' )) {
|
if(getdata.hasOwnProperty(key) && dropmodel[j]) {
|
tmpdata[nm] = getdata[key];
|
}
|
}
|
j++;
|
}
|
}
|
getdata = tmpdata;
|
} catch (e) {}
|
}
|
ui.helper.dropped = true;
|
if(opts.beforedrop && $.isFunction(opts.beforedrop) ) {
|
//parameters to this callback - event, element, data to be inserted, sender, reciever
|
// should return object which will be inserted into the reciever
|
var datatoinsert = opts.beforedrop.call(this,ev,ui,getdata,$('#'+$.jgrid.jqID($t.p.id)),$(this));
|
if (datatoinsert !== undefined && datatoinsert !== null && typeof datatoinsert === "object") { getdata = datatoinsert; }
|
}
|
if(ui.helper.dropped) {
|
var grid;
|
if(opts.autoid) {
|
if($.isFunction(opts.autoid)) {
|
grid = opts.autoid.call(this,getdata);
|
} else {
|
grid = Math.ceil(Math.random()*1000);
|
grid = opts.autoidprefix+grid;
|
}
|
}
|
// NULL is interpreted as undefined while null as object
|
$("#"+$.jgrid.jqID(this.id)).jqGrid('addRowData',grid,getdata,opts.droppos);
|
}
|
if(opts.ondrop && $.isFunction(opts.ondrop) ) { opts.ondrop.call(this,ev,ui, getdata); }
|
}}, opts.drop_opts || {});
|
},
|
"onstart" : null,
|
"onstop" : null,
|
"beforedrop": null,
|
"ondrop" : null,
|
"drop_opts" : {
|
"activeClass": "ui-state-active",
|
"hoverClass": "ui-state-hover"
|
},
|
"drag_opts" : {
|
"revert": "invalid",
|
"helper": "clone",
|
"cursor": "move",
|
"appendTo" : "#jqgrid_dnd",
|
"zIndex": 5000
|
},
|
"dragcopy": false,
|
"dropbyname" : false,
|
"droppos" : "first",
|
"autoid" : true,
|
"autoidprefix" : "dnd_"
|
}, opts || {});
|
|
if(!opts.connectWith) { return; }
|
opts.connectWith = opts.connectWith.split(",");
|
opts.connectWith = $.map(opts.connectWith,function(n){return $.trim(n);});
|
$.data($t,"dnd",opts);
|
|
if($t.p.reccount !== 0 && !$t.p.jqgdnd) {
|
updateDnD();
|
}
|
$t.p.jqgdnd = true;
|
for (i=0;i<opts.connectWith.length;i++){
|
cn =opts.connectWith[i];
|
$(cn).droppable($.isFunction(opts.drop) ? opts.drop.call($($t),opts) : opts.drop);
|
}
|
});
|
},
|
gridResize : function(opts) {
|
return this.each(function(){
|
var $t = this, gID = $.jgrid.jqID($t.p.id), req;
|
if(!$t.grid || !$.fn.resizable) { return; }
|
opts = $.extend({}, opts || {});
|
if(opts.alsoResize ) {
|
opts._alsoResize_ = opts.alsoResize;
|
delete opts.alsoResize;
|
} else {
|
opts._alsoResize_ = false;
|
}
|
if(opts.stop && $.isFunction(opts.stop)) {
|
opts._stop_ = opts.stop;
|
delete opts.stop;
|
} else {
|
opts._stop_ = false;
|
}
|
opts.stop = function (ev, ui) {
|
$($t).jqGrid('setGridParam',{height:$("#gview_"+gID+" .ui-jqgrid-bdiv").height()});
|
$($t).jqGrid('setGridWidth',ui.size.width,opts.shrinkToFit);
|
if(opts._stop_) { opts._stop_.call($t,ev,ui); }
|
if($t.p.caption) {
|
$("#gbox_"+ gID).css({ 'height': 'auto' });
|
}
|
if($t.p.frozenColumns) {
|
if (req ) clearTimeout(req);
|
req = setTimeout(function(){
|
if (req ) clearTimeout(req);
|
$("#" + gID).jqGrid("destroyFrozenColumns");
|
$("#" + gID).jqGrid("setFrozenColumns");
|
});
|
}
|
};
|
if(opts._alsoResize_) {
|
var optstest = "{\'#gview_"+gID+" .ui-jqgrid-bdiv\':true,'" +opts._alsoResize_+"':true}";
|
opts.alsoResize = eval('('+optstest+')'); // the only way that I found to do this
|
} else {
|
opts.alsoResize = $(".ui-jqgrid-bdiv","#gview_"+gID);
|
}
|
delete opts._alsoResize_;
|
$("#gbox_"+gID).resizable(opts);
|
});
|
}
|
});
|
//module end
|
}));
|