/fa/jquery/jquery-ui/jqgrid/src/grid.jqueryui.js

https://bitbucket.org/gawel/fajquery · JavaScript · 472 lines · 415 code · 14 blank · 43 comment · 113 complexity · c85bcd93fc653cc11b68ff43e78eaf88 MD5 · raw file

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