/fa/jquery/jquery-ui/jqgrid/src/grid.jqueryui.js
JavaScript | 472 lines | 415 code | 14 blank | 43 comment | 113 complexity | c85bcd93fc653cc11b68ff43e78eaf88 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
1;(function($){
2/*
3**
4 * jqGrid addons using jQuery UI
5 * Author: Mark Williams
6 * Dual licensed under the MIT and GPL licenses:
7 * http://www.opensource.org/licenses/mit-license.php
8 * http://www.gnu.org/licenses/gpl.html
9 * depends on jQuery UI sortable
10**/
11if ($.browser.msie && $.browser.version==8) {
12 $.expr[":"].hidden = function(elem) {
13 return elem.offsetWidth === 0 || elem.offsetHeight === 0 ||
14 elem.style.display == "none";
15 }
16}
17
18if ($.ui && $.ui.multiselect && $.ui.multiselect.prototype._setSelected) {
19 var setSelected = $.ui.multiselect.prototype._setSelected;
20 $.ui.multiselect.prototype._setSelected = function(item,selected) {
21 var ret = setSelected.call(this,item,selected);
22 if (selected && this.selectedList) {
23 var elt = this.element;
24 this.selectedList.find('li').each(function() {
25 if ($(this).data('optionLink'))
26 $(this).data('optionLink').remove().appendTo(elt);
27 });
28 }
29 return ret;
30 }
31}
32
33$.jgrid.extend({
34 sortableColumns : function (tblrow)
35 {
36 return this.each(function (){
37 var ts = this;
38 function start() {ts.p.disableClick = true;};
39 var sortable_opts = {
40 "tolerance" : "pointer",
41 "axis" : "x",
42 "items": '>th:not(:has(#jqgh_cb,#jqgh_rn,#jqgh_subgrid),:hidden)',
43 "placeholder": {
44 element: function(item) {
45 var el = $(document.createElement(item[0].nodeName))
46 .addClass(item[0].className+" ui-sortable-placeholder ui-state-highlight")
47 .removeClass("ui-sortable-helper")[0];
48 return el;
49 },
50 update: function(self, p) {
51 p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10));
52 p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10));
53 }
54 },
55 "update": function(event, ui) {
56 var p = $(ui.item).parent();
57 var th = $(">th", p);
58 var colModel = ts.p.colModel;
59 var cmMap = {};
60 $.each(colModel, function(i) { cmMap[this.name]=i });
61 var permutation = [];
62 th.each(function(i) {
63 var id = $(">div", this).get(0).id.replace(/^jqgh_/, "");
64 if (id in cmMap) {
65 permutation.push(cmMap[id]);
66 }
67 });
68
69 $(ts).jqGrid("remapColumns",permutation, true, true);
70 if ($.isFunction(ts.p.sortable.update)) {
71 ts.p.sortable.update(permutation);
72 }
73 setTimeout(function(){ts.p.disableClick=false}, 50);
74 }
75 };
76 if (ts.p.sortable.options) {
77 $.extend(sortable_opts, ts.p.sortable.options);
78 } else if ($.isFunction(ts.p.sortable)) {
79 ts.p.sortable = { "update" : ts.p.sortable };
80 }
81 if (sortable_opts.start) {
82 var s = sortable_opts.start;
83 sortable_opts.start = function(e,ui) {
84 start();
85 s.call(this,e,ui);
86 }
87 } else {
88 sortable_opts.start = start;
89 }
90 if (ts.p.sortable.exclude) {
91 sortable_opts.items += ":not("+ts.p.sortable.exclude+")";
92 }
93 tblrow.sortable(sortable_opts).data("sortable").floating = true;
94 });
95 },
96 columnChooser : function(opts) {
97 var self = this;
98 if($("#colchooser_"+self[0].p.id).length ) return;
99 var selector = $('<div id="colchooser_'+self[0].p.id+'" style="position:relative;overflow:hidden"><div><select multiple="multiple"></select></div></div>');
100 var select = $('select', selector);
101
102 opts = $.extend({
103 "width" : 420,
104 "height" : 240,
105 "classname" : null,
106 "done" : function(perm) { if (perm) self.jqGrid("remapColumns", perm, true) },
107 /* msel is either the name of a ui widget class that
108 extends a multiselect, or a function that supports
109 creating a multiselect object (with no argument,
110 or when passed an object), and destroying it (when
111 passed the string "destroy"). */
112 "msel" : "multiselect",
113 /* "msel_opts" : {}, */
114
115 /* dlog is either the name of a ui widget class that
116 behaves in a dialog-like way, or a function, that
117 supports creating a dialog (when passed dlog_opts)
118 or destroying a dialog (when passed the string
119 "destroy")
120 */
121 "dlog" : "dialog",
122
123 /* dlog_opts is either an option object to be passed
124 to "dlog", or (more likely) a function that creates
125 the options object.
126 The default produces a suitable options object for
127 ui.dialog */
128 "dlog_opts" : function(opts) {
129 var buttons = {};
130 buttons[opts.bSubmit] = function() {
131 opts.apply_perm();
132 opts.cleanup(false);
133 };
134 buttons[opts.bCancel] = function() {
135 opts.cleanup(true);
136 };
137 return {
138 "buttons": buttons,
139 "close": function() {
140 opts.cleanup(true);
141 },
142 "modal" : false,
143 "resizable": false,
144 "width": opts.width+20
145 };
146 },
147 /* Function to get the permutation array, and pass it to the
148 "done" function */
149 "apply_perm" : function() {
150 $('option',select).each(function(i) {
151 if (this.selected) {
152 self.jqGrid("showCol", colModel[this.value].name);
153 } else {
154 self.jqGrid("hideCol", colModel[this.value].name);
155 }
156 });
157
158 var perm = [];
159 //fixedCols.slice(0);
160 $('option[selected]',select).each(function() { perm.push(parseInt(this.value)) });
161 $.each(perm, function() { delete colMap[colModel[parseInt(this)].name] });
162 $.each(colMap, function() {
163 var ti = parseInt(this);
164 perm = insert(perm,ti,ti);
165 });
166 if (opts.done) {
167 opts.done.call(self, perm);
168 }
169 },
170 /* Function to cleanup the dialog, and select. Also calls the
171 done function with no permutation (to indicate that the
172 columnChooser was aborted */
173 "cleanup" : function(calldone) {
174 call(opts.dlog, selector, 'destroy');
175 call(opts.msel, select, 'destroy');
176 selector.remove();
177 if (calldone && opts.done) {
178 opts.done.call(self);
179 }
180 },
181 "msel_opts" : {}
182 }, $.jgrid.col, opts || {});
183
184 if (opts.caption) {
185 selector.attr("title", opts.caption);
186 }
187 if (opts.classname) {
188 selector.addClass(classname);
189 select.addClass(classname);
190 }
191 if (opts.width) {
192 $(">div",selector).css({"width": opts.width,"margin":"0 auto"});
193 select.css("width", opts.width);
194 }
195 if (opts.height) {
196 $(">div",selector).css("height", opts.height);
197 select.css("height", opts.height - 10);
198 }
199 var colModel = self.jqGrid("getGridParam", "colModel");
200 var colNames = self.jqGrid("getGridParam", "colNames");
201 var colMap = {}, fixedCols = [];
202
203 select.empty();
204 $.each(colModel, function(i) {
205 colMap[this.name] = i;
206 if (this.hidedlg) {
207 if (!this.hidden) {
208 fixedCols.push(i);
209 }
210 return;
211 }
212
213 select.append("<option value='"+i+"' "+
214 (this.hidden?"":"selected='selected'")+">"+colNames[i]+"</option>");
215 });
216 function insert(perm,i,v) {
217 if(i>=0){
218 var a = perm.slice();
219 var b = a.splice(i);
220 if(i>perm.length) i = perm.length;
221 a[i] = v;
222 return a.concat(b);
223 }
224 }
225 function call(fn, obj) {
226 if (!fn) return;
227 if (typeof fn == 'string') {
228 if ($.fn[fn]) {
229 $.fn[fn].apply(obj, $.makeArray(arguments).slice(2));
230 }
231 } else if ($.isFunction(fn)) {
232 fn.apply(obj, $.makeArray(arguments).slice(2));
233 }
234 }
235
236 var dopts = $.isFunction(opts.dlog_opts) ? opts.dlog_opts.call(self, opts) : opts.dlog_opts;
237 call(opts.dlog, selector, dopts);
238 var mopts = $.isFunction(opts.msel_opts) ? opts.msel_opts.call(self, opts) : opts.msel_opts;
239 call(opts.msel, select, mopts);
240 },
241 sortableRows : function (opts) {
242 // Can accept all sortable options and events
243 return this.each(function(){
244 var $t = this;
245 if(!$t.grid) return;
246 // Currently we disable a treeGrid sortable
247 if($t.p.treeGrid) return;
248 if($.fn['sortable']) {
249 opts = $.extend({
250 "cursor":"move",
251 "axis" : "y",
252 "items": ".jqgrow"
253 },
254 opts || {});
255 if(opts.start && $.isFunction(opts.start)) {
256 opts._start_ = opts.start;
257 delete opts.start;
258 } else {opts._start_=false;}
259 if(opts.update && $.isFunction(opts.update)) {
260 opts._update_ = opts.update;
261 delete opts.update;
262 } else {opts._update_ = false;}
263 opts.start = function(ev,ui) {
264 $(ui.item).css("border-width","0px");
265 $("td",ui.item).each(function(i){
266 this.style.width = $t.grid.cols[i].style.width;
267 });
268 if($t.p.subGrid) {
269 var subgid = $(ui.item).attr("id");
270 try {
271 $($t).jqGrid('collapseSubGridRow',subgid);
272 } catch (e) {}
273 }
274 if(opts._start_) {
275 opts._start_.apply(this,[ev,ui]);
276 }
277 }
278 opts.update = function (ev,ui) {
279 $(ui.item).css("border-width","");
280 $t.updateColumns();
281 if($t.p.rownumbers === true) {
282 $("td.jqgrid-rownum",$t.rows).each(function(i){
283 $(this).html(i+1);
284 });
285 }
286 if(opts._update_) {
287 opts._update_.apply(this,[ev,ui]);
288 }
289 }
290 $("tbody:first",$t).sortable(opts);
291 }
292 });
293 },
294 gridDnD : function(opts) {
295 return this.each(function(){
296 var $t = this;
297 if(!$t.grid) return;
298 // Currently we disable a treeGrid drag and drop
299 if($t.p.treeGrid) return;
300 if(!$.fn['draggable'] || !$.fn['droppable']) return;
301 function updateDnD ()
302 {
303 var datadnd = $.data($t,"dnd");
304 $("tr.jqgrow:not(.ui-draggable)",$t).draggable($.isFunction(datadnd.drag) ? datadnd.drag.call($($t),datadnd) : datadnd.drag);
305 }
306 var appender = "<table id='jqgrid_dnd' class='ui-jqgrid-dnd'></table>";
307 if($("#jqgrid_dnd").html() == null) {
308 $('body').append(appender);
309 }
310
311 if(typeof opts == 'string' && opts == 'updateDnD' && $t.p.jqgdnd==true) {
312 updateDnD();
313 return;
314 }
315 opts = $.extend({
316 "drag" : function (opts) {
317 return $.extend({
318 start : function (ev, ui) {
319 // if we are in subgrid mode try to collapse the node
320 if($t.p.subGrid) {
321 var subgid = $(ui.helper).attr("id");
322 try {
323 $($t).jqGrid('collapseSubGridRow',subgid);
324 } catch (e) {}
325 }
326 // hack
327 // drag and drop does not insert tr in table, when the table has no rows
328 // we try to insert new empty row on the target(s)
329 for (var i=0;i<$.data($t,"dnd").connectWith.length;i++){
330 if($($.data($t,"dnd").connectWith[i]).jqGrid('getGridParam','reccount') == "0" ){
331 $($.data($t,"dnd").connectWith[i]).jqGrid('addRowData','jqg_empty_row',{});
332 }
333 }
334 ui.helper.addClass("ui-state-highlight");
335 $("td",ui.helper).each(function(i) {
336 this.style.width = $t.grid.headers[i].width+"px";
337 });
338 if(opts.onstart && $.isFunction(opts.onstart) ) opts.onstart.call($($t),ev,ui);
339 },
340 stop :function(ev,ui) {
341 if(ui.helper.dropped) {
342 var ids = $(ui.helper).attr("id");
343 $($t).jqGrid('delRowData',ids );
344 }
345 // if we have a empty row inserted from start event try to delete it
346 for (var i=0;i<$.data($t,"dnd").connectWith.length;i++){
347 $($.data($t,"dnd").connectWith[i]).jqGrid('delRowData','jqg_empty_row');
348 }
349 if(opts.onstop && $.isFunction(opts.onstop) ) opts.onstop.call($($t),ev,ui);
350 }
351 },opts.drag_opts || {});
352 },
353 "drop" : function (opts) {
354 return $.extend({
355 accept: function(d) {
356 var tid = $(d).closest("table.ui-jqgrid-btable");
357 if($.data(tid[0],"dnd") != undefined) {
358 var cn = $.data(tid[0],"dnd").connectWith;
359 return $.inArray('#'+this.id,cn) != -1 ? true : false;
360 }
361 return d;
362 },
363 drop: function(ev, ui) {
364 var accept = $(ui.draggable).attr("id");
365 var getdata = $('#'+$t.id).jqGrid('getRowData',accept);
366 if(!opts.dropbyname) {
367 var j =0, tmpdata = {}, dropname;
368 var dropmodel = $("#"+this.id).jqGrid('getGridParam','colModel');
369 try {
370 for (key in getdata) {
371 if(dropmodel[j]) {
372 dropname = dropmodel[j].name;
373 tmpdata[dropname] = getdata[key];
374 }
375 j++;
376 }
377 getdata = tmpdata;
378 } catch (e) {}
379 }
380 ui.helper.dropped = true;
381 if(opts.beforedrop && $.isFunction(opts.beforedrop) ) {
382 //parameters to this callback - event, element, data to be inserted, sender, reciever
383 // should return object which will be inserted into the reciever
384 var datatoinsert = opts.beforedrop.call(this,ev,ui,getdata,$('#'+$t.id),$(this));
385 if (typeof datatoinsert != "undefined" && datatoinsert !== null && typeof datatoinsert == "object") getdata = datatoinsert;
386 }
387 if(ui.helper.dropped) {
388 var grid;
389 if(opts.autoid) {
390 if($.isFunction(opts.autoid)) {
391 grid = opts.autoid.call(this,getdata);
392 } else {
393 grid = Math.ceil(Math.random()*1000);
394 grid = opts.autoidprefix+grid;
395 }
396 }
397 // NULL is interpreted as undefined while null as object
398 $("#"+this.id).jqGrid('addRowData',grid,getdata,opts.droppos);
399 }
400 if(opts.ondrop && $.isFunction(opts.ondrop) ) opts.ondrop.call(this,ev,ui, getdata);
401 }}, opts.drop_opts || {});
402 },
403 "onstart" : null,
404 "onstop" : null,
405 "beforedrop": null,
406 "ondrop" : null,
407 "drop_opts" : {
408 "activeClass": "ui-state-active",
409 "hoverClass": "ui-state-hover"
410 },
411 "drag_opts" : {
412 "revert": "invalid",
413 "helper": "clone",
414 "cursor": "move",
415 "appendTo" : "#jqgrid_dnd",
416 "zIndex": 5000
417 },
418 "dropbyname" : false,
419 "droppos" : "first",
420 "autoid" : true,
421 "autoidprefix" : "dnd_"
422 }, opts || {});
423
424 if(!opts.connectWith) return;
425 opts.connectWith = opts.connectWith.split(",");
426 opts.connectWith = $.map(opts.connectWith,function(n){return $.trim(n);});
427 $.data($t,"dnd",opts);
428
429 if($t.p.reccount != "0" && !$t.p.jqgdnd) {
430 updateDnD();
431 }
432 $t.p.jqgdnd = true;
433 for (var i=0;i<opts.connectWith.length;i++){
434 var cn =opts.connectWith[i]
435 $(cn).droppable($.isFunction(opts.drop) ? opts.drop.call($($t),opts) : opts.drop);
436 };
437 });
438 },
439 gridResize : function(opts) {
440 return this.each(function(){
441 var $t = this;
442 if(!$t.grid || !$.fn['resizable']) return;
443 opts = $.extend({}, opts || {});
444 if(opts.alsoResize ) {
445 opts._alsoResize_ = opts.alsoResize;
446 delete opts.alsoResize;
447 } else {
448 opts._alsoResize_ = false;
449 }
450 if(opts.stop && $.isFunction(opts.stop)) {
451 opts._stop_ = opts.stop;
452 delete opts.stop;
453 } else {
454 opts._stop_ = false;
455 }
456 opts.stop = function (ev, ui) {
457 $($t).jqGrid('setGridParam',{height:$("#gview_"+$t.p.id+" .ui-jqgrid-bdiv").height()});
458 $($t).jqGrid('setGridWidth',ui.size.width,opts.shrinkToFit);
459 if(opts._stop_) opts._stop_.call($t,ev,ui);
460 };
461 if(opts._alsoResize_) {
462 var optstest = "{'\#gview_"+$t.p.id+" .ui-jqgrid-bdiv\':true,'" +opts._alsoResize_+"':true}";
463 opts.alsoResize = eval('('+optstest+')'); // the only way that I found to do this
464 } else {
465 opts.alsoResize = $(".ui-jqgrid-bdiv","#gview_"+$t.p.id);
466 }
467 delete opts._alsoResize_;
468 $("#gbox_"+$t.p.id).resizable(opts);
469 });
470 }
471});
472})(jQuery);