Merge "Fix the docker push"
[clamp.git] / src / main / resources / META-INF / resources / designer / lib / flexigrid / js / flexigrid.js
1 /*
2  * Flexigrid for jQuery -  v1.1
3  *
4  * Copyright (c) 2008 Paulo P. Marinas (code.google.com/p/flexigrid/)
5  * Dual licensed under the MIT or GPL Version 2 licenses.
6  * http://jquery.org/license
7  *
8  */
9 (function ($) {
10         /*
11          * jQuery 1.9 support. browser object has been removed in 1.9 
12          */
13         var browser = $.browser
14         
15         if (!browser) {
16                 function uaMatch( ua ) {
17                         ua = ua.toLowerCase();
18
19                         var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
20                                 /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
21                                 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
22                                 /(msie) ([\w.]+)/.exec( ua ) ||
23                                 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
24                                 [];
25
26                         return {
27                                 browser: match[ 1 ] || "",
28                                 version: match[ 2 ] || "0"
29                         };
30                 };
31
32                 var matched = uaMatch( navigator.userAgent );
33                 browser = {};
34
35                 if ( matched.browser ) {
36                         browser[ matched.browser ] = true;
37                         browser.version = matched.version;
38                 }
39
40                 // Chrome is Webkit, but Webkit is also Safari.
41                 if ( browser.chrome ) {
42                         browser.webkit = true;
43                 } else if ( browser.webkit ) {
44                         browser.safari = true;
45                 }
46         }
47         
48     /*!
49      * START code from jQuery UI
50      *
51      * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
52      * Dual licensed under the MIT or GPL Version 2 licenses.
53      * http://jquery.org/license
54      *
55      * http://docs.jquery.com/UI
56      */
57      
58     if(typeof $.support.selectstart != 'function') {
59         $.support.selectstart = "onselectstart" in document.createElement("div");
60     }
61     
62     if(typeof $.fn.disableSelection != 'function') {
63         $.fn.disableSelection = function() {
64             return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
65                 ".ui-disableSelection", function( event ) {
66                 event.preventDefault();
67             });
68         };
69     }
70     
71     /* END code from jQuery UI */
72     
73         $.addFlex = function (t, p) {
74                 if (t.grid) return false; //return if already exist
75                 p = $.extend({ //apply default properties
76                         height: 200, //default height
77                         width: 'auto', //auto width
78                         striped: true, //apply odd even stripes
79                         novstripe: false,
80                         minwidth: 30, //min width of columns
81                         minheight: 80, //min height of columns
82                         resizable: true, //allow table resizing
83                         url: false, //URL if using data from AJAX
84                         method: 'POST', //data sending method
85                         dataType: 'xml', //type of data for AJAX, either xml or json
86                         errormsg: 'Connection Error',
87                         usepager: false,
88                         nowrap: true,
89                         page: 1, //current page
90                         total: 1, //total pages
91                         useRp: true, //use the results per page select box
92                         rp: 15, //results per page
93                         rpOptions: [10, 15, 20, 30, 50], //allowed per-page values
94                         title: false,
95                         idProperty: 'id',
96                         pagestat: 'Displaying {from} to {to} of {total} items',
97                         pagetext: 'Page',
98                         outof: 'of',
99                         findtext: 'Find',
100                         params: [], //allow optional parameters to be passed around
101                         procmsg: 'Processing, please wait ...',
102                         query: '',
103                         qtype: '',
104                         nomsg: 'No items',
105                         minColToggle: 1, //minimum allowed column to be hidden
106                         showToggleBtn: true, //show or hide column toggle popup
107                         hideOnSubmit: true,
108                         autoload: true,
109                         blockOpacity: 0.5,
110                         preProcess: false,
111                         addTitleToCell: false, // add a title attr to cells with truncated contents
112                         dblClickResize: false, //auto resize column by double clicking
113                         onDragCol: false,
114                         onToggleCol: false,
115                         onChangeSort: false,
116                         onDoubleClick: false,
117                         onSuccess: false,
118                         onError: false,
119                         onSubmit: false, //using a custom populate function
120             __mw: { //extendable middleware function holding object
121                 datacol: function(p, col, val) { //middleware for formatting data columns
122                     var _col = (typeof p.datacol[col] == 'function') ? p.datacol[col](val) : val; //format column using function
123                     if(typeof p.datacol['*'] == 'function') { //if wildcard function exists
124                         return p.datacol['*'](_col); //run wildcard function
125                     } else {
126                         return _col; //return column without wildcard
127                     }
128                 }
129             },
130             getGridClass: function(g) { //get the grid class, always returns g
131                 return g;
132             },
133             datacol: {}, //datacol middleware object 'colkey': function(colval) {}
134             colResize: true, //from: http://stackoverflow.com/a/10615589
135             colMove: true
136                 }, p);
137                 $(t).show() //show if hidden
138                         .attr({
139                                 cellPadding: 0,
140                                 cellSpacing: 0,
141                                 border: 0
142                         }) //remove padding and spacing
143                         .removeAttr('width'); //remove width properties
144                 //create grid class
145                 var g = {
146                         hset: {},
147                         rePosDrag: function () {
148                                 var cdleft = 0 - this.hDiv.scrollLeft;
149                                 if (this.hDiv.scrollLeft > 0) cdleft -= Math.floor(p.cgwidth / 2);
150                                 $(g.cDrag).css({
151                                         top: g.hDiv.offsetTop + 1
152                                 });
153                                 var cdpad = this.cdpad;
154                                 var cdcounter=0;
155                                 $('div', g.cDrag).hide();
156                                 $('thead tr:first th:visible', this.hDiv).each(function () {
157                                         var n = $('thead tr:first th:visible', g.hDiv).index(this);
158                                         var cdpos = parseInt($('div', this).width());
159                                         if (cdleft == 0) cdleft -= Math.floor(p.cgwidth / 2);
160                                         cdpos = cdpos + cdleft + cdpad;
161                                         if (isNaN(cdpos)) {
162                                                 cdpos = 0;
163                                         }
164                                         $('div:eq(' + n + ')', g.cDrag).css({
165                                                 'left': (!(browser.mozilla) ? cdpos - cdcounter : cdpos) + 'px'
166                                         }).show();
167                                         cdleft = cdpos;
168                                         cdcounter++;
169                                 });
170                         },
171                         fixHeight: function (newH) {
172                                 newH = false;
173                                 if (!newH) newH = $(g.bDiv).height();
174                                 var hdHeight = $(this.hDiv).height();
175                                 $('div', this.cDrag).each(
176                                         function () {
177                                                 $(this).height(newH + hdHeight);
178                                         }
179                                 );
180                                 var nd = parseInt($(g.nDiv).height(), 10);
181                                 if (nd > newH) $(g.nDiv).height(newH).width(200);
182                                 else $(g.nDiv).height('auto').width('auto');
183                                 $(g.block).css({
184                                         height: newH,
185                                         marginBottom: (newH * -1)
186                                 });
187                                 var hrH = g.bDiv.offsetTop + newH;
188                                 if (p.height != 'auto' && p.resizable) hrH = g.vDiv.offsetTop;
189                                 $(g.rDiv).css({
190                                         height: hrH
191                                 });
192                         },
193                         dragStart: function (dragtype, e, obj) { //default drag function start
194                 if (dragtype == 'colresize' && p.colResize === true) {//column resize
195                                         $(g.nDiv).hide();
196                                         $(g.nBtn).hide();
197                                         var n = $('div', this.cDrag).index(obj);
198                                         var ow = $('th:visible div:eq(' + n + ')', this.hDiv).width();
199                                         $(obj).addClass('dragging').siblings().hide();
200                                         $(obj).prev().addClass('dragging').show();
201                                         this.colresize = {
202                                                 startX: e.pageX,
203                                                 ol: parseInt(obj.style.left, 10),
204                                                 ow: ow,
205                                                 n: n
206                                         };
207                                         $('body').css('cursor', 'col-resize');
208                                 } else if (dragtype == 'vresize') {//table resize
209                                         var hgo = false;
210                                         $('body').css('cursor', 'row-resize');
211                                         if (obj) {
212                                                 hgo = true;
213                                                 $('body').css('cursor', 'col-resize');
214                                         }
215                                         this.vresize = {
216                                                 h: p.height,
217                                                 sy: e.pageY,
218                                                 w: p.width,
219                                                 sx: e.pageX,
220                                                 hgo: hgo
221                                         };
222                                 } else if (dragtype == 'colMove') {//column header drag
223                     $(e.target).disableSelection(); //disable selecting the column header
224                     if((p.colMove === true)) {
225                         $(g.nDiv).hide();
226                         $(g.nBtn).hide();
227                         this.hset = $(this.hDiv).offset();
228                         this.hset.right = this.hset.left + $('table', this.hDiv).width();
229                         this.hset.bottom = this.hset.top + $('table', this.hDiv).height();
230                         this.dcol = obj;
231                         this.dcoln = $('th', this.hDiv).index(obj);
232                         this.colCopy = document.createElement("div");
233                         this.colCopy.className = "colCopy";
234                         this.colCopy.innerHTML = obj.innerHTML;
235                         if (browser.msie) {
236                             this.colCopy.className = "colCopy ie";
237                         }
238                         $(this.colCopy).css({
239                             position: 'absolute',
240                             'float': 'left',
241                             display: 'none',
242                             textAlign: obj.align
243                         });
244                         $('body').append(this.colCopy);
245                         $(this.cDrag).hide();
246                     }
247                                 }
248                                 $('body').noSelect();
249                         },
250                         dragMove: function (e) {
251                                 if (this.colresize) {//column resize
252                                         var n = this.colresize.n;
253                                         var diff = e.pageX - this.colresize.startX;
254                                         var nleft = this.colresize.ol + diff;
255                                         var nw = this.colresize.ow + diff;
256                                         if (nw > p.minwidth) {
257                                                 $('div:eq(' + n + ')', this.cDrag).css('left', nleft);
258                                                 this.colresize.nw = nw;
259                                         }
260                                 } else if (this.vresize) {//table resize
261                                         var v = this.vresize;
262                                         var y = e.pageY;
263                                         var diff = y - v.sy;
264                                         if (!p.defwidth) p.defwidth = p.width;
265                                         if (p.width != 'auto' && !p.nohresize && v.hgo) {
266                                                 var x = e.pageX;
267                                                 var xdiff = x - v.sx;
268                                                 var newW = v.w + xdiff;
269                                                 if (newW > p.defwidth) {
270                                                         this.gDiv.style.width = newW + 'px';
271                                                         p.width = newW;
272                                                 }
273                                         }
274                                         var newH = v.h + diff;
275                                         if ((newH > p.minheight || p.height < p.minheight) && !v.hgo) {
276                                                 this.bDiv.style.height = newH + 'px';
277                                                 p.height = newH;
278                                                 this.fixHeight(newH);
279                                         }
280                                         v = null;
281                                 } else if (this.colCopy) {
282                                         $(this.dcol).addClass('thMove').removeClass('thOver');
283                                         if (e.pageX > this.hset.right || e.pageX < this.hset.left || e.pageY > this.hset.bottom || e.pageY < this.hset.top) {
284                                                 //this.dragEnd();
285                                                 $('body').css('cursor', 'move');
286                                         } else {
287                                                 $('body').css('cursor', 'pointer');
288                                         }
289                                         $(this.colCopy).css({
290                                                 top: e.pageY + 10,
291                                                 left: e.pageX + 20,
292                                                 display: 'block'
293                                         });
294                                 }
295                         },
296                         dragEnd: function () {
297                                 if (this.colresize) {
298                                         var n = this.colresize.n;
299                                         var nw = this.colresize.nw;
300                                         $('th:visible div:eq(' + n + ')', this.hDiv).css('width', nw);
301                                         $('tr', this.bDiv).each(
302                                                 function () {
303                                                         var $tdDiv = $('td:visible div:eq(' + n + ')', this);
304                                                         $tdDiv.css('width', nw);
305                                                         g.addTitleToCell($tdDiv);
306                                                 }
307                                         );
308                                         this.hDiv.scrollLeft = this.bDiv.scrollLeft;
309                                         $('div:eq(' + n + ')', this.cDrag).siblings().show();
310                                         $('.dragging', this.cDrag).removeClass('dragging');
311                                         this.rePosDrag();
312                                         this.fixHeight();
313                                         this.colresize = false;
314                                         if ($.cookies) {
315                                                 var name = p.colModel[n].name;          // Store the widths in the cookies
316                                                 $.cookie('flexiwidths/'+name, nw);
317                                         }
318                                 } else if (this.vresize) {
319                                         this.vresize = false;
320                                 } else if (this.colCopy) {
321                                         $(this.colCopy).remove();
322                                         if (this.dcolt !== null) {
323                                                 if (this.dcoln > this.dcolt) $('th:eq(' + this.dcolt + ')', this.hDiv).before(this.dcol);
324                                                 else $('th:eq(' + this.dcolt + ')', this.hDiv).after(this.dcol);
325                                                 this.switchCol(this.dcoln, this.dcolt);
326                                                 $(this.cdropleft).remove();
327                                                 $(this.cdropright).remove();
328                                                 this.rePosDrag();
329                                                 if (p.onDragCol) {
330                                                         p.onDragCol(this.dcoln, this.dcolt);
331                                                 }
332                                         }
333                                         this.dcol = null;
334                                         this.hset = null;
335                                         this.dcoln = null;
336                                         this.dcolt = null;
337                                         this.colCopy = null;
338                                         $('.thMove', this.hDiv).removeClass('thMove');
339                                         $(this.cDrag).show();
340                                 }
341                                 $('body').css('cursor', 'default');
342                                 $('body').noSelect(false);
343                         },
344                         toggleCol: function (cid, visible) {
345                                 var ncol = $("th[axis='col" + cid + "']", this.hDiv)[0];
346                                 var n = $('thead th', g.hDiv).index(ncol);
347                                 var cb = $('input[value=' + cid + ']', g.nDiv)[0];
348                                 if (visible == null) {
349                                         visible = ncol.hidden;
350                                 }
351                                 if ($('input:checked', g.nDiv).length < p.minColToggle && !visible) {
352                                         return false;
353                                 }
354                                 if (visible) {
355                                         ncol.hidden = false;
356                                         $(ncol).show();
357                                         cb.checked = true;
358                                 } else {
359                                         ncol.hidden = true;
360                                         $(ncol).hide();
361                                         cb.checked = false;
362                                 }
363                                 $('tbody tr', t).each(
364                                         function () {
365                                                 if (visible) {
366                                                         $('td:eq(' + n + ')', this).show();
367                                                 } else {
368                                                         $('td:eq(' + n + ')', this).hide();
369                                                 }
370                                         }
371                                 );
372                                 this.rePosDrag();
373                                 if (p.onToggleCol) {
374                                         p.onToggleCol(cid, visible);
375                                 }
376                                 return visible;
377                         },
378                         switchCol: function (cdrag, cdrop) { //switch columns
379                                 $('tbody tr', t).each(
380                                         function () {
381                                                 if (cdrag > cdrop) $('td:eq(' + cdrop + ')', this).before($('td:eq(' + cdrag + ')', this));
382                                                 else $('td:eq(' + cdrop + ')', this).after($('td:eq(' + cdrag + ')', this));
383                                         }
384                                 );
385                                 //switch order in nDiv
386                                 if (cdrag > cdrop) {
387                                         $('tr:eq(' + cdrop + ')', this.nDiv).before($('tr:eq(' + cdrag + ')', this.nDiv));
388                                 } else {
389                                         $('tr:eq(' + cdrop + ')', this.nDiv).after($('tr:eq(' + cdrag + ')', this.nDiv));
390                                 }
391                                 if (browser.msie && browser.version < 7.0) {
392                                         $('tr:eq(' + cdrop + ') input', this.nDiv)[0].checked = true;
393                                 }
394                                 this.hDiv.scrollLeft = this.bDiv.scrollLeft;
395                         },
396                         scroll: function () {
397                                 this.hDiv.scrollLeft = this.bDiv.scrollLeft;
398                                 this.rePosDrag();
399                         },
400                         addData: function (data) { //parse data
401                                 if (p.dataType == 'json') {
402                                         data = $.extend({rows: [], page: 0, total: 0}, data);
403                                 }
404                                 if (p.preProcess) {
405                                         data = p.preProcess(data);
406                                 }
407                                 $('.pReload', this.pDiv).removeClass('loading');
408                                 this.loading = false;
409                                 if (!data) {
410                                         $('.pPageStat', this.pDiv).html(p.errormsg);
411                     if (p.onSuccess) p.onSuccess(this);
412                                         return false;
413                                 }
414                                 if (p.dataType == 'xml') {
415                                         p.total = +$('rows total', data).text();
416                                 } else {
417                                         p.total = data.total;
418                                 }
419                                 if (p.total === 0) {
420                                         $('tr, a, td, div', t).unbind();
421                                         $(t).empty();
422                                         p.pages = 1;
423                                         p.page = 1;
424                                         this.buildpager();
425                                         $('.pPageStat', this.pDiv).html(p.nomsg);
426                     if (p.onSuccess) p.onSuccess(this);
427                                         return false;
428                                 }
429                                 p.pages = Math.ceil(p.total / p.rp);
430                                 if (p.dataType == 'xml') {
431                                         p.page = +$('rows page', data).text();
432                                 } else {
433                                         p.page = data.page;
434                                 }
435                                 this.buildpager();
436                                 //build new body
437                                 var tbody = document.createElement('tbody');
438                                 if (p.dataType == 'json') {
439                                         $.each(data.rows, function (i, row) {
440                                                 var tr = document.createElement('tr');
441                                                 var jtr = $(tr);
442                                                 if (row.name) tr.name = row.name;
443                                                 if (row.color) {
444                                                         jtr.css('background',row.color);
445                                                 } else {
446                                                         if (i % 2 && p.striped) tr.className = 'erow';
447                                                 }
448                                                 if (row[p.idProperty]) {
449                                                         tr.id = 'row' + row[p.idProperty];
450                                                         jtr.attr('data-id', row[p.idProperty]);
451                                                 }
452                                                 $('thead tr:first th', g.hDiv).each( //add cell
453                                                         function () {
454                                                                 var td = document.createElement('td');
455                                                                 var idx = $(this).attr('axis').substr(3);
456                                                                 td.align = this.align;
457                                                                 // If each row is the object itself (no 'cell' key)
458                                                                 if (typeof row.cell == 'undefined') {
459                                                                         td.innerHTML = row[p.colModel[idx].name];
460                                                                 } else {
461                                                                         // If the json elements aren't named (which is typical), use numeric order
462                                     var iHTML = '';
463                                     if (typeof row.cell[idx] != "undefined") {
464                                         iHTML = (row.cell[idx] !== null) ? row.cell[idx] : ''; //null-check for Opera-browser
465                                     } else {
466                                         iHTML = row.cell[p.colModel[idx].name];
467                                     }
468                                     td.innerHTML = p.__mw.datacol(p, $(this).attr('abbr'), iHTML); //use middleware datacol to format cols
469                                                                 }
470                                                                 // If the content has a <BGCOLOR=nnnnnn> option, decode it.
471                                                                 var offs = td.innerHTML.indexOf( '<BGCOLOR=' );
472                                                                 if( offs >0 ) {
473                                     $(td).css('background', text.substr(offs+7,7) );
474                                                                 }
475
476                                                                 $(td).attr('abbr', $(this).attr('abbr'));
477                                                                 $(tr).append(td);
478                                                                 td = null;
479                                                         }
480                                                 );
481                                                 if ($('thead', this.gDiv).length < 1) {//handle if grid has no headers
482                                                         for (idx = 0; idx < row.cell.length; idx++) {
483                                                                 var td = document.createElement('td');
484                                                                 // If the json elements aren't named (which is typical), use numeric order
485                                                                 if (typeof row.cell[idx] != "undefined") {
486                                                                         td.innerHTML = (row.cell[idx] != null) ? row.cell[idx] : '';//null-check for Opera-browser
487                                                                 } else {
488                                                                         td.innerHTML = row.cell[p.colModel[idx].name];
489                                                                 }
490                                                                 $(tr).append(td);
491                                                                 td = null;
492                                                         }
493                                                 }
494                                                 $(tbody).append(tr);
495                                                 tr = null;
496                                         });
497                                 } else if (p.dataType == 'xml') {
498                                         var i = 1;
499                                         $("rows row", data).each(function () {
500                                                 i++;
501                                                 var tr = document.createElement('tr');
502                                                 if ($(this).attr('name')) tr.name = $(this).attr('name');
503                                                 if ($(this).attr('color')) {
504                                                         $(tr).css('background',$(this).attr('id'));
505                                                 } else {
506                                                         if (i % 2 && p.striped) tr.className = 'erow';
507                                                 }
508                                                 var nid = $(this).attr('id');
509                                                 if (nid) {
510                                                         tr.id = 'row' + nid;
511                                                 }
512                                                 nid = null;
513                                                 var robj = this;
514                                                 $('thead tr:first th', g.hDiv).each(function () {
515                                                         var td = document.createElement('td');
516                                                         var idx = $(this).attr('axis').substr(3);
517                                                         td.align = this.align;
518
519                                                         var text = $("cell:eq(" + idx + ")", robj).text();
520                                                         var offs = text.indexOf( '<BGCOLOR=' );
521                                                         if( offs >0 ) {
522                                                                 $(td).css('background',  text.substr(offs+7,7) );
523                                                         }
524                             td.innerHTML = p.__mw.datacol(p, $(this).attr('abbr'), text); //use middleware datacol to format cols
525                                                         $(td).attr('abbr', $(this).attr('abbr'));
526                                                         $(tr).append(td);
527                                                         td = null;
528                                                 });
529                                                 if ($('thead', this.gDiv).length < 1) {//handle if grid has no headers
530                                                         $('cell', this).each(function () {
531                                                                 var td = document.createElement('td');
532                                                                 td.innerHTML = $(this).text();
533                                                                 $(tr).append(td);
534                                                                 td = null;
535                                                         });
536                                                 }
537                                                 $(tbody).append(tr);
538                                                 tr = null;
539                                                 robj = null;
540                                         });
541                                 }
542                                 $('tr', t).unbind();
543                                 $(t).empty();
544                                 $(t).append(tbody);
545                                 this.addCellProp();
546                                 this.addRowProp();
547                                 this.rePosDrag();
548                                 tbody = null;
549                                 data = null;
550                                 i = null;
551                                 if (p.onSuccess) {
552                                         p.onSuccess(this);
553                                 }
554                                 if (p.hideOnSubmit) {
555                                         $(g.block).remove();
556                                 }
557                                 this.hDiv.scrollLeft = this.bDiv.scrollLeft;
558                                 if (browser.opera) {
559                                         $(t).css('visibility', 'visible');
560                                 }
561                         },
562                         changeSort: function (th) { //change sortorder
563                                 if (this.loading) {
564                                         return true;
565                                 }
566                                 $(g.nDiv).hide();
567                                 $(g.nBtn).hide();
568                                 if (p.sortname == $(th).attr('abbr')) {
569                                         if (p.sortorder == 'asc') {
570                                                 p.sortorder = 'desc';
571                                         } else {
572                                                 p.sortorder = 'asc';
573                                         }
574                                 }
575                                 $(th).addClass('sorted').siblings().removeClass('sorted');
576                                 $('.sdesc', this.hDiv).removeClass('sdesc');
577                                 $('.sasc', this.hDiv).removeClass('sasc');
578                                 $('div', th).addClass('s' + p.sortorder);
579                                 p.sortname = $(th).attr('abbr');
580                                 if (p.onChangeSort) {
581                                         p.onChangeSort(p.sortname, p.sortorder);
582                                 } else {
583                                         this.populate();
584                                 }
585                         },
586                         buildpager: function () { //rebuild pager based on new properties
587                                 $('.pcontrol input', this.pDiv).val(p.page);
588                                 $('.pcontrol span', this.pDiv).html(p.pages);
589                                 var r1 = p.total == 0 ? 0 : (p.page - 1) * p.rp + 1;
590                                 var r2 = r1 + p.rp - 1;
591                                 if (p.total < r2) {
592                                         r2 = p.total;
593                                 }
594                                 var stat = p.pagestat;
595                                 stat = stat.replace(/{from}/, r1);
596                                 stat = stat.replace(/{to}/, r2);
597                                 stat = stat.replace(/{total}/, p.total);
598                                 $('.pPageStat', this.pDiv).html(stat);
599                         },
600                         populate: function () { //get latest data
601                                 if (this.loading) {
602                                         return true;
603                                 }
604                                 if (p.onSubmit) {
605                                         var gh = p.onSubmit();
606                                         if (!gh) {
607                                                 return false;
608                                         }
609                                 }
610                                 this.loading = true;
611                                 if (!p.url) {
612                                         return false;
613                                 }
614                                 $('.pPageStat', this.pDiv).html(p.procmsg);
615                                 $('.pReload', this.pDiv).addClass('loading');
616                                 $(g.block).css({
617                                         top: g.bDiv.offsetTop
618                                 });
619                                 if (p.hideOnSubmit) {
620                                         $(this.gDiv).prepend(g.block);
621                                 }
622                                 if (browser.opera) {
623                                         $(t).css('visibility', 'hidden');
624                                 }
625                                 if (!p.newp) {
626                                         p.newp = 1;
627                                 }
628                                 if (p.page > p.pages) {
629                                         p.page = p.pages;
630                                 }
631                                 var param = [{
632                                         name: 'page',
633                                         value: p.newp
634                                 }, {
635                                         name: 'rp',
636                                         value: p.rp
637                                 }, {
638                                         name: 'sortname',
639                                         value: p.sortname
640                                 }, {
641                                         name: 'sortorder',
642                                         value: p.sortorder
643                                 }, {
644                                         name: 'query',
645                                         value: p.query
646                                 }, {
647                                         name: 'qtype',
648                                         value: p.qtype
649                                 }];
650                                 if (p.params.length) {
651                                         for (var pi = 0; pi < p.params.length; pi++) {
652                                                 param[param.length] = p.params[pi];
653                                         }
654                                 }
655                                 $.ajax({
656                                         type: p.method,
657                                         url: p.url,
658                                         data: param,
659                                         dataType: p.dataType,
660                                         success: function (data) {
661                                                 g.addData(data);
662                                         },
663                                         error: function (XMLHttpRequest, textStatus, errorThrown) {
664                                                 try {
665                                                         if (p.onError) p.onError(XMLHttpRequest, textStatus, errorThrown);
666                                                 } catch (e) {}
667                                         }
668                                 });
669                         },
670                         doSearch: function () {
671                                 p.query = $('input[name=q]', g.sDiv).val();
672                                 p.qtype = $('select[name=qtype]', g.sDiv).val();
673                                 p.newp = 1;
674                                 this.populate();
675                         },
676                         changePage: function (ctype) { //change page
677                                 if (this.loading) {
678                                         return true;
679                                 }
680                                 switch (ctype) {
681                                         case 'first':
682                                                 p.newp = 1;
683                                                 break;
684                                         case 'prev':
685                                                 if (p.page > 1) {
686                                                         p.newp = parseInt(p.page, 10) - 1;
687                                                 }
688                                                 break;
689                                         case 'next':
690                                                 if (p.page < p.pages) {
691                                                         p.newp = parseInt(p.page, 10) + 1;
692                                                 }
693                                                 break;
694                                         case 'last':
695                                                 p.newp = p.pages;
696                                                 break;
697                                         case 'input':
698                                                 var nv = parseInt($('.pcontrol input', this.pDiv).val(), 10);
699                                                 if (isNaN(nv)) {
700                                                         nv = 1;
701                                                 }
702                                                 if (nv < 1) {
703                                                         nv = 1;
704                                                 } else if (nv > p.pages) {
705                                                         nv = p.pages;
706                                                 }
707                                                 $('.pcontrol input', this.pDiv).val(nv);
708                                                 p.newp = nv;
709                                                 break;
710                                 }
711                                 if (p.newp == p.page) {
712                                         return false;
713                                 }
714                                 if (p.onChangePage) {
715                                         p.onChangePage(p.newp);
716                                 } else {
717                                         this.populate();
718                                 }
719                         },
720                         addCellProp: function () {
721                                 $('tbody tr td', g.bDiv).each(function () {
722                                         var tdDiv = document.createElement('div');
723                                         var n = $('td', $(this).parent()).index(this);
724                                         var pth = $('th:eq(' + n + ')', g.hDiv).get(0);
725                                         if (pth != null) {
726                                                 if (p.sortname == $(pth).attr('abbr') && p.sortname) {
727                                                         this.className = 'sorted';
728                                                 }
729                                                 $(tdDiv).css({
730                                                         textAlign: pth.align,
731                                                         width: $('div:first', pth)[0].style.width
732                                                 });
733                                                 if (pth.hidden) {
734                                                         $(this).css('display', 'none');
735                                                 }
736                                         }
737                                         if (p.nowrap == false) {
738                                                 $(tdDiv).css('white-space', 'normal');
739                                         }
740                                         if (this.innerHTML == '') {
741                                                 this.innerHTML = '&nbsp;';
742                                         }
743                                         tdDiv.innerHTML = this.innerHTML;
744                                         var prnt = $(this).parent()[0];
745                                         var pid = false;
746                                         if (prnt.id) {
747                                                 pid = prnt.id.substr(3);
748                                         }
749                                         if (pth != null) {
750                                                 if (pth.process) pth.process(tdDiv, pid);
751                                         }
752                                         $(this).empty().append(tdDiv).removeAttr('width'); //wrap content
753                                         g.addTitleToCell(tdDiv);
754                                 });
755                         },
756                         getCellDim: function (obj) {// get cell prop for editable event
757                                 var ht = parseInt($(obj).height(), 10);
758                                 var pht = parseInt($(obj).parent().height(), 10);
759                                 var wt = parseInt(obj.style.width, 10);
760                                 var pwt = parseInt($(obj).parent().width(), 10);
761                                 var top = obj.offsetParent.offsetTop;
762                                 var left = obj.offsetParent.offsetLeft;
763                                 var pdl = parseInt($(obj).css('paddingLeft'), 10);
764                                 var pdt = parseInt($(obj).css('paddingTop'), 10);
765                                 return {
766                                         ht: ht,
767                                         wt: wt,
768                                         top: top,
769                                         left: left,
770                                         pdl: pdl,
771                                         pdt: pdt,
772                                         pht: pht,
773                                         pwt: pwt
774                                 };
775                         },
776                         addRowProp: function () {
777                                 $('tbody tr', g.bDiv).on('click', function (e) {
778                                         var obj = (e.target || e.srcElement);
779                                         if (obj.href || obj.type) return true;
780                                         if (e.ctrlKey || e.metaKey) {
781                                                 // mousedown already took care of this case
782                                                 return;
783                                         }
784                                         $(this).toggleClass('trSelected');
785                                         if (p.singleSelect && ! g.multisel) {
786                                                 $(this).siblings().removeClass('trSelected');
787                                         }
788                                 }).on('mousedown', function (e) {
789                                         if (e.shiftKey) {
790                                                 $(this).toggleClass('trSelected');
791                                                 g.multisel = true;
792                                                 this.focus();
793                                                 $(g.gDiv).noSelect();
794                                         }
795                                         if (e.ctrlKey || e.metaKey) {
796                                                 $(this).toggleClass('trSelected');
797                                                 g.multisel = true;
798                                                 this.focus();
799                                         }
800                                 }).on('mouseup', function (e) {
801                                         if (g.multisel && ! (e.ctrlKey || e.metaKey)) {
802                                                 g.multisel = false;
803                                                 $(g.gDiv).noSelect(false);
804                                         }
805                                 }).on('dblclick', function () {
806                                         if (p.onDoubleClick) {
807                                                 p.onDoubleClick(this, g, p);
808                                         }
809                                 }).hover(function (e) {
810                                         if (g.multisel && e.shiftKey) {
811                                                 $(this).toggleClass('trSelected');
812                                         }
813                                 }, function () {});
814                                 if (browser.msie && browser.version < 7.0) {
815                                         $(this).hover(function () {
816                                                 $(this).addClass('trOver');
817                                         }, function () {
818                                                 $(this).removeClass('trOver');
819                                         });
820                                 }
821                         },
822
823                         combo_flag: true,
824                         combo_resetIndex: function(selObj)
825                         {
826                                 if(this.combo_flag) {
827                                         selObj.selectedIndex = 0;
828                                 }
829                                 this.combo_flag = true;
830                         },
831                         combo_doSelectAction: function(selObj)
832                         {
833                                 eval( selObj.options[selObj.selectedIndex].value );
834                                 selObj.selectedIndex = 0;
835                                 this.combo_flag = false;
836                         },
837                         //Add title attribute to div if cell contents is truncated
838                         addTitleToCell: function(tdDiv) {
839                                 if(p.addTitleToCell) {
840                                         var $span = $('<span />').css('display', 'none'),
841                                                 $div = (tdDiv instanceof jQuery) ? tdDiv : $(tdDiv),
842                                                 div_w = $div.outerWidth(),
843                                                 span_w = 0;
844
845                                         $('body').children(':first').before($span);
846                                         $span.html($div.html());
847                                         $span.css('font-size', '' + $div.css('font-size'));
848                                         $span.css('padding-left', '' + $div.css('padding-left'));
849                                         span_w = $span.innerWidth();
850                                         $span.remove();
851
852                                         if(span_w > div_w) {
853                                                 $div.attr('title', $div.text());
854                                         } else {
855                                                 $div.removeAttr('title');
856                                         }
857                                 }
858                         },
859                         autoResizeColumn: function (obj) {
860                                 if(!p.dblClickResize) {
861                                         return;
862                                 }
863                                 var n = $('div', this.cDrag).index(obj),
864                                         $th = $('th:visible div:eq(' + n + ')', this.hDiv),
865                                         ol = parseInt(obj.style.left, 10),
866                                         ow = $th.width(),
867                                         nw = 0,
868                                         nl = 0,
869                                         $span = $('<span />');
870                                 $('body').children(':first').before($span);
871                                 $span.html($th.html());
872                                 $span.css('font-size', '' + $th.css('font-size'));
873                                 $span.css('padding-left', '' + $th.css('padding-left'));
874                                 $span.css('padding-right', '' + $th.css('padding-right'));
875                                 nw = $span.width();
876                                 $('tr', this.bDiv).each(function () {
877                                         var $tdDiv = $('td:visible div:eq(' + n + ')', this),
878                                                 spanW = 0;
879                                         $span.html($tdDiv.html());
880                                         $span.css('font-size', '' + $tdDiv.css('font-size'));
881                                         $span.css('padding-left', '' + $tdDiv.css('padding-left'));
882                                         $span.css('padding-right', '' + $tdDiv.css('padding-right'));
883                                         spanW = $span.width();
884                                         nw = (spanW > nw) ? spanW : nw;
885                                 });
886                                 $span.remove();
887                                 nw = (p.minWidth > nw) ? p.minWidth : nw;
888                                 nl = ol + (nw - ow);
889                                 $('div:eq(' + n + ')', this.cDrag).css('left', nl);
890                                 this.colresize = {
891                                         nw: nw,
892                                         n: n
893                                 };
894                                 g.dragEnd();
895                         },
896                         pager: 0
897                 };
898         
899         g = p.getGridClass(g); //get the grid class
900         
901                 if (p.colModel) { //create model if any
902                         thead = document.createElement('thead');
903                         var tr = document.createElement('tr');
904                         for (var i = 0; i < p.colModel.length; i++) {
905                                 var cm = p.colModel[i];
906                                 var th = document.createElement('th');
907                                 $(th).attr('axis', 'col' + i);
908                                 if( cm ) {      // only use cm if its defined
909                                         if ($.cookies) {
910                                                 var cookie_width = 'flexiwidths/'+cm.name;              // Re-Store the widths in the cookies
911                                                 if( $.cookie(cookie_width) != undefined ) {
912                                                         cm.width = $.cookie(cookie_width);
913                                                 }
914                                         }
915                                         if( cm.display != undefined ) {
916                                                 th.innerHTML = cm.display;
917                                         }
918                                         if (cm.name && cm.sortable) {
919                                                 $(th).attr('abbr', cm.name);
920                                         }
921                                         if (cm.align) {
922                                                 th.align = cm.align;
923                                         }
924                                         if (cm.width) {
925                                                 $(th).attr('width', cm.width);
926                                         }
927                                         if ($(cm).attr('hide')) {
928                                                 th.hidden = true;
929                                         }
930                                         if (cm.process) {
931                                                 th.process = cm.process;
932                                         }
933                                 } else {
934                                         th.innerHTML = "";
935                                         $(th).attr('width',30);
936                                 }
937                                 $(tr).append(th);
938                         }
939                         $(thead).append(tr);
940                         $(t).prepend(thead);
941                 } // end if p.colmodel
942                 //init divs
943                 g.gDiv = document.createElement('div'); //create global container
944                 g.mDiv = document.createElement('div'); //create title container
945                 g.hDiv = document.createElement('div'); //create header container
946                 g.bDiv = document.createElement('div'); //create body container
947                 g.vDiv = document.createElement('div'); //create grip
948                 g.rDiv = document.createElement('div'); //create horizontal resizer
949                 g.cDrag = document.createElement('div'); //create column drag
950                 g.block = document.createElement('div'); //creat blocker
951                 g.nDiv = document.createElement('div'); //create column show/hide popup
952                 g.nBtn = document.createElement('div'); //create column show/hide button
953                 g.iDiv = document.createElement('div'); //create editable layer
954                 g.tDiv = document.createElement('div'); //create toolbar
955                 g.sDiv = document.createElement('div');
956                 g.pDiv = document.createElement('div'); //create pager container
957         
958         if(p.colResize === false) { //don't display column drag if we are not using it
959             $(g.cDrag).css('display', 'none');
960         }
961         
962                 if (!p.usepager) {
963                         g.pDiv.style.display = 'none';
964                 }
965                 g.hTable = document.createElement('table');
966                 g.gDiv.className = 'flexigrid';
967                 if (p.width != 'auto') {
968                         g.gDiv.style.width = p.width + (isNaN(p.width) ? '' : 'px');
969                 } 
970                 //add conditional classes
971                 if (browser.msie) {
972                         $(g.gDiv).addClass('ie');
973                 }
974                 if (p.novstripe) {
975                         $(g.gDiv).addClass('novstripe');
976                 }
977                 $(t).before(g.gDiv);
978                 $(g.gDiv).append(t);
979                 //set toolbar
980                 if (p.buttons) {
981                         g.tDiv.className = 'tDiv';
982                         var tDiv2 = document.createElement('div');
983                         tDiv2.className = 'tDiv2';
984                         for (var i = 0; i < p.buttons.length; i++) {
985                                 var btn = p.buttons[i];
986                                 if (!btn.separator) {
987                                         var btnDiv = document.createElement('div');
988                                         btnDiv.className = 'fbutton';
989                                         btnDiv.innerHTML = ("<div><span>") + (btn.hidename ? "&nbsp;" : btn.name) + ("</span></div>");
990                                         if (btn.bclass) $('span', btnDiv).addClass(btn.bclass).css({
991                                                 paddingLeft: 20
992                                         });
993                                         if (btn.bimage) // if bimage defined, use its string as an image url for this buttons style (RS)
994                                                 $('span',btnDiv).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
995                                                 $('span',btnDiv).css( 'paddingLeft', 20 );
996
997                                         if (btn.tooltip) // add title if exists (RS)
998                                                 $('span',btnDiv)[0].title = btn.tooltip;
999
1000                                         btnDiv.onpress = btn.onpress;
1001                                         btnDiv.name = btn.name;
1002                                         if (btn.id) {
1003                                                 btnDiv.id = btn.id;
1004                                         }
1005                                         if (btn.onpress) {
1006                                                 $(btnDiv).click(function () {
1007                                                         this.onpress(this.id || this.name, g.gDiv);
1008                                                 });
1009                                         }
1010                                         $(tDiv2).append(btnDiv);
1011                                         if (browser.msie && browser.version < 7.0) {
1012                                                 $(btnDiv).hover(function () {
1013                                                         $(this).addClass('fbOver');
1014                                                 }, function () {
1015                                                         $(this).removeClass('fbOver');
1016                                                 });
1017                                         }
1018                                 } else {
1019                                         $(tDiv2).append("<div class='btnseparator'></div>");
1020                                 }
1021                         }
1022                         $(g.tDiv).append(tDiv2);
1023                         $(g.tDiv).append("<div style='clear:both'></div>");
1024                         $(g.gDiv).prepend(g.tDiv);
1025                 }
1026                 g.hDiv.className = 'hDiv';
1027
1028                 // Define a combo button set with custom action'ed calls when clicked.
1029                 if( p.combobuttons && $(g.tDiv2) )
1030                 {
1031                         var btnDiv = document.createElement('div');
1032                         btnDiv.className = 'fbutton';
1033
1034                         var tSelect = document.createElement('select');
1035                         $(tSelect).change( function () { g.combo_doSelectAction( tSelect ) } );
1036                         $(tSelect).click( function () { g.combo_resetIndex( tSelect) } );
1037                         tSelect.className = 'cselect';
1038                         $(btnDiv).append(tSelect);
1039
1040                         for (i=0;i<p.combobuttons.length;i++)
1041                         {
1042                                 var btn = p.combobuttons[i];
1043                                 if (!btn.separator)
1044                                 {
1045                                         var btnOpt = document.createElement('option');
1046                                         btnOpt.innerHTML = btn.name;
1047
1048                                         if (btn.bclass)
1049                                                 $(btnOpt)
1050                                                 .addClass(btn.bclass)
1051                                                 .css({paddingLeft:20})
1052                                                 ;
1053                                         if (btn.bimage)  // if bimage defined, use its string as an image url for this buttons style (RS)
1054                                                 $(btnOpt).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
1055                                                 $(btnOpt).css( 'paddingLeft', 20 );
1056
1057                                         if (btn.tooltip) // add title if exists (RS)
1058                                                 $(btnOpt)[0].title = btn.tooltip;
1059
1060                                         if (btn.onpress)
1061                                         {
1062                                                 btnOpt.value = btn.onpress;
1063                                         }
1064                                         $(tSelect).append(btnOpt);
1065                                 }
1066                         }
1067                         $('.tDiv2').append(btnDiv);
1068                 }
1069
1070
1071                 $(t).before(g.hDiv);
1072                 g.hTable.cellPadding = 0;
1073                 g.hTable.cellSpacing = 0;
1074                 $(g.hDiv).append('<div class="hDivBox"></div>');
1075                 $('div', g.hDiv).append(g.hTable);
1076                 var thead = $("thead:first", t).get(0);
1077                 if (thead) $(g.hTable).append(thead);
1078                 thead = null;
1079                 if (!p.colmodel) var ci = 0;
1080                 $('thead tr:first th', g.hDiv).each(function () {
1081                         var thdiv = document.createElement('div');
1082                         if ($(this).attr('abbr')) {
1083                                 $(this).click(function (e) {
1084                                         if (!$(this).hasClass('thOver')) return false;
1085                                         var obj = (e.target || e.srcElement);
1086                                         if (obj.href || obj.type) return true;
1087                                         g.changeSort(this);
1088                                 });
1089                                 if ($(this).attr('abbr') == p.sortname) {
1090                                         this.className = 'sorted';
1091                                         thdiv.className = 's' + p.sortorder;
1092                                 }
1093                         }
1094                         if (this.hidden) {
1095                                 $(this).hide();
1096                         }
1097                         if (!p.colmodel) {
1098                                 $(this).attr('axis', 'col' + ci++);
1099                         }
1100                         
1101                         // if there isn't a default width, then the column headers don't match
1102                         // i'm sure there is a better way, but this at least stops it failing
1103                         if (this.width == '') {
1104                                 this.width = 100;
1105                         }
1106                         
1107                         $(thdiv).css({
1108                                 textAlign: this.align,
1109                                 width: this.width + 'px'
1110                         });
1111                         thdiv.innerHTML = this.innerHTML;
1112                         $(this).empty().append(thdiv).removeAttr('width').mousedown(function (e) {
1113                                 g.dragStart('colMove', e, this);
1114                         }).hover(function () {
1115                                 if (!g.colresize && !$(this).hasClass('thMove') && !g.colCopy) {
1116                                         $(this).addClass('thOver');
1117                                 }
1118                                 if ($(this).attr('abbr') != p.sortname && !g.colCopy && !g.colresize && $(this).attr('abbr')) {
1119                                         $('div', this).addClass('s' + p.sortorder);
1120                                 } else if ($(this).attr('abbr') == p.sortname && !g.colCopy && !g.colresize && $(this).attr('abbr')) {
1121                                         var no = (p.sortorder == 'asc') ? 'desc' : 'asc';
1122                                         $('div', this).removeClass('s' + p.sortorder).addClass('s' + no);
1123                                 }
1124                                 if (g.colCopy) {
1125                                         var n = $('th', g.hDiv).index(this);
1126                                         if (n == g.dcoln) {
1127                                                 return false;
1128                                         }
1129                                         if (n < g.dcoln) {
1130                                                 $(this).append(g.cdropleft);
1131                                         } else {
1132                                                 $(this).append(g.cdropright);
1133                                         }
1134                                         g.dcolt = n;
1135                                 } else if (!g.colresize) {
1136                                         var nv = $('th:visible', g.hDiv).index(this);
1137                                         var onl = parseInt($('div:eq(' + nv + ')', g.cDrag).css('left'), 10);
1138                                         var nw = jQuery(g.nBtn).outerWidth();
1139                                         var nl = onl - nw + Math.floor(p.cgwidth / 2);
1140                                         $(g.nDiv).hide();
1141                                         $(g.nBtn).hide();
1142                                         $(g.nBtn).css({
1143                                                 'left': nl,
1144                                                 top: g.hDiv.offsetTop
1145                                         }).show();
1146                                         var ndw = parseInt($(g.nDiv).width(), 10);
1147                                         $(g.nDiv).css({
1148                                                 top: g.bDiv.offsetTop
1149                                         });
1150                                         if ((nl + ndw) > $(g.gDiv).width()) {
1151                                                 $(g.nDiv).css('left', onl - ndw + 1);
1152                                         } else {
1153                                                 $(g.nDiv).css('left', nl);
1154                                         }
1155                                         if ($(this).hasClass('sorted')) {
1156                                                 $(g.nBtn).addClass('srtd');
1157                                         } else {
1158                                                 $(g.nBtn).removeClass('srtd');
1159                                         }
1160                                 }
1161                         }, function () {
1162                                 $(this).removeClass('thOver');
1163                                 if ($(this).attr('abbr') != p.sortname) {
1164                                         $('div', this).removeClass('s' + p.sortorder);
1165                                 } else if ($(this).attr('abbr') == p.sortname) {
1166                                         var no = (p.sortorder == 'asc') ? 'desc' : 'asc';
1167                                         $('div', this).addClass('s' + p.sortorder).removeClass('s' + no);
1168                                 }
1169                                 if (g.colCopy) {
1170                                         $(g.cdropleft).remove();
1171                                         $(g.cdropright).remove();
1172                                         g.dcolt = null;
1173                                 }
1174                         }); //wrap content
1175                 });
1176                 //set bDiv
1177                 g.bDiv.className = 'bDiv';
1178                 $(t).before(g.bDiv);
1179                 $(g.bDiv).css({
1180                         height: (p.height == 'auto') ? 'auto' : p.height + "px"
1181                 }).scroll(function (e) {
1182                         g.scroll()
1183                 }).append(t);
1184                 if (p.height == 'auto') {
1185                         $('table', g.bDiv).addClass('autoht');
1186                 }
1187                 //add td & row properties
1188                 g.addCellProp();
1189                 g.addRowProp();
1190         //set cDrag only if we are using it
1191         if (p.colResize === true) {
1192             var cdcol = $('thead tr:first th:first', g.hDiv).get(0);
1193             if(cdcol !== null) {
1194                 g.cDrag.className = 'cDrag';
1195                 g.cdpad = 0;
1196                 g.cdpad += (isNaN(parseInt($('div', cdcol).css('borderLeftWidth'), 10)) ? 0 : parseInt($('div', cdcol).css('borderLeftWidth'), 10));
1197                 g.cdpad += (isNaN(parseInt($('div', cdcol).css('borderRightWidth'), 10)) ? 0 : parseInt($('div', cdcol).css('borderRightWidth'), 10));
1198                 g.cdpad += (isNaN(parseInt($('div', cdcol).css('paddingLeft'), 10)) ? 0 : parseInt($('div', cdcol).css('paddingLeft'), 10));
1199                 g.cdpad += (isNaN(parseInt($('div', cdcol).css('paddingRight'), 10)) ? 0 : parseInt($('div', cdcol).css('paddingRight'), 10));
1200                 g.cdpad += (isNaN(parseInt($(cdcol).css('borderLeftWidth'), 10)) ? 0 : parseInt($(cdcol).css('borderLeftWidth'), 10));
1201                 g.cdpad += (isNaN(parseInt($(cdcol).css('borderRightWidth'), 10)) ? 0 : parseInt($(cdcol).css('borderRightWidth'), 10));
1202                 g.cdpad += (isNaN(parseInt($(cdcol).css('paddingLeft'), 10)) ? 0 : parseInt($(cdcol).css('paddingLeft'), 10));
1203                 g.cdpad += (isNaN(parseInt($(cdcol).css('paddingRight'), 10)) ? 0 : parseInt($(cdcol).css('paddingRight'), 10));
1204                 $(g.bDiv).before(g.cDrag);
1205                 var cdheight = $(g.bDiv).height();
1206                 var hdheight = $(g.hDiv).height();
1207                 $(g.cDrag).css({
1208                     top: -hdheight + 'px'
1209                 });
1210                 $('thead tr:first th', g.hDiv).each(function() {
1211                     var cgDiv = document.createElement('div');
1212                     $(g.cDrag).append(cgDiv);
1213                     if (!p.cgwidth) {
1214                         p.cgwidth = $(cgDiv).width();
1215                     }
1216                     $(cgDiv).css({
1217                         height: cdheight + hdheight
1218                     }).mousedown(function(e) {
1219                         g.dragStart('colresize', e, this);
1220                     }).dblclick(function(e) {
1221                         g.autoResizeColumn(this);
1222                     });
1223                     if (browser.msie && browser.version < 7.0) {
1224                         g.fixHeight($(g.gDiv).height());
1225                         $(cgDiv).hover(function() {
1226                             g.fixHeight();
1227                             $(this).addClass('dragging');
1228                         }, function() {
1229                             if(!g.colresize) {
1230                                 $(this).removeClass('dragging');
1231                             }
1232                         });
1233                     }
1234                 });
1235             }
1236         }
1237                 //add strip
1238                 if (p.striped) {
1239                         $('tbody tr:odd', g.bDiv).addClass('erow');
1240                 }
1241                 if (p.resizable && p.height != 'auto') {
1242                         g.vDiv.className = 'vGrip';
1243                         $(g.vDiv).mousedown(function (e) {
1244                                 g.dragStart('vresize', e);
1245                         }).html('<span></span>');
1246                         $(g.bDiv).after(g.vDiv);
1247                 }
1248                 if (p.resizable && p.width != 'auto' && !p.nohresize) {
1249                         g.rDiv.className = 'hGrip';
1250                         $(g.rDiv).mousedown(function (e) {
1251                                 g.dragStart('vresize', e, true);
1252                         }).html('<span></span>').css('height', $(g.gDiv).height());
1253                         if (browser.msie && browser.version < 7.0) {
1254                                 $(g.rDiv).hover(function () {
1255                                         $(this).addClass('hgOver');
1256                                 }, function () {
1257                                         $(this).removeClass('hgOver');
1258                                 });
1259                         }
1260                         $(g.gDiv).append(g.rDiv);
1261                 }
1262                 // add pager
1263                 if (p.usepager) {
1264                         g.pDiv.className = 'pDiv';
1265                         g.pDiv.innerHTML = '<div class="pDiv2"></div>';
1266                         $(g.bDiv).after(g.pDiv);
1267                         var html = ' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">' + p.pagetext + ' <input type="text" size="4" value="1" /> ' + p.outof + ' <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';
1268                         $('div', g.pDiv).html(html);
1269                         $('.pReload', g.pDiv).click(function () {
1270                                 g.populate();
1271                         });
1272                         $('.pFirst', g.pDiv).click(function () {
1273                                 g.changePage('first');
1274                         });
1275                         $('.pPrev', g.pDiv).click(function () {
1276                                 g.changePage('prev');
1277                         });
1278                         $('.pNext', g.pDiv).click(function () {
1279                                 g.changePage('next');
1280                         });
1281                         $('.pLast', g.pDiv).click(function () {
1282                                 g.changePage('last');
1283                         });
1284                         $('.pcontrol input', g.pDiv).keydown(function (e) {
1285                                 if (e.keyCode == 13) { 
1286                     g.changePage('input');
1287                                 }
1288                         });
1289                         if (browser.msie && browser.version < 7) $('.pButton', g.pDiv).hover(function () {
1290                                 $(this).addClass('pBtnOver');
1291                         }, function () {
1292                                 $(this).removeClass('pBtnOver');
1293                         });
1294                         if (p.useRp) {
1295                                 var opt = '',
1296                                         sel = '';
1297                                 for (var nx = 0; nx < p.rpOptions.length; nx++) {
1298                                         if (p.rp == p.rpOptions[nx]) sel = 'selected="selected"';
1299                                         else sel = '';
1300                                         opt += "<option value='" + p.rpOptions[nx] + "' " + sel + " >" + p.rpOptions[nx] + "&nbsp;&nbsp;</option>";
1301                                 }
1302                                 $('.pDiv2', g.pDiv).prepend("<div class='pGroup'><select name='rp'>" + opt + "</select></div> <div class='btnseparator'></div>");
1303                                 $('select', g.pDiv).change(function () {
1304                                         if (p.onRpChange) {
1305                                                 p.onRpChange(+this.value);
1306                                         } else {
1307                                                 p.newp = 1;
1308                                                 p.rp = +this.value;
1309                                                 g.populate();
1310                                         }
1311                                 });
1312                         }
1313                         //add search button
1314                         if (p.searchitems) {
1315                                 $('.pDiv2', g.pDiv).prepend("<div class='pGroup'> <div class='pSearch pButton'><span></span></div> </div>  <div class='btnseparator'></div>");
1316                                 $('.pSearch', g.pDiv).click(function () {
1317                                         $(g.sDiv).slideToggle('fast', function () {
1318                                                 $('.sDiv:visible input:first', g.gDiv).trigger('focus');
1319                                         });
1320                                 });
1321                                 //add search box
1322                                 g.sDiv.className = 'sDiv';
1323                                 var sitems = p.searchitems;
1324                                 var sopt = '', sel = '';
1325                                 for (var s = 0; s < sitems.length; s++) {
1326                                         if (p.qtype === '' && sitems[s].isdefault === true) {
1327                                                 p.qtype = sitems[s].name;
1328                                                 sel = 'selected="selected"';
1329                                         } else {
1330                                                 sel = '';
1331                                         }
1332                                         sopt += "<option value='" + sitems[s].name + "' " + sel + " >" + sitems[s].display + "&nbsp;&nbsp;</option>";
1333                                 }
1334                                 if (p.qtype === '') {
1335                                         p.qtype = sitems[0].name;
1336                                 }
1337                                 $(g.sDiv).append("<div class='sDiv2'>" + p.findtext +
1338                                                 " <input type='text' value='" + p.query +"' size='30' name='q' class='qsbox' /> "+
1339                                                 " <select name='qtype'>" + sopt + "</select></div>");
1340                                 //Split into separate selectors because of bug in jQuery 1.3.2
1341                                 $('input[name=q]', g.sDiv).keydown(function (e) {
1342                                         if (e.keyCode == 13) {
1343                                                 g.doSearch();
1344                                         }
1345                                 });
1346                                 $('select[name=qtype]', g.sDiv).keydown(function (e) {
1347                                         if (e.keyCode == 13) {
1348                                                 g.doSearch();
1349                                         }
1350                                 });
1351                                 $('input[value=Clear]', g.sDiv).click(function () {
1352                                         $('input[name=q]', g.sDiv).val('');
1353                                         p.query = '';
1354                                         g.doSearch();
1355                                 });
1356                                 $(g.bDiv).after(g.sDiv);
1357                         }
1358                 }
1359                 $(g.pDiv, g.sDiv).append("<div style='clear:both'></div>");
1360                 // add title
1361                 if (p.title) {
1362                         g.mDiv.className = 'mDiv';
1363                         g.mDiv.innerHTML = '<div class="ftitle">' + p.title + '</div>';
1364                         $(g.gDiv).prepend(g.mDiv);
1365                         if (p.showTableToggleBtn) {
1366                                 $(g.mDiv).append('<div class="ptogtitle" title="Minimize/Maximize Table"><span></span></div>');
1367                                 $('div.ptogtitle', g.mDiv).click(function () {
1368                                         $(g.gDiv).toggleClass('hideBody');
1369                                         $(this).toggleClass('vsble');
1370                                 });
1371                         }
1372                 }
1373                 //setup cdrops
1374                 g.cdropleft = document.createElement('span');
1375                 g.cdropleft.className = 'cdropleft';
1376                 g.cdropright = document.createElement('span');
1377                 g.cdropright.className = 'cdropright';
1378                 //add block
1379                 g.block.className = 'gBlock';
1380                 var gh = $(g.bDiv).height();
1381                 var gtop = g.bDiv.offsetTop;
1382                 $(g.block).css({
1383                         width: g.bDiv.style.width,
1384                         height: gh,
1385                         background: 'white',
1386                         position: 'relative',
1387                         marginBottom: (gh * -1),
1388                         zIndex: 1,
1389                         top: gtop,
1390                         left: '0px'
1391                 });
1392                 $(g.block).fadeTo(0, p.blockOpacity);
1393                 // add column control
1394                 if ($('th', g.hDiv).length) {
1395                         g.nDiv.className = 'nDiv';
1396                         g.nDiv.innerHTML = "<table cellpadding='0' cellspacing='0'><tbody></tbody></table>";
1397                         $(g.nDiv).css({
1398                                 marginBottom: (gh * -1),
1399                                 display: 'none',
1400                                 top: gtop
1401                         }).noSelect();
1402                         var cn = 0;
1403                         $('th div', g.hDiv).each(function () {
1404                                 var kcol = $("th[axis='col" + cn + "']", g.hDiv)[0];
1405                                 var chk = 'checked="checked"';
1406                                 if (kcol.style.display == 'none') {
1407                                         chk = '';
1408                                 }
1409                                 $('tbody', g.nDiv).append('<tr><td class="ndcol1"><input type="checkbox" ' + chk + ' class="togCol" value="' + cn + '" /></td><td class="ndcol2">' + this.innerHTML + '</td></tr>');
1410                                 cn++;
1411                         });
1412                         if (browser.msie && browser.version < 7.0) $('tr', g.nDiv).hover(function () {
1413                                 $(this).addClass('ndcolover');
1414                         }, function () {
1415                                 $(this).removeClass('ndcolover');
1416                         });
1417                         $('td.ndcol2', g.nDiv).click(function () {
1418                                 if ($('input:checked', g.nDiv).length <= p.minColToggle && $(this).prev().find('input')[0].checked) return false;
1419                                 return g.toggleCol($(this).prev().find('input').val());
1420                         });
1421                         $('input.togCol', g.nDiv).click(function () {
1422                                 if ($('input:checked', g.nDiv).length < p.minColToggle && this.checked === false) return false;
1423                                 $(this).parent().next().trigger('click');
1424                         });
1425                         $(g.gDiv).prepend(g.nDiv);
1426                         $(g.nBtn).addClass('nBtn')
1427                                 .html('<div></div>')
1428                                 .attr('title', 'Hide/Show Columns')
1429                                 .click(function () {
1430                                         $(g.nDiv).toggle();
1431                                         return true;
1432                                 }
1433                         );
1434                         if (p.showToggleBtn) {
1435                                 $(g.gDiv).prepend(g.nBtn);
1436                         }
1437                 }
1438                 // add date edit layer
1439                 $(g.iDiv).addClass('iDiv').css({
1440                         display: 'none'
1441                 });
1442                 $(g.bDiv).append(g.iDiv);
1443                 // add flexigrid events
1444                 $(g.bDiv).hover(function () {
1445                         $(g.nDiv).hide();
1446                         $(g.nBtn).hide();
1447                 }, function () {
1448                         if (g.multisel) {
1449                                 g.multisel = false;
1450                         }
1451                 });
1452                 $(g.gDiv).hover(function () {}, function () {
1453                         $(g.nDiv).hide();
1454                         $(g.nBtn).hide();
1455                 });
1456                 //add document events
1457                 $(document).mousemove(function (e) {
1458                         g.dragMove(e);
1459                 }).mouseup(function (e) {
1460                         g.dragEnd();
1461                 }).hover(function () {}, function () {
1462                         g.dragEnd();
1463                 });
1464                 //browser adjustments
1465                 if (browser.msie && browser.version < 7.0) {
1466                         $('.hDiv,.bDiv,.mDiv,.pDiv,.vGrip,.tDiv, .sDiv', g.gDiv).css({
1467                                 width: '100%'
1468                         });
1469                         $(g.gDiv).addClass('ie6');
1470                         if (p.width != 'auto') {
1471                                 $(g.gDiv).addClass('ie6fullwidthbug');
1472                         }
1473                 }
1474                 g.rePosDrag();
1475                 g.fixHeight();
1476                 //make grid functions accessible
1477                 t.p = p;
1478                 t.grid = g;
1479                 // load data
1480                 if (p.url && p.autoload) {
1481                         g.populate();
1482                 }
1483                 return t;
1484         };
1485         var docloaded = false;
1486         $(document).ready(function () {
1487                 docloaded = true;
1488         });
1489         $.fn.flexigrid = function (p) {
1490                 return this.each(function () {
1491                         if (!docloaded) {
1492                                 $(this).hide();
1493                                 var t = this;
1494                                 $(document).ready(function () {
1495                                         $.addFlex(t, p);
1496                                 });
1497                         } else {
1498                                 $.addFlex(this, p);
1499                         }
1500                 });
1501         }; //end flexigrid
1502         $.fn.flexReload = function (p) { // function to reload grid
1503                 return this.each(function () {
1504                         if (this.grid && this.p.url) this.grid.populate();
1505                 });
1506         }; //end flexReload
1507         $.fn.flexOptions = function (p) { //function to update general options
1508                 return this.each(function () {
1509                         if (this.grid) $.extend(this.p, p);
1510                 });
1511         }; //end flexOptions
1512         $.fn.flexToggleCol = function (cid, visible) { // function to reload grid
1513                 return this.each(function () {
1514                         if (this.grid) this.grid.toggleCol(cid, visible);
1515                 });
1516         }; //end flexToggleCol
1517         $.fn.flexAddData = function (data) { // function to add data to grid
1518                 return this.each(function () {
1519                         if (this.grid) this.grid.addData(data);
1520                 });
1521         };
1522         $.fn.noSelect = function (p) { //no select plugin by me :-)
1523                 var prevent = (p === null) ? true : p;
1524                 if (prevent) {
1525                         return this.each(function () {
1526                                 if (browser.msie || browser.safari) $(this).bind('selectstart', function () {
1527                                         return false;
1528                                 });
1529                                 else if (browser.mozilla) {
1530                                         $(this).css('MozUserSelect', 'none');
1531                                         $('body').trigger('focus');
1532                                 } else if (browser.opera) $(this).bind('mousedown', function () {
1533                                         return false;
1534                                 });
1535                                 else $(this).attr('unselectable', 'on');
1536                         });
1537                 } else {
1538                         return this.each(function () {
1539                                 if (browser.msie || browser.safari) $(this).unbind('selectstart');
1540                                 else if (browser.mozilla) $(this).css('MozUserSelect', 'inherit');
1541                                 else if (browser.opera) $(this).unbind('mousedown');
1542                                 else $(this).removeAttr('unselectable', 'on');
1543                         });
1544                 }
1545         }; //end noSelect
1546         $.fn.flexSearch = function(p) { // function to search grid
1547                 return this.each( function() { if (this.grid&&this.p.searchitems) this.grid.doSearch(); });
1548         }; //end flexSearch
1549         $.fn.selectedRows = function (p) { // Returns the selected rows as an array, taken and adapted from http://stackoverflow.com/questions/11868404/flexigrid-get-selected-row-columns-values
1550                 var arReturn = [];
1551                 var arRow = [];
1552                 var selector = $(this.selector + ' .trSelected');
1553
1554
1555                 $(selector).each(function (i, row) {
1556                         arRow = [];
1557                         var idr = $(row).data('id');
1558                         $.each(row.cells, function (c, cell) {
1559                                 var col = cell.abbr;
1560                                 var val = cell.firstChild.innerHTML;
1561                                 if (val == '&nbsp;') val = '';      // Trim the content
1562                                 var idx = cell.cellIndex;                
1563
1564                                 arRow.push({
1565                                         Column: col,        // Column identifier
1566                                         Value: val,         // Column value
1567                                         CellIndex: idx,     // Cell index
1568                                         RowIdentifier: idr  // Identifier of this row element
1569                                 });
1570                         });
1571                         arReturn.push(arRow);
1572                 });
1573                 return arReturn;
1574         };
1575 })(jQuery);