watable-rails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/assets/images/glyphicons-halflings-white.png +0 -0
- data/app/assets/images/glyphicons-halflings.png +0 -0
- data/app/assets/javascripts/jquery.watable.js +1213 -0
- data/app/assets/javascripts/watable-rails/application.js +15 -0
- data/app/assets/javascripts/watable-rails/bootstrap.min.js +6 -0
- data/app/assets/stylesheets/watable-rails/application.css +13 -0
- data/app/assets/stylesheets/watable-rails/bootstrap.min.css +9 -0
- data/app/assets/stylesheets/watable-rails/bootstrap.scss +5916 -0
- data/app/assets/stylesheets/watable.css +129 -0
- data/config/routes.rb +2 -0
- data/lib/tasks/watable-rails_tasks.rake +4 -0
- data/lib/watable-rails.rb +4 -0
- data/lib/watable-rails/engine.rb +5 -0
- data/lib/watable-rails/version.rb +3 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/watable-rails_test.rb +7 -0
- metadata +100 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'WatableRails'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
Binary file
|
Binary file
|
@@ -0,0 +1,1213 @@
|
|
1
|
+
/*
|
2
|
+
WATable 1.07
|
3
|
+
Copyright (c) 2012 Andreas Petersson(apesv03@gmail.com)
|
4
|
+
http://wootapa-watable.appspot.com/
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
*/
|
25
|
+
(function ($, undefined) {
|
26
|
+
|
27
|
+
var WATable = function () {
|
28
|
+
|
29
|
+
var priv = {}; //private api
|
30
|
+
var publ = {}; //public api
|
31
|
+
|
32
|
+
priv.options = {};
|
33
|
+
var defaults = {
|
34
|
+
url: '', //webservice url
|
35
|
+
urlData: '', //webservice params
|
36
|
+
urlPost: false, //use POST instead of GET
|
37
|
+
debug: false, //prints debug info to console
|
38
|
+
filter: false, //show filter row
|
39
|
+
columnPicker: false, //show columnpicker
|
40
|
+
checkboxes: false, //show body checkboxes
|
41
|
+
actions: '', //holds action links
|
42
|
+
pageSize: 10, //current pagesize
|
43
|
+
pageSizes: [10, 20, 30, 40, 50, 'All'], //available pagesizes
|
44
|
+
hidePagerOnEmpty: false, //removes pager if no rows
|
45
|
+
preFill: false, //prefill table with empty rows
|
46
|
+
pagingTemplate: '<p>Rows {0}-{1} of {2}</p>',
|
47
|
+
types: { //type specific options
|
48
|
+
string: {},
|
49
|
+
number: {},
|
50
|
+
bool: {},
|
51
|
+
date: {}
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
/* bundled scripts */
|
56
|
+
priv.ext = {};
|
57
|
+
priv.ext.XDate = /* xdate 0.7 */ function(a,b,c,d){function e(){var b=this instanceof e?this:new e,c=arguments,d=c.length,h;typeof c[d-1]=="boolean"&&(h=c[--d],c=y(c,0,d));if(d)if(d==1)if(d=c[0],d instanceof a||typeof d=="number")b[0]=new a(+d);else if(d instanceof e){var c=b,i=new a(+d[0]);if(f(d))i.toString=G;c[0]=i}else{if(typeof d=="string"){b[0]=new a(0);a:{for(var c=d,d=h||!1,i=e.parsers,j=0,k;j<i.length;j++)if(k=i[j](c,d,b)){b=k;break a}b[0]=new a(c)}}}else b[0]=new a(F.apply(a,c)),h||(b[0]=u(b[0]));else b[0]=new a;typeof h=="boolean"&&g(b,h);return b}function f(a){return a[0].toString===G}function g(b,c,d){if(c){if(!f(b))d&&(b[0]=new a(F(b[0].getFullYear(),b[0].getMonth(),b[0].getDate(),b[0].getHours(),b[0].getMinutes(),b[0].getSeconds(),b[0].getMilliseconds()))),b[0].toString=G}else f(b)&&(b[0]=d?u(b[0]):new a(+b[0]));return b}function h(a,b,c,d,e){var f=x(s,a[0],e),a=x(t,a[0],e),e=b==1?c%12:f(1),g=!1;d.length==2&&typeof d[1]=="boolean"&&(g=d[1],d=[c]);a(b,d);g&&f(1)!=e&&(a(1,[f(1)-1]),a(2,[v(f(0),f(1))]))}function i(a,c,d,e){var d=Number(d),f=b.floor(d);a["set"+B[c]](a["get"+B[c]]()+f,e||!1);f!=d&&c<6&&i(a,c+1,(d-f)*D[c],e)}function j(a,c,d){var a=a.clone().setUTCMode(!0,!0),c=e(c).setUTCMode(!0,!0),f=0;if(d==0||d==1){for(var g=6;g>=d;g--)f/=D[g],f+=s(c,!1,g)-s(a,!1,g);d==1&&(f+=(c.getFullYear()-a.getFullYear())*12)}else d==2?(d=a.toDate().setUTCHours(0,0,0,0),f=c.toDate().setUTCHours(0,0,0,0),f=b.round((f-d)/864e5)+(c-f-(a-d))/864e5):f=(c-a)/[36e5,6e4,1e3,1][d-3];return f}function k(c){var d=c(0),e=c(1),c=c(2),e=new a(F(d,e,c)),f=l(d),c=f;e<f?c=l(d-1):(d=l(d+1),e>=d&&(c=d));return b.floor(b.round((e-c)/864e5)/7)+1}function l(b){b=new a(F(b,0,4));b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+6)%7);return b}function m(a,b,c,e){var f=x(s,a,e),g=x(t,a,e),c=l(c===d?f(0):c);e||(c=u(c));a.setTime(+c);g(2,[f(2)+(b-1)*7])}function n(a,b,c,d,f){var g=e.locales,h=g[e.defaultLocale]||{},i=x(s,a,f),c=(typeof c=="string"?g[c]:c)||{};return o(a,b,function(a){if(d)for(var b=(a==7?2:a)-1;b>=0;b--)d.push(i(b));return i(a)},function(a){return c[a]||h[a]},f)}function o(a,b,c,e,f){for(var g,h,i="";g=b.match(E);){i+=b.substr(0,g.index);if(g[1]){h=i;for(var i=a,j=g[1],k=c,l=e,m=f,n=j.length,q=void 0,r="";n>0;)q=p(i,j.substr(0,n),k,l,m),q!==d?(r+=q,j=j.substr(n),n=j.length):n--;i=h+(r+j)}else g[3]?(h=o(a,g[4],c,e,f),parseInt(h.replace(/\D/g,""),10)&&(i+=h)):i+=g[7]||"'";b=b.substr(g.index+g[0].length)}return i+b}function p(a,c,d,f,g){var h=e.formatters[c];if(typeof h=="string")return o(a,h,d,f,g);else if(typeof h=="function")return h(a,g||!1,f);switch(c){case"fff":return A(d(6),3);case"s":return d(5);case"ss":return A(d(5));case"m":return d(4);case"mm":return A(d(4));case"h":return d(3)%12||12;case"hh":return A(d(3)%12||12);case"H":return d(3);case"HH":return A(d(3));case"d":return d(2);case"dd":return A(d(2));case"ddd":return f("dayNamesShort")[d(7)]||"";case"dddd":return f("dayNames")[d(7)]||"";case"M":return d(1)+1;case"MM":return A(d(1)+1);case"MMM":return f("monthNamesShort")[d(1)]||"";case"MMMM":return f("monthNames")[d(1)]||"";case"yy":return(d(0)+"").substring(2);case"yyyy":return d(0);case"t":return q(d,f).substr(0,1).toLowerCase();case"tt":return q(d,f).toLowerCase();case"T":return q(d,f).substr(0,1);case"TT":return q(d,f);case"z":case"zz":case"zzz":return g?c="Z":(f=a.getTimezoneOffset(),a=f<0?"+":"-",d=b.floor(b.abs(f)/60),f=b.abs(f)%60,g=d,c=="zz"?g=A(d):c=="zzz"&&(g=A(d)+":"+A(f)),c=a+g),c;case"w":return k(d);case"ww":return A(k(d));case"S":return c=d(2),c>10&&c<20?"th":["st","nd","rd"][c%10-1]||"th"}}function q(a,b){return a(3)<12?b("amDesignator"):b("pmDesignator")}function r(a){return!isNaN(+a[0])}function s(a,b,c){return a["get"+(b?"UTC":"")+B[c]]()}function t(a,b,c,d){a["set"+(b?"UTC":"")+B[c]].apply(a,d)}function u(b){return new a(b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate(),b.getUTCHours(),b.getUTCMinutes(),b.getUTCSeconds(),b.getUTCMilliseconds())}function v(b,c){return 32-(new a(F(b,c,32))).getUTCDate()}function w(a){return function(){return a.apply(d,[this].concat(y(arguments)))}}function x(a){var b=y(arguments,1);return function(){return a.apply(d,b.concat(y(arguments)))}}function y(a,b,e){return c.prototype.slice.call(a,b||0,e===d?a.length:e)}function z(a,b){for(var c=0;c<a.length;c++)b(a[c],c)}function A(a,b){b=b||2;for(a+="";a.length<b;)a="0"+a;return a}var B="FullYear,Month,Date,Hours,Minutes,Seconds,Milliseconds,Day,Year".split(","),C=["Years","Months","Days"],D=[12,31,24,60,60,1e3,1],E=/(([a-zA-Z])\2*)|(\((('.*?'|\(.*?\)|.)*?)\))|('(.*?)')/,F=a.UTC,G=a.prototype.toUTCString,H=e.prototype;H.length=1;H.splice=c.prototype.splice;H.getUTCMode=w(f);H.setUTCMode=w(g);H.getTimezoneOffset=function(){return f(this)?0:this[0].getTimezoneOffset()};z(B,function(a,b){H["get"+a]=function(){return s(this[0],f(this),b)};b!=8&&(H["getUTC"+a]=function(){return s(this[0],!0,b)});b!=7&&(H["set"+a]=function(a){h(this,b,a,arguments,f(this));return this},b!=8&&(H["setUTC"+a]=function(a){h(this,b,a,arguments,!0);return this},H["add"+(C[b]||a)]=function(a,c){i(this,b,a,c);return this},H["diff"+(C[b]||a)]=function(a){return j(this,a,b)}))});H.getWeek=function(){return k(x(s,this,!1))};H.getUTCWeek=function(){return k(x(s,this,!0))};H.setWeek=function(a,b){m(this,a,b,!1);return this};H.setUTCWeek=function(a,b){m(this,a,b,!0);return this};H.addWeeks=function(a){return this.addDays(Number(a)*7)};H.diffWeeks=function(a){return j(this,a,2)/7};e.parsers=[function(b,c,d){if(b=b.match(/^(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/)){var e=new a(F(b[1],b[3]?b[3]-1:0,b[5]||1,b[7]||0,b[8]||0,b[10]||0,b[12]?Number("0."+b[12])*1e3:0));b[13]?b[14]&&e.setUTCMinutes(e.getUTCMinutes()+(b[15]=="-"?1:-1)*(Number(b[16])*60+(b[18]?Number(b[18]):0))):c||(e=u(e));return d.setTime(+e)}}];e.parse=function(a){return+e(""+a)};H.toString=function(a,b,c){return a===d||!r(this)?this[0].toString():n(this,a,b,c,f(this))};H.toUTCString=H.toGMTString=function(a,b,c){return a===d||!r(this)?this[0].toUTCString():n(this,a,b,c,!0)};H.toISOString=function(){return this.toUTCString("yyyy-MM-dd'T'HH:mm:ss(.fff)zzz")};e.defaultLocale="";e.locales={"":{monthNames:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),monthNamesShort:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),dayNames:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),dayNamesShort:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),amDesignator:"AM",pmDesignator:"PM"}};e.formatters={i:"yyyy-MM-dd'T'HH:mm:ss(.fff)",u:"yyyy-MM-dd'T'HH:mm:ss(.fff)zzz"};z("getTime,valueOf,toDateString,toTimeString,toLocaleString,toLocaleDateString,toLocaleTimeString,toJSON".split(","),function(a){H[a]=function(){return this[0][a]()}});H.setTime=function(a){this[0].setTime(a);return this};H.valid=w(r);H.clone=function(){return new e(this)};H.clearTime=function(){return this.setHours(0,0,0,0)};H.toDate=function(){return new a(+this[0])};e.now=function(){return+(new a)};e.today=function(){return(new e).clearTime()};e.UTC=F;e.getDaysInMonth=v;if(typeof module!=="undefined"&&module.exports)module.exports=e;return e}(Date,Math,Array);
|
58
|
+
|
59
|
+
//these holds the actual dom table objects, and is used to identify what parts of the table that needs to be created.
|
60
|
+
var _cont; //container holding table
|
61
|
+
var _table; //the table
|
62
|
+
var _head; //table header
|
63
|
+
var _headSort; //table header sorting row
|
64
|
+
var _headFilter; //table header filter row
|
65
|
+
var _body; //table body
|
66
|
+
var _foot; //table footer
|
67
|
+
|
68
|
+
var _data; //columns and rows
|
69
|
+
var _currPage = 1; //current page
|
70
|
+
var _pageSize; //current pagesize
|
71
|
+
var _totalPages; //total pages
|
72
|
+
var _currSortCol; //current sorting column
|
73
|
+
var _currSortFlip = false; //current sorting direction
|
74
|
+
var _currDpOp; //clicked datepicker operator
|
75
|
+
var _filterCols = {}; //array with current filters
|
76
|
+
var _filterTimeout; //timer for delayed filtering
|
77
|
+
var _uniqueCol; //reference to column with the unique property
|
78
|
+
var _uniqueCols = {}; //array with checked rows
|
79
|
+
var _checkToggleChecked = false; //check-all toggle state
|
80
|
+
|
81
|
+
/*
|
82
|
+
initialize the plugin.
|
83
|
+
*/
|
84
|
+
priv.init = function () {
|
85
|
+
_cont = priv.options.id;
|
86
|
+
priv.options.types.string = ((priv.options.types || {}).string || {});
|
87
|
+
priv.options.types.number = ((priv.options.types || {}).number || {});
|
88
|
+
priv.options.types.bool = ((priv.options.types || {}).bool || {});
|
89
|
+
priv.options.types.date = ((priv.options.types || {}).date || {});
|
90
|
+
|
91
|
+
//fill the table with empty cells
|
92
|
+
if (priv.options.preFill) {
|
93
|
+
var data = {
|
94
|
+
cols: {
|
95
|
+
dummy: {
|
96
|
+
index: 1,
|
97
|
+
friendly: " ",
|
98
|
+
type: "string"
|
99
|
+
}
|
100
|
+
},
|
101
|
+
rows: []
|
102
|
+
};
|
103
|
+
for (var i = 0; i < priv.options.pageSize; i++)
|
104
|
+
data.rows.push({dummy: " "});
|
105
|
+
priv.setData(data);
|
106
|
+
}
|
107
|
+
//try call webservice for data
|
108
|
+
priv.update();
|
109
|
+
};
|
110
|
+
|
111
|
+
/*
|
112
|
+
creates the table with all its parts and handlers.
|
113
|
+
note that only the parts we need is created.
|
114
|
+
(yeah, the function is huge)
|
115
|
+
*/
|
116
|
+
priv.createTable = function () {
|
117
|
+
var start = new priv.ext.XDate();
|
118
|
+
|
119
|
+
//create table itself
|
120
|
+
if (!_table) {
|
121
|
+
_head = _body = _foot = undefined;
|
122
|
+
_table = $('<table class="watable table table-striped table-hover table-bordered table-condensed"></table>').appendTo(_cont);
|
123
|
+
}
|
124
|
+
|
125
|
+
//create the header which will later hold both sorting and filtering
|
126
|
+
if (!_head) {
|
127
|
+
_table.find('thead').remove();
|
128
|
+
_headSort = _headFilter = undefined;
|
129
|
+
_head = $('<thead></thead>').prependTo(_table);
|
130
|
+
}
|
131
|
+
|
132
|
+
//sort the columns in index order
|
133
|
+
var colsSorted = Object.keys(_data.cols).sort(function (a, b) {
|
134
|
+
return _data.cols[a].index - _data.cols[b].index;
|
135
|
+
});
|
136
|
+
|
137
|
+
//create the header sorting row
|
138
|
+
if (!_headSort) {
|
139
|
+
_head.find('.sort i').tooltip('hide');
|
140
|
+
_head.find(".sort").remove();
|
141
|
+
_headSort = $('<tr class="sort"></tr>').prependTo(_head);
|
142
|
+
|
143
|
+
//create the checkall toggle
|
144
|
+
if (_uniqueCol && priv.options.checkboxes) {
|
145
|
+
var checked = _checkToggleChecked ? 'checked' : '';
|
146
|
+
var headCell = $('<th></th>').appendTo(_headSort);
|
147
|
+
var elem = $('<input {0} class="checkToggle" type="checkbox" />'.f(checked)).appendTo(headCell);
|
148
|
+
elem.on('change', priv.checkToggleChanged);
|
149
|
+
}
|
150
|
+
|
151
|
+
//create the sortable headers
|
152
|
+
for (var i = 0; i < colsSorted.length; i++) {
|
153
|
+
var column = colsSorted[i];
|
154
|
+
var props = _data.cols[column];
|
155
|
+
|
156
|
+
if (!props.hidden) {
|
157
|
+
var headCell = $('<th></th>').appendTo(_headSort);
|
158
|
+
var link = $('<a class="pull-left" href="#">{0}</a>'.f(props.friendly || column));
|
159
|
+
link.on('click', {column: column}, priv.columnClicked).appendTo(headCell);
|
160
|
+
|
161
|
+
if (props.tooltip) {
|
162
|
+
$('<i class="icon-info-sign"></i>').tooltip({
|
163
|
+
title: props.tooltip.trim(),
|
164
|
+
html: true,
|
165
|
+
container: 'body',
|
166
|
+
placement: "top",
|
167
|
+
delay: {
|
168
|
+
show: 500,
|
169
|
+
hide: 100
|
170
|
+
}
|
171
|
+
}).appendTo(link);
|
172
|
+
}
|
173
|
+
|
174
|
+
//Add sort arrow
|
175
|
+
if (column == _currSortCol) {
|
176
|
+
if (_currSortFlip) $('<i class="icon-chevron-down pull-right"></i>').appendTo(headCell);
|
177
|
+
else $('<i class="icon-chevron-up pull-right"></i>').appendTo(headCell);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
//create the header filtering row
|
184
|
+
if (!_headFilter && priv.options.filter) {
|
185
|
+
_head.find(".filter").remove();
|
186
|
+
_headFilter = $('<tr class="filter"></tr>').appendTo(_head);
|
187
|
+
var headCell;
|
188
|
+
var elem;
|
189
|
+
var placeHolder = '';
|
190
|
+
var tooltip = '';
|
191
|
+
|
192
|
+
//create the filter checkbox
|
193
|
+
if (_uniqueCol && priv.options.checkboxes) {
|
194
|
+
tooltip = priv.options.types.bool.filterTooltip || 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked';
|
195
|
+
headCell = $('<th></th>').appendTo(_headFilter);
|
196
|
+
elem = $('<input class="filter indeterminate" checked type="checkbox" />').appendTo(headCell);
|
197
|
+
$.map(_filterCols, function (colProps, col) {
|
198
|
+
if (col == "unique") {
|
199
|
+
if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
|
200
|
+
else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
|
201
|
+
else if (colProps.filter == '') elem.addClass('indeterminate');
|
202
|
+
}
|
203
|
+
});
|
204
|
+
|
205
|
+
if (tooltip) {
|
206
|
+
elem.tooltip({
|
207
|
+
title: tooltip.trim(),
|
208
|
+
html: true,
|
209
|
+
container: 'body',
|
210
|
+
trigger: 'hover',
|
211
|
+
placement: 'top',
|
212
|
+
delay: {
|
213
|
+
show: 500,
|
214
|
+
hide: 100
|
215
|
+
}
|
216
|
+
});
|
217
|
+
}
|
218
|
+
elem.on('click', {column: "unique"}, priv.filterChanged);
|
219
|
+
}
|
220
|
+
|
221
|
+
//create the column filters
|
222
|
+
for (var i = 0; i < colsSorted.length; i++) {
|
223
|
+
var column = colsSorted[i];
|
224
|
+
var props = _data.cols[column];
|
225
|
+
tooltip = props.filterTooltip === true ? undefined : props.filterTooltip === false ? '' : props.filterTooltip;
|
226
|
+
placeHolder = props.placeHolder === true ? undefined : props.placeHolder === false ? '' : props.placeHolder;
|
227
|
+
|
228
|
+
if (!props.hidden) {
|
229
|
+
headCell = $('<th></th>').appendTo(_headFilter);
|
230
|
+
|
231
|
+
switch (props.type || 'string') {
|
232
|
+
case "number":
|
233
|
+
if (placeHolder == undefined) placeHolder = priv.options.types.number.placeHolder;
|
234
|
+
placeHolder = (placeHolder === true || placeHolder == undefined) ? '10..20 =50' : placeHolder === false ? '' : placeHolder;
|
235
|
+
if (tooltip == undefined) tooltip = priv.options.types.number.filterTooltip;
|
236
|
+
tooltip = (tooltip === true || tooltip == undefined) ? 'Values 10 to 20:<br/>10..20<br/>Values exactly 50:<br/>=50' : tooltip === false ? '' : tooltip;
|
237
|
+
elem = $('<input placeholder="{0}" class="filter" type="text" />'.f(placeHolder));
|
238
|
+
elem.on('keyup', {column: column}, priv.filterChanged);
|
239
|
+
break;
|
240
|
+
case "date":
|
241
|
+
if (placeHolder == undefined) placeHolder = priv.options.types.date.placeHolder;
|
242
|
+
placeHolder = (placeHolder === true || placeHolder == undefined) ? '-7..0' : placeHolder === false ? '' : placeHolder;
|
243
|
+
if (tooltip == undefined) tooltip = priv.options.types.date.filterTooltip;
|
244
|
+
tooltip = (tooltip === true || tooltip == undefined) ? 'Today:<br/>0..1<br/>A week today excluded:<br/>-7..0' : tooltip === false ? '' : tooltip;
|
245
|
+
elem = $('<div><input placeholder="{0}" class="filter" type="text" /></div>'.f(placeHolder));
|
246
|
+
|
247
|
+
if (priv.options.types.date.datePicker === true || priv.options.types.date.datePicker == undefined)
|
248
|
+
{
|
249
|
+
if ($().datepicker)
|
250
|
+
{
|
251
|
+
elem.addClass('date-wrap');
|
252
|
+
var today = new priv.ext.XDate(false).setHours(0, 0, 0, 0).toString('yyyy-MM-dd');
|
253
|
+
var dp = $('<div style="float:right" class="date" data-date="{0}" data-date-format="{1}" />'.f(today, 'yyyy-mm-dd')).appendTo(elem);
|
254
|
+
$('<input style="display:none" type="text" />').appendTo(dp);
|
255
|
+
$('<span class="add-on"><i class="icon-chevron-right"></i></span>').on('click', {op: "l"}, priv.dpOpChanged).appendTo(dp);
|
256
|
+
$('<span class="add-on"><i class="icon-chevron-left"></i></span>').on('click', {op: "r"}, priv.dpOpChanged).appendTo(dp);
|
257
|
+
dp.datepicker({weekStart:1});
|
258
|
+
dp.on('changeDate', {column: column, input: $('input.filter', elem)}, priv.dpClicked);
|
259
|
+
}
|
260
|
+
else
|
261
|
+
if (priv.options.debug) console.log('datepicker plugin not found');
|
262
|
+
}
|
263
|
+
elem.on('keyup', 'input.filter', {column: column}, priv.filterChanged);
|
264
|
+
break;
|
265
|
+
case "bool":
|
266
|
+
if (tooltip == undefined) tooltip = priv.options.types.bool.filterTooltip;
|
267
|
+
tooltip = (tooltip === true || tooltip == undefined) ? 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked' : tooltip === false ? '' : tooltip;
|
268
|
+
elem = $('<input class="filter indeterminate" checked type="checkbox" />');
|
269
|
+
elem.on('click', {column: column}, priv.filterChanged);
|
270
|
+
break;
|
271
|
+
case "string":
|
272
|
+
if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;
|
273
|
+
placeHolder = (placeHolder === true || placeHolder == undefined) ? 'John Doe' : placeHolder === false ? '' : placeHolder;
|
274
|
+
if (tooltip == undefined) tooltip = priv.options.types.string.filterTooltip;
|
275
|
+
tooltip = (tooltip === true || tooltip == undefined) ? 'Find John Doe:<br/>John Doe<br/>Find all but John Doe:<br/>!John Doe' : tooltip === false ? '' : tooltip;
|
276
|
+
elem = $('<input placeholder="{0}" class="filter" type="text" />'.f(placeHolder));
|
277
|
+
elem.on('keyup', {column: column}, priv.filterChanged);
|
278
|
+
break;
|
279
|
+
case "none":
|
280
|
+
elem = $('<div> </div>');
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
|
284
|
+
if (tooltip) {
|
285
|
+
elem.tooltip({
|
286
|
+
title: tooltip.trim(),
|
287
|
+
html: true,
|
288
|
+
container: 'body',
|
289
|
+
trigger: 'hover',
|
290
|
+
placement: 'top',
|
291
|
+
delay: {
|
292
|
+
show: 500,
|
293
|
+
hide: 100
|
294
|
+
}
|
295
|
+
});
|
296
|
+
}
|
297
|
+
|
298
|
+
if (elem && props.filter) {
|
299
|
+
$.map(_filterCols, function (colProps, col) {
|
300
|
+
if (col == column) {
|
301
|
+
if (colProps.col.type == 'bool') {
|
302
|
+
if (colProps.filter) elem.prop('checked', true).removeClass('indeterminate');
|
303
|
+
else if (!colProps.filter) elem.prop('checked', false).removeClass('indeterminate');
|
304
|
+
else if (colProps.filter == '') elem.addClass('indeterminate');
|
305
|
+
}
|
306
|
+
else elem.val(colProps.filter);
|
307
|
+
}
|
308
|
+
});
|
309
|
+
elem.appendTo(headCell);
|
310
|
+
}
|
311
|
+
}
|
312
|
+
}
|
313
|
+
}
|
314
|
+
|
315
|
+
//create the body
|
316
|
+
if (!_body) {
|
317
|
+
_table.find('tbody').remove();
|
318
|
+
_body = $('<tbody></tbody>').insertAfter(_head);
|
319
|
+
_body.on('change', '.unique', priv.rowChecked);
|
320
|
+
_body.on('click', 'td', priv.rowClicked);
|
321
|
+
|
322
|
+
//find out what rows to show next...
|
323
|
+
var rowsAdded = 0;
|
324
|
+
_data.toRow = _data.fromRow + priv.options.pageSize;
|
325
|
+
if (_data.toRow > _data.rows.length)
|
326
|
+
_data.toRow = _data.rows.length;
|
327
|
+
|
328
|
+
//slice out the chunk of data we need and create rows
|
329
|
+
$.each(_data.rows.slice(_data.fromRow, _data.toRow), function (index, props) {
|
330
|
+
var row = $('<tr></tr>').appendTo(_body);
|
331
|
+
|
332
|
+
//create checkbox
|
333
|
+
if (_uniqueCol && priv.options.checkboxes) {
|
334
|
+
var check = _uniqueCols[props[_uniqueCol]] != undefined ? 'checked' : '';
|
335
|
+
var checkable = props['checkable'] === false ? 'disabled' : '';
|
336
|
+
var cell = $('<td></td>').appendTo(row);
|
337
|
+
$('<input class="unique" {0} {1} type="checkbox" />'.f(check, checkable)).appendTo(cell);
|
338
|
+
}
|
339
|
+
|
340
|
+
//create cells
|
341
|
+
for (var i = 0; i < colsSorted.length; i++) {
|
342
|
+
var key = colsSorted[i];
|
343
|
+
var val = props[key];
|
344
|
+
if (!_data.cols[key]) return;
|
345
|
+
if (_data.cols[key].unique) row.data('unique', val);
|
346
|
+
|
347
|
+
if (!_data.cols[key].hidden) {
|
348
|
+
var cell = $('<td></td>').appendTo(row);
|
349
|
+
cell.data('column', key);
|
350
|
+
if (val === undefined) continue;
|
351
|
+
|
352
|
+
var format = props[key + 'Format'] || _data.cols[key].format || '{0}';
|
353
|
+
|
354
|
+
switch (_data.cols[key].type) {
|
355
|
+
case "string":
|
356
|
+
cell.html(format.f(val));
|
357
|
+
break;
|
358
|
+
case "number":
|
359
|
+
val = Number(val);
|
360
|
+
var forceDecimals = !isNaN(_data.cols[key].decimals);
|
361
|
+
if (forceDecimals) cell.html(format.f(val.toFixed(_data.cols[key].decimals)));
|
362
|
+
else {
|
363
|
+
(val || 0) % 1 === 0
|
364
|
+
? cell.html(format.f(val))
|
365
|
+
: cell.html(format.f(val.toFixed(priv.options.types.number.decimals || 2)));
|
366
|
+
}
|
367
|
+
break;
|
368
|
+
case "date":
|
369
|
+
val = new priv.ext.XDate(val, priv.options.types.date.utc === true).toString(priv.options.types.date.format || 'yyyy-MM-dd HH:mm:ss');
|
370
|
+
cell.html(format.f(val));
|
371
|
+
break;
|
372
|
+
case "bool":
|
373
|
+
$('<input type="checkbox" {0} disabled />'.f(val ? "checked" : "")).appendTo(cell);
|
374
|
+
break;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
}
|
378
|
+
rowsAdded++;
|
379
|
+
|
380
|
+
//enough rows created?
|
381
|
+
if (rowsAdded >= priv.options.pageSize) {
|
382
|
+
_data.toRow = _data.fromRow + rowsAdded;
|
383
|
+
return false;
|
384
|
+
}
|
385
|
+
});
|
386
|
+
|
387
|
+
if (_currPage == 1) {
|
388
|
+
_pageSize = rowsAdded;
|
389
|
+
_totalPages = Math.round(Math.ceil(_data.rows.length / _pageSize));
|
390
|
+
}
|
391
|
+
|
392
|
+
//pad with empty rows if we're at last page.
|
393
|
+
if (_currPage == _totalPages) {
|
394
|
+
while (rowsAdded < _pageSize) {
|
395
|
+
var row = $('<tr></tr>').appendTo(_body);
|
396
|
+
|
397
|
+
if (_uniqueCol && priv.options.checkboxes) {
|
398
|
+
var cell = $('<td></td>').appendTo(row);
|
399
|
+
$('<input disabled type="checkbox" />').appendTo(cell);
|
400
|
+
}
|
401
|
+
|
402
|
+
$.each(_data.cols, function (column, props) {
|
403
|
+
if (!props.hidden) $('<td> </td>').appendTo(row);
|
404
|
+
});
|
405
|
+
rowsAdded++;
|
406
|
+
}
|
407
|
+
}
|
408
|
+
}
|
409
|
+
|
410
|
+
//create the footer
|
411
|
+
if (!_foot) {
|
412
|
+
_table.find('tfoot').remove();
|
413
|
+
_foot = $('<tfoot></tfoot>').insertAfter(_body);
|
414
|
+
|
415
|
+
var footRow = $('<tr></tr>').appendTo(_foot);
|
416
|
+
var footCell = $('<td colspan="999"></td>').appendTo(footRow);
|
417
|
+
|
418
|
+
//create summary
|
419
|
+
if (_data.rows.length > 0)
|
420
|
+
$(priv.options.pagingTemplate.f(_data.fromRow + 1, Math.min(_data.toRow, _data.rows.length), _data.rows.length)).appendTo(footCell);
|
421
|
+
else {
|
422
|
+
$('<p>No results</p>').appendTo(footCell);
|
423
|
+
_totalPages = 0;
|
424
|
+
}
|
425
|
+
|
426
|
+
//create the pager.
|
427
|
+
var lowerPage = _currPage - 2;
|
428
|
+
var upperPage = _currPage + 2;
|
429
|
+
if (upperPage > _totalPages) {
|
430
|
+
var diff = upperPage - _totalPages;
|
431
|
+
upperPage = _totalPages;
|
432
|
+
lowerPage -= diff;
|
433
|
+
}
|
434
|
+
if (lowerPage < 1) lowerPage = 1;
|
435
|
+
if (upperPage < 5) upperPage = 5;
|
436
|
+
|
437
|
+
var footToolbar = $('<div class="btn-toolbar"></div>').appendTo(footCell);
|
438
|
+
var footDiv = $('<div class="btn-group"></div>').appendTo(footToolbar);
|
439
|
+
var footPagerDiv = $('<div class="pagination"></div>').appendTo(footDiv);
|
440
|
+
var footPagerUl = $('<ul></ul>').appendTo(footPagerDiv);
|
441
|
+
|
442
|
+
$('<li class="{0}"><a href="#">«</a></li>'.f(_currPage == 1 ? 'disabled' : ''))
|
443
|
+
.on('click', {pageIndex: _currPage - 1}, priv.pageChanged).appendTo(footPagerUl);
|
444
|
+
|
445
|
+
for (var i = lowerPage; i <= upperPage; i++) {
|
446
|
+
var link;
|
447
|
+
if (i != _currPage) link = $('<li class="{1}"><a href="#">{0}</a></li>'.f(i, i > _totalPages ? 'disabled' : ''));
|
448
|
+
if (i == _currPage) link = $('<li class="active"><a href="#">{0}</a></li>'.f(i));
|
449
|
+
|
450
|
+
if (link) {
|
451
|
+
link.on('click', {pageIndex: i}, priv.pageChanged);
|
452
|
+
link.appendTo(footPagerUl);
|
453
|
+
}
|
454
|
+
}
|
455
|
+
$('<li class="{0}"><a href="#">»</a></li>'.f(_currPage == _totalPages ? 'disabled' : ''))
|
456
|
+
.on('click', {pageIndex: _currPage + 1}, priv.pageChanged).appendTo(footPagerUl);
|
457
|
+
|
458
|
+
//create pagesize dropdown
|
459
|
+
if (priv.options.pageSizes.length) {
|
460
|
+
var div = $('<div class="btn-group dropup pagesize"></div>').appendTo(footToolbar);
|
461
|
+
var btn = $('<button class="btn dropdown-toggle" data-toggle="dropdown" href="#">Rows </button>').appendTo(div);
|
462
|
+
var span = $('<span class="caret"></span>').appendTo(btn);
|
463
|
+
var ul = $('<ul class="dropdown-menu">').appendTo(div);
|
464
|
+
|
465
|
+
$.each(priv.options.pageSizes, function (index, val) {
|
466
|
+
var li = $('<li></li>').appendTo(ul);
|
467
|
+
$('<a href="#">{0}</a>'.f(val)).appendTo(li);
|
468
|
+
});
|
469
|
+
div.on('click', 'a', priv.pageSizeChanged);
|
470
|
+
}
|
471
|
+
|
472
|
+
//create columnpicker dropdown
|
473
|
+
if (priv.options.columnPicker) {
|
474
|
+
var div = $('<div class="btn-group dropup columnpicker"></div>').appendTo(footToolbar);
|
475
|
+
var btn = $('<button class="btn dropdown-toggle" data-toggle="dropdown" href="#">Columns </button>').appendTo(div);
|
476
|
+
var span = $('<span class="caret"></span>').appendTo(btn);
|
477
|
+
var ul = $('<ul class="dropdown-menu">').appendTo(div);
|
478
|
+
|
479
|
+
$.each(_data.cols, function (col, props) {
|
480
|
+
if (props.type != "unique") {
|
481
|
+
var li = $('<li></li>').appendTo(ul);
|
482
|
+
$('<input {0} type="checkbox" title="{1}" value="{1}" > {2}</input>'.f(props.hidden ? '' : 'checked', col, props.friendly || col)).appendTo(li);
|
483
|
+
}
|
484
|
+
});
|
485
|
+
div.on('click', 'input', priv.columnPickerClicked);
|
486
|
+
}
|
487
|
+
|
488
|
+
//create actions dropdown
|
489
|
+
if (priv.options.actions) {
|
490
|
+
var div = $('<div class="btn-group dropup actions"></div>').appendTo(footToolbar);
|
491
|
+
var btn = $('<button class="btn dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-list"></i> </button>').appendTo(div);
|
492
|
+
var span = $('<span class="caret"></span>').appendTo(btn);
|
493
|
+
var ul = $('<ul class="dropdown-menu">').appendTo(div);
|
494
|
+
|
495
|
+
if (priv.options.actions.filter) {
|
496
|
+
var li = $('<li></li>').appendTo(ul);
|
497
|
+
$('<input {0} type="checkbox" > Filter</input>'.f(priv.options.filter ? 'checked' : '')).appendTo(li);
|
498
|
+
li.on('click', 'input', function (e) {
|
499
|
+
priv.options.filter = !priv.options.filter;
|
500
|
+
_head = undefined;
|
501
|
+
priv.createTable();
|
502
|
+
});
|
503
|
+
}
|
504
|
+
if (priv.options.actions.columnPicker) {
|
505
|
+
var li = $('<li></li>').appendTo(ul);
|
506
|
+
$('<input {0} type="checkbox" > ColumnPicker</input>'.f(priv.options.columnPicker ? 'checked' : '')).appendTo(li);
|
507
|
+
li.on('click', 'input', function (e) {
|
508
|
+
priv.options.columnPicker = !priv.options.columnPicker;
|
509
|
+
_foot = undefined;
|
510
|
+
priv.createTable();
|
511
|
+
});
|
512
|
+
}
|
513
|
+
if (priv.options.actions.custom) {
|
514
|
+
$.each(priv.options.actions.custom, function (index, val) {
|
515
|
+
var li = $('<li></li>').appendTo(ul);
|
516
|
+
$(val).appendTo(li);
|
517
|
+
});
|
518
|
+
}
|
519
|
+
}
|
520
|
+
}
|
521
|
+
|
522
|
+
if (_data.rows.length == 0 && priv.options.hidePagerOnEmpty)
|
523
|
+
$('.btn-toolbar', _foot).remove();
|
524
|
+
if (priv.options.debug)
|
525
|
+
console.log('table created in {0} ms.'.f(new priv.ext.XDate() - start));
|
526
|
+
if (typeof priv.options.tableCreated == 'function')
|
527
|
+
priv.options.tableCreated.call(_table.get(0), {table: _table.get(0)});
|
528
|
+
|
529
|
+
};
|
530
|
+
|
531
|
+
/*
|
532
|
+
calls the webservice(if defined).
|
533
|
+
*/
|
534
|
+
priv.update = function (callback, skipCols, resetChecked) {
|
535
|
+
if (!priv.options.url) {
|
536
|
+
if (priv.options.debug) console.log('no url found');
|
537
|
+
return;
|
538
|
+
}
|
539
|
+
|
540
|
+
if (priv.options.debug) console.log('requesting data from url:{0} data:{1}'.f(priv.options.url, JSON.stringify(priv.options.urlData) || ''));
|
541
|
+
var start = new priv.ext.XDate();
|
542
|
+
|
543
|
+
$.ajax({
|
544
|
+
url: priv.options.url,
|
545
|
+
type: priv.options.urlPost ? 'POST' : 'GET',
|
546
|
+
dataType: 'json',
|
547
|
+
contentType: "application/json; charset=utf-8",
|
548
|
+
data: priv.options.urlData,
|
549
|
+
async: true,
|
550
|
+
success: function (data) {
|
551
|
+
if (priv.options.debug) console.log('request finished in {0} ms.'.f(new priv.ext.XDate() - start));
|
552
|
+
|
553
|
+
//assign the new data
|
554
|
+
if (data.d && data.d.cols)
|
555
|
+
priv.setData(data.d, skipCols, resetChecked);
|
556
|
+
else
|
557
|
+
priv.setData(data, skipCols, resetChecked);
|
558
|
+
if (typeof callback == "function")
|
559
|
+
callback.call(this);
|
560
|
+
},
|
561
|
+
error: function (err) {
|
562
|
+
console.log('request error: '.f(err));
|
563
|
+
}
|
564
|
+
});
|
565
|
+
};
|
566
|
+
|
567
|
+
/*
|
568
|
+
assigns the new data.
|
569
|
+
*/
|
570
|
+
priv.setData = function (pData, skipCols, resetChecked) {
|
571
|
+
var data = $.extend(true, {}, pData);
|
572
|
+
data.fromRow = _data && _data.fromRow || 0;
|
573
|
+
data.toRow = _data && _data.toRow || 0;
|
574
|
+
|
575
|
+
//use previous column definitions?
|
576
|
+
skipCols = skipCols || false;
|
577
|
+
if (skipCols) data.cols = _data.cols;
|
578
|
+
else _filterCols = {};
|
579
|
+
|
580
|
+
_data = data;
|
581
|
+
_data.rowsOrg = _data.rows;
|
582
|
+
|
583
|
+
//we might have more/less data now. Recalculate stuff.
|
584
|
+
if (_currPage > 1) {
|
585
|
+
_data.toRow = Math.min(_data.rows.length, _data.toRow);
|
586
|
+
_data.fromRow = _data.toRow - _pageSize;
|
587
|
+
_data.fromRow = Math.max(_data.fromRow, 0);
|
588
|
+
_currPage = Math.ceil(_data.fromRow / _pageSize) + 1;
|
589
|
+
_totalPages = Math.ceil(_data.rows.length / _pageSize);
|
590
|
+
} else {
|
591
|
+
_data.fromRow = 0;
|
592
|
+
if (priv.options.pageSize != -1)
|
593
|
+
_data.toRow = _data.fromRow + priv.options.pageSize;
|
594
|
+
_data.toRow = Math.max(_data.toRow, _data.rows.length);
|
595
|
+
}
|
596
|
+
|
597
|
+
//wash the new data a bit
|
598
|
+
_uniqueCol = "";
|
599
|
+
$.each(_data.cols, function (col, props) {
|
600
|
+
//set sorting
|
601
|
+
if (!_currSortCol && props.sortOrder) {
|
602
|
+
_currSortCol = col;
|
603
|
+
_currSortFlip = props.sortOrder != "asc";
|
604
|
+
}
|
605
|
+
|
606
|
+
//default to string type if missing
|
607
|
+
if (!props.type) _data.cols[col].type = "string";
|
608
|
+
|
609
|
+
//if several unique columns is defined, use the first.
|
610
|
+
if (props.unique) {
|
611
|
+
if (!_uniqueCol) _uniqueCol = col;
|
612
|
+
else props.unique = false;
|
613
|
+
}
|
614
|
+
|
615
|
+
//if index property is missing, create one
|
616
|
+
if (!props.index) _data.cols[col].index = new priv.ext.XDate();
|
617
|
+
props.column = col;
|
618
|
+
|
619
|
+
//set any initial filter
|
620
|
+
if (!skipCols) {
|
621
|
+
if (props.filter == undefined) props.filter = true;
|
622
|
+
if (props.filter && typeof props.type != "bool" && typeof props.filter != "boolean") {
|
623
|
+
_filterCols[col] = _filterCols[col] || {
|
624
|
+
filter: String(props.filter),
|
625
|
+
col: props
|
626
|
+
};
|
627
|
+
}
|
628
|
+
}
|
629
|
+
});
|
630
|
+
|
631
|
+
//keep any previously checked rows around?
|
632
|
+
if (resetChecked === true || resetChecked === undefined)
|
633
|
+
_uniqueCols = {};
|
634
|
+
else {
|
635
|
+
for (var key in _uniqueCols)
|
636
|
+
_uniqueCols[key] = priv.getRow(key);
|
637
|
+
}
|
638
|
+
|
639
|
+
if (_uniqueCol) {
|
640
|
+
//create a unique column definition
|
641
|
+
_data.cols["unique"] = {
|
642
|
+
column: "unique",
|
643
|
+
type: "unique",
|
644
|
+
index: -1,
|
645
|
+
hidden: true
|
646
|
+
};
|
647
|
+
|
648
|
+
//add rows that needs to be pre-checked
|
649
|
+
$.each(_data.rows, function (index, row) {
|
650
|
+
if (row["checked"] === true)
|
651
|
+
_uniqueCols[row[_uniqueCol]] = row;
|
652
|
+
});
|
653
|
+
}
|
654
|
+
|
655
|
+
_head = undefined;
|
656
|
+
_body = undefined;
|
657
|
+
_foot = undefined;
|
658
|
+
priv.filter();
|
659
|
+
priv.sort();
|
660
|
+
priv.createTable();
|
661
|
+
};
|
662
|
+
|
663
|
+
/*
|
664
|
+
filters the data.
|
665
|
+
*/
|
666
|
+
priv.filter = function () {
|
667
|
+
if (!priv.options.filter) return;
|
668
|
+
if (Object.keys(_filterCols).length == 0) return;
|
669
|
+
|
670
|
+
//get a fresh copy of the data
|
671
|
+
_data.rows = $.extend(true, {}, _data.rowsOrg);
|
672
|
+
var start = new priv.ext.XDate();
|
673
|
+
|
674
|
+
//for every column with a filter, run through the rows and return the matching rows
|
675
|
+
$.each(_filterCols, function (col, colProps) {
|
676
|
+
if (priv.options.debug) console.log('filtering on text:{0} col:{1} type:{2} '.f(colProps.filter, colProps.col.column, colProps.col.type));
|
677
|
+
|
678
|
+
switch (colProps.col.type) {
|
679
|
+
case "string":
|
680
|
+
_data.rows = $.map(_data.rows, function (row) {
|
681
|
+
var val = String(row[col]);
|
682
|
+
var filter = colProps.filter.toLowerCase();
|
683
|
+
var ne = filter.charAt(0) == '!';
|
684
|
+
if (ne) filter = filter.substring(1);
|
685
|
+
var pos = val.toLowerCase().indexOf(filter);
|
686
|
+
|
687
|
+
if ((pos == -1 && ne) || colProps.filter === '') return row;
|
688
|
+
else if (row[col] != undefined && pos >= 0 && !ne) {
|
689
|
+
if (!row[col + 'Format'] && !colProps.col.format) {
|
690
|
+
var pre = val.substring(0, pos);
|
691
|
+
var match = val.substring(pos, pos + colProps.filter.length);
|
692
|
+
var post = val.substring(pos + colProps.filter.length, row[col].length);
|
693
|
+
row[col + 'Format'] = '<span>{0}<span class="filter">{1}</span>{2}</span>'.f(pre, match, post);
|
694
|
+
}
|
695
|
+
return row;
|
696
|
+
}
|
697
|
+
});
|
698
|
+
break;
|
699
|
+
case "number":
|
700
|
+
case "date":
|
701
|
+
_data.rows = $.map(_data.rows, function (row) {
|
702
|
+
var exp = colProps.filter.replace(/\s+/gi, ' ').split(' ');
|
703
|
+
exp = $(exp).filter(function(){return this});
|
704
|
+
var opArray = [">=", "<=", "..", ">", "<", "="];
|
705
|
+
var matches = 0;
|
706
|
+
var illegal = true;
|
707
|
+
|
708
|
+
$.each(exp, function (index, expr) {
|
709
|
+
|
710
|
+
for (var i = 0; i < opArray.length; i++) {
|
711
|
+
|
712
|
+
var op = opArray[i];
|
713
|
+
var pos = expr.indexOf(op);
|
714
|
+
var lval = expr.substring(0, pos);
|
715
|
+
var rval = expr.substring(pos + op.length);
|
716
|
+
|
717
|
+
if (pos == -1) continue;
|
718
|
+
|
719
|
+
illegal = ((lval.length + rval.length) == 0);
|
720
|
+
lval = parseFloat(lval);
|
721
|
+
rval = parseFloat(rval);
|
722
|
+
if (isNaN(lval)) lval = Number.NEGATIVE_INFINITY;
|
723
|
+
if (isNaN(rval)) rval = Number.MAX_VALUE;
|
724
|
+
|
725
|
+
if (colProps.col.type == "date") {
|
726
|
+
var today = new priv.ext.XDate(priv.options.types.date.utc === true).setHours(0, 0, 0, 0);
|
727
|
+
lval = today - (lval * -1) * (60 * 60 * 24 * 1000);
|
728
|
+
rval = today - (rval * -1) * (60 * 60 * 24 * 1000);
|
729
|
+
}
|
730
|
+
|
731
|
+
switch (op) {
|
732
|
+
case ">":
|
733
|
+
if (row[col] > rval) matches++;
|
734
|
+
break;
|
735
|
+
case ">=":
|
736
|
+
if (row[col] >= rval) matches++;
|
737
|
+
break;
|
738
|
+
case "<":
|
739
|
+
if (row[col] < rval) matches++;
|
740
|
+
break;
|
741
|
+
case "<=":
|
742
|
+
if (row[col] <= rval) matches++;
|
743
|
+
break;
|
744
|
+
case "=":
|
745
|
+
if (row[col] == rval) matches++;
|
746
|
+
break;
|
747
|
+
case "..":
|
748
|
+
if (colProps.col.type == "date") {
|
749
|
+
if (row[col] >= lval && row[col] < rval) matches++;
|
750
|
+
}
|
751
|
+
else {
|
752
|
+
if (row[col] >= lval && row[col] <= rval) matches++;
|
753
|
+
}
|
754
|
+
break;
|
755
|
+
default:
|
756
|
+
illegal = true;
|
757
|
+
}
|
758
|
+
break;
|
759
|
+
}
|
760
|
+
});
|
761
|
+
if ((exp.length == 1 && illegal) ||
|
762
|
+
(matches > 0 && illegal) ||
|
763
|
+
matches == exp.length ||
|
764
|
+
colProps.filter == '') return row;
|
765
|
+
});
|
766
|
+
break;
|
767
|
+
case "bool":
|
768
|
+
_data.rows = $.map(_data.rows, function (row) {
|
769
|
+
if (colProps.filter === '') return row;
|
770
|
+
if (row[col] != undefined && ((Boolean(row[col]) && colProps.filter) || (!Boolean(row[col]) && !colProps.filter))) return row;
|
771
|
+
});
|
772
|
+
break;
|
773
|
+
case "unique":
|
774
|
+
_data.rows = $.map(_data.rows, function (row) {
|
775
|
+
if (colProps.filter === '') return row;
|
776
|
+
var a = row[_uniqueCol];
|
777
|
+
var b = _uniqueCols[a] ? _uniqueCols[a][_uniqueCol] : '';
|
778
|
+
if ((colProps.filter && a === b) || (!colProps.filter && b === '')) return row;
|
779
|
+
});
|
780
|
+
break;
|
781
|
+
}
|
782
|
+
if (colProps.filter === '') delete _filterCols[colProps.col.column];
|
783
|
+
});
|
784
|
+
if (priv.options.debug) console.log('filtering finished in {0} ms.'.f(new priv.ext.XDate() - start));
|
785
|
+
|
786
|
+
_currPage = 1;
|
787
|
+
_data.fromRow = 0;
|
788
|
+
_body = undefined;
|
789
|
+
_foot = undefined;
|
790
|
+
};
|
791
|
+
|
792
|
+
/*
|
793
|
+
sorts the data on the current sorting column
|
794
|
+
*/
|
795
|
+
priv.sort = function () {
|
796
|
+
if (!_data.cols[_currSortCol]) _currSortCol = "";
|
797
|
+
if (!_currSortCol) return;
|
798
|
+
|
799
|
+
var start = new priv.ext.XDate();
|
800
|
+
if (priv.options.debug) console.log('sorting on col:{0} order:{1}'.f(_currSortCol, _currSortFlip ? "desc" : "asc"));
|
801
|
+
|
802
|
+
var isString = (_data.cols[_currSortCol].type == "string");
|
803
|
+
_data.rows = _data.rows.sort(function (a, b) {
|
804
|
+
|
805
|
+
var valA = a[_currSortCol];
|
806
|
+
var valB = b[_currSortCol];
|
807
|
+
|
808
|
+
if (isString) {
|
809
|
+
if (valA == undefined) valA = '';
|
810
|
+
if (valB == undefined) valB = '';
|
811
|
+
|
812
|
+
if (String(valA).toLowerCase() == String(valB).toLowerCase()) return 0;
|
813
|
+
if (String(valA).toLowerCase() > String(valB).toLowerCase()) return _currSortFlip ? -1 : 1;
|
814
|
+
else return _currSortFlip ? 1 : -1;
|
815
|
+
} else {
|
816
|
+
if (valA == undefined) valA = Number.NEGATIVE_INFINITY;
|
817
|
+
if (valB == undefined) valB = Number.NEGATIVE_INFINITY;
|
818
|
+
|
819
|
+
if (valA == valB) return 0;
|
820
|
+
if (valA > valB) return _currSortFlip ? -1 : 1;
|
821
|
+
else return _currSortFlip ? 1 : -1;
|
822
|
+
}
|
823
|
+
});
|
824
|
+
if (priv.options.debug) console.log('sorting finished in {0} ms.'.f(new priv.ext.XDate() - start));
|
825
|
+
};
|
826
|
+
|
827
|
+
/*
|
828
|
+
helper that returns the underlying data by the unique value
|
829
|
+
*/
|
830
|
+
priv.getRow = function (unique) {
|
831
|
+
var start = new priv.ext.XDate();
|
832
|
+
var row;
|
833
|
+
$.each(_data.rowsOrg, function (i, r) {
|
834
|
+
if (r[_uniqueCol] == unique) {
|
835
|
+
row = r;
|
836
|
+
return false;
|
837
|
+
}
|
838
|
+
});
|
839
|
+
if (priv.options.debug) console.log('row lookup finished in {0} ms.'.f(new priv.ext.XDate() - start));
|
840
|
+
return row;
|
841
|
+
};
|
842
|
+
|
843
|
+
|
844
|
+
/* Event Handlers
|
845
|
+
*************************************************************************/
|
846
|
+
|
847
|
+
/*
|
848
|
+
when: typing a filter
|
849
|
+
what: triggers filtering on the value
|
850
|
+
*/
|
851
|
+
priv.filterChanged = function (e) {
|
852
|
+
//clear old timer if we're typing fast enough
|
853
|
+
if (_filterTimeout) {
|
854
|
+
clearTimeout(_filterTimeout);
|
855
|
+
if (priv.options.debug) console.log('filtering cancelled');
|
856
|
+
}
|
857
|
+
|
858
|
+
var filter = this.value;
|
859
|
+
var col = _data.cols[e.data.column];
|
860
|
+
var timeout = 200;
|
861
|
+
|
862
|
+
//boolean filters needs some special care
|
863
|
+
if (col.type == "bool" || col.type == "unique") {
|
864
|
+
timeout = 0;
|
865
|
+
var elem = $(this);
|
866
|
+
var cssClass = 'indeterminate';
|
867
|
+
if (elem.hasClass(cssClass)) {
|
868
|
+
e.preventDefault();
|
869
|
+
elem.removeClass(cssClass);
|
870
|
+
filter = true;
|
871
|
+
} else {
|
872
|
+
if (!elem.is(':checked')) {
|
873
|
+
filter = false;
|
874
|
+
} else {
|
875
|
+
elem.addClass(cssClass);
|
876
|
+
filter = '';
|
877
|
+
}
|
878
|
+
}
|
879
|
+
}
|
880
|
+
|
881
|
+
//add the filter to the filter array
|
882
|
+
_filterCols[col.column] = {
|
883
|
+
filter: filter,
|
884
|
+
col: col
|
885
|
+
};
|
886
|
+
|
887
|
+
//wait a few deciseconds before filtering
|
888
|
+
_filterTimeout = setTimeout(function () {
|
889
|
+
_filterTimeout = undefined;
|
890
|
+
priv.filter();
|
891
|
+
priv.sort();
|
892
|
+
priv.createTable();
|
893
|
+
}, timeout);
|
894
|
+
};
|
895
|
+
|
896
|
+
/*
|
897
|
+
when: changing page in pager
|
898
|
+
what: triggers table to be created with new page
|
899
|
+
*/
|
900
|
+
priv.pageChanged = function (e) {
|
901
|
+
e.preventDefault();
|
902
|
+
if (e.data.pageIndex < 1 || e.data.pageIndex > _totalPages) return;
|
903
|
+
|
904
|
+
//set the new page
|
905
|
+
_currPage = e.data.pageIndex;
|
906
|
+
if (priv.options.debug) console.log('paging to index:{0}'.f(_currPage));
|
907
|
+
|
908
|
+
//find out what rows to create
|
909
|
+
_data.fromRow = ((_currPage - 1) * _pageSize);
|
910
|
+
_data.toRow = _data.fromRow + _pageSize;
|
911
|
+
if (_data.toRow > _data.rows.length) _data.toRow = _data.rows.length;
|
912
|
+
|
913
|
+
//trigger callback
|
914
|
+
if (typeof priv.options.pageChanged == 'function') {
|
915
|
+
priv.options.pageChanged.call(e.target, {
|
916
|
+
event: e,
|
917
|
+
page: _currPage
|
918
|
+
});
|
919
|
+
}
|
920
|
+
|
921
|
+
_body = undefined;
|
922
|
+
_foot = undefined;
|
923
|
+
priv.createTable();
|
924
|
+
};
|
925
|
+
|
926
|
+
/*
|
927
|
+
when: changing pagesize in pagesize dropdown
|
928
|
+
what: triggers table to be created with new pagesize
|
929
|
+
*/
|
930
|
+
priv.pageSizeChanged = function (e) {
|
931
|
+
e.preventDefault();
|
932
|
+
var val = $(this).text().toLowerCase();
|
933
|
+
if (priv.options.debug) console.log('pagesize changed to:{0}'.f(val));
|
934
|
+
|
935
|
+
//set the new pagesize
|
936
|
+
if (val == "all") priv.options.pageSize = _data.rows.length;
|
937
|
+
else priv.options.pageSize = parseInt(val);
|
938
|
+
|
939
|
+
//revert to first page, as its gets messy otherwise.
|
940
|
+
_currPage = 1;
|
941
|
+
_data.fromRow = 0;
|
942
|
+
_data.toRow = _data.fromRow + priv.options.pageSize;
|
943
|
+
if (_data.toRow > _data.rows.length) _data.toRow = _data.rows.length;
|
944
|
+
|
945
|
+
//trigger callback
|
946
|
+
if (typeof priv.options.pageSizeChanged == 'function') {
|
947
|
+
priv.options.pageSizeChanged.call(e.target, {
|
948
|
+
event: e,
|
949
|
+
pageSize: priv.options.pageSize
|
950
|
+
});
|
951
|
+
}
|
952
|
+
|
953
|
+
_body = undefined;
|
954
|
+
_foot = undefined;
|
955
|
+
priv.createTable();
|
956
|
+
};
|
957
|
+
|
958
|
+
/*
|
959
|
+
when: clicking a column
|
960
|
+
what: triggers table to be sorted by the column
|
961
|
+
*/
|
962
|
+
priv.columnClicked = function (e) {
|
963
|
+
e.preventDefault();
|
964
|
+
if (priv.options.debug) console.log('col:{0} clicked'.f(e.data.column));
|
965
|
+
|
966
|
+
//set the new sorting column
|
967
|
+
if (_currSortCol == e.data.column) _currSortFlip = !_currSortFlip;
|
968
|
+
_currSortCol = e.data.column;
|
969
|
+
|
970
|
+
//trigger callback
|
971
|
+
if (typeof priv.options.columnClicked == 'function') {
|
972
|
+
priv.options.columnClicked.call(e.target, {
|
973
|
+
event: e,
|
974
|
+
column: _data.cols[_currSortCol],
|
975
|
+
descending: _currSortFlip
|
976
|
+
});
|
977
|
+
}
|
978
|
+
|
979
|
+
_headSort = undefined;
|
980
|
+
_body = undefined;
|
981
|
+
priv.sort();
|
982
|
+
priv.createTable();
|
983
|
+
};
|
984
|
+
|
985
|
+
/*
|
986
|
+
when: clicking a column in columnpicker
|
987
|
+
what: triggers table to show/hide the column
|
988
|
+
*/
|
989
|
+
priv.columnPickerClicked = function (e) {
|
990
|
+
e.stopPropagation();
|
991
|
+
|
992
|
+
var elem = $(this);
|
993
|
+
var col = elem.val();
|
994
|
+
if (priv.options.debug) console.log('col:{0} {1}'.f(col, elem.is(':checked') ? 'checked' : 'unchecked'));
|
995
|
+
|
996
|
+
//toggle column visibility
|
997
|
+
_data.cols[col].hidden = !_data.cols[col].hidden;
|
998
|
+
|
999
|
+
_data.cols[col].index = new priv.ext.XDate();
|
1000
|
+
_head = undefined;
|
1001
|
+
_body = undefined;
|
1002
|
+
priv.createTable();
|
1003
|
+
};
|
1004
|
+
|
1005
|
+
/*
|
1006
|
+
when: clicking the check-all checkbox
|
1007
|
+
what: toggles checked state on all rows, and adds/removes them from checked array
|
1008
|
+
*/
|
1009
|
+
priv.checkToggleChanged = function (e) {
|
1010
|
+
var elem = $(this);
|
1011
|
+
|
1012
|
+
if (elem.is(':checked')) {
|
1013
|
+
var start = new priv.ext.XDate();
|
1014
|
+
//for every row(except non checkables), add it to the checked array
|
1015
|
+
$.each(_data.rows, function (index, props) {
|
1016
|
+
var row = _data.rows[index];
|
1017
|
+
if (row.checkable === false) return;
|
1018
|
+
_uniqueCols[props[_uniqueCol]] = row;
|
1019
|
+
});
|
1020
|
+
if (priv.options.debug) console.log('{0} rows checked in {1} ms.'.f(_data.rows.length, new priv.ext.XDate() - start));
|
1021
|
+
_checkToggleChecked = true;
|
1022
|
+
}
|
1023
|
+
else {
|
1024
|
+
var start = new priv.ext.XDate();
|
1025
|
+
//for every checked row(except non checkables), remove it from checked array
|
1026
|
+
for (var key in _uniqueCols) {
|
1027
|
+
var row = _uniqueCols[key];
|
1028
|
+
if (row.checkable === false)
|
1029
|
+
continue;
|
1030
|
+
else
|
1031
|
+
delete _uniqueCols[key];
|
1032
|
+
}
|
1033
|
+
if (priv.options.debug) console.log('{0} rows unchecked in {1} ms.'.f(_data.rows.length, new priv.ext.XDate() - start));
|
1034
|
+
_checkToggleChecked = false;
|
1035
|
+
}
|
1036
|
+
_body = undefined;
|
1037
|
+
priv.createTable();
|
1038
|
+
};
|
1039
|
+
|
1040
|
+
/*
|
1041
|
+
when: clicking a row checkbox
|
1042
|
+
what: toggles checked state on row, and add/removes it from checked array
|
1043
|
+
*/
|
1044
|
+
priv.rowChecked = function (e) {
|
1045
|
+
var elem = $(this);
|
1046
|
+
|
1047
|
+
//get the row's unique value
|
1048
|
+
var unique = elem.closest('tr').data('unique');
|
1049
|
+
if (priv.options.debug) console.log('row({0}) {1}'.f(unique, elem.is(':checked') ? 'checked' : 'unchecked'));
|
1050
|
+
|
1051
|
+
//store the row in checked array
|
1052
|
+
if (elem.is(':checked')) _uniqueCols[unique] = priv.getRow(unique);
|
1053
|
+
else delete _uniqueCols[unique];
|
1054
|
+
};
|
1055
|
+
|
1056
|
+
/*
|
1057
|
+
when: clicking anywhere on a row
|
1058
|
+
what: row data and other info is returned to caller
|
1059
|
+
*/
|
1060
|
+
priv.rowClicked = function (e) {
|
1061
|
+
if (!_uniqueCol) {
|
1062
|
+
if (priv.options.debug) console.log('no unique column specified');
|
1063
|
+
return;
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
//gather callback data
|
1067
|
+
var elem = $(this);
|
1068
|
+
var column = _data.cols[elem.data('column')];
|
1069
|
+
var unique = elem.closest('tr').data('unique');
|
1070
|
+
var row = priv.getRow(unique);
|
1071
|
+
var isChecked = elem.closest('tr').find('.unique').is(':checked');
|
1072
|
+
|
1073
|
+
//trigger callback
|
1074
|
+
if (typeof priv.options.rowClicked == 'function') {
|
1075
|
+
priv.options.rowClicked.call(e.target, {
|
1076
|
+
event: e,
|
1077
|
+
row: row,
|
1078
|
+
column: column,
|
1079
|
+
checked: isChecked
|
1080
|
+
});
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
};
|
1084
|
+
|
1085
|
+
/*
|
1086
|
+
when: clicking a datepicker operator
|
1087
|
+
what: sets the datepicker operator before a datepicker date is chosen.
|
1088
|
+
*/
|
1089
|
+
priv.dpOpChanged = function(e) {
|
1090
|
+
if (priv.options.debug) console.log('dp oper:{0} clicked'.f(e.data.op));
|
1091
|
+
e.preventDefault();
|
1092
|
+
_currDpOp = e.data.op;
|
1093
|
+
};
|
1094
|
+
|
1095
|
+
/*
|
1096
|
+
when: clicking a datepicker date
|
1097
|
+
what: triggers filtering on the date
|
1098
|
+
*/
|
1099
|
+
priv.dpClicked = function (e) {
|
1100
|
+
if (priv.options.debug) console.log('dp date:{0} clicked'.f(new priv.ext.XDate(e.date, priv.options.types.date.utc === true).toString('yyyy-MM-dd')));
|
1101
|
+
|
1102
|
+
e.preventDefault();
|
1103
|
+
input = $(this).prev('input.filter').get(0);
|
1104
|
+
Placeholders.disable(input); //Remove date placeholders for IE
|
1105
|
+
|
1106
|
+
var today = new priv.ext.XDate(false).setHours(0, 0, 0, 0);
|
1107
|
+
var daysDiff = Math.floor(e.date / (60 * 60 * 24 * 1000)) - Math.floor(today / (60 * 60 * 24 * 1000));
|
1108
|
+
|
1109
|
+
var filter = $(e.data.input);
|
1110
|
+
var op = "..";
|
1111
|
+
var pos = filter.val().indexOf(op);
|
1112
|
+
var lval = filter.val().substring(0, pos);
|
1113
|
+
var rval = filter.val().substring(pos + op.length);
|
1114
|
+
|
1115
|
+
if (_currDpOp == "l") lval = daysDiff;
|
1116
|
+
if (_currDpOp == "r") rval = daysDiff;
|
1117
|
+
|
1118
|
+
filter.val("{0}{1}{2}".f(lval, op, rval));
|
1119
|
+
Placeholders.enable(input);
|
1120
|
+
$(this).datepicker('hide');
|
1121
|
+
filter.trigger('keyup');
|
1122
|
+
};
|
1123
|
+
|
1124
|
+
|
1125
|
+
/* Public API
|
1126
|
+
*************************************************************************/
|
1127
|
+
|
1128
|
+
publ.init = function (options) {
|
1129
|
+
if (priv.options.debug) console.log('watable initialization...');
|
1130
|
+
//merge supplied options with defaults
|
1131
|
+
$.extend(priv.options, defaults, options);
|
1132
|
+
priv.init();
|
1133
|
+
return publ;
|
1134
|
+
};
|
1135
|
+
|
1136
|
+
publ.update = function (callback, skipCols, resetChecked) {
|
1137
|
+
if (priv.options.debug) console.log('publ.update called');
|
1138
|
+
priv.update(callback, skipCols, resetChecked);
|
1139
|
+
return publ;
|
1140
|
+
};
|
1141
|
+
|
1142
|
+
publ.getData = function (checked, filtered) {
|
1143
|
+
if (priv.options.debug) console.log('publ.getData called');
|
1144
|
+
checked = checked || false;
|
1145
|
+
filtered = filtered || false;
|
1146
|
+
|
1147
|
+
var data = $.extend(true, {}, _data);
|
1148
|
+
delete data.cols["unique"];
|
1149
|
+
|
1150
|
+
$.each(data.cols, function(col) {
|
1151
|
+
if (_filterCols[col]) data.cols[col].filter = _filterCols[col].filter;
|
1152
|
+
});
|
1153
|
+
|
1154
|
+
if (!filtered) {
|
1155
|
+
delete data.rows;
|
1156
|
+
data.rows = data.rowsOrg;
|
1157
|
+
}
|
1158
|
+
delete data.rowsOrg;
|
1159
|
+
delete data.fromRow;
|
1160
|
+
delete data.toRow;
|
1161
|
+
|
1162
|
+
if (checked) {
|
1163
|
+
delete data.rows;
|
1164
|
+
data.rows = $.map(_uniqueCols, function (val, index) {
|
1165
|
+
return val;
|
1166
|
+
});
|
1167
|
+
}
|
1168
|
+
return data;
|
1169
|
+
};
|
1170
|
+
|
1171
|
+
publ.setData = function (data, skipCols, resetChecked) {
|
1172
|
+
if (priv.options.debug) console.log('publ.setData called');
|
1173
|
+
priv.setData(data, skipCols, resetChecked);
|
1174
|
+
return publ;
|
1175
|
+
};
|
1176
|
+
|
1177
|
+
publ.option = function (option, val) {
|
1178
|
+
if (priv.options.debug) console.log('publ.option called');
|
1179
|
+
if (val == undefined) return priv.options[option];
|
1180
|
+
priv.options[option] = val;
|
1181
|
+
_head = undefined;
|
1182
|
+
_body = undefined;
|
1183
|
+
_foot = undefined;
|
1184
|
+
priv.createTable();
|
1185
|
+
return publ;
|
1186
|
+
};
|
1187
|
+
|
1188
|
+
return publ;
|
1189
|
+
};
|
1190
|
+
|
1191
|
+
$.fn.WATable = function (options) {
|
1192
|
+
options = options || {};
|
1193
|
+
return this.each(function () {
|
1194
|
+
options.id = this;
|
1195
|
+
$(this).data('WATable', new WATable().init(options));
|
1196
|
+
});
|
1197
|
+
};
|
1198
|
+
|
1199
|
+
String.prototype.format = String.prototype.f = function () {
|
1200
|
+
var s = this;
|
1201
|
+
i = arguments.length;
|
1202
|
+
while (i--) s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
|
1203
|
+
return s;
|
1204
|
+
};
|
1205
|
+
|
1206
|
+
//IE Polyfills
|
1207
|
+
/* placeholders.js */ (function(t){"use strict";function e(t,e,r){return t.addEventListener?t.addEventListener(e,r,!1):t.attachEvent?t.attachEvent("on"+e,r):void 0}function r(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(t[r]===e)return!0;return!1}function n(t,e){var r;t.createTextRange?(r=t.createTextRange(),r.move("character",e),r.select()):t.selectionStart&&(t.focus(),t.setSelectionRange(e,e))}function a(t,e){try{return t.type=e,!0}catch(r){return!1}}t.Placeholders={Utils:{addEventListener:e,inArray:r,moveCaret:n,changeType:a}}})(this),function(t){"use strict";function e(t){var e;return t.value===t.getAttribute(S)&&"true"===t.getAttribute(I)?(t.setAttribute(I,"false"),t.value="",t.className=t.className.replace(R,""),e=t.getAttribute(P),e&&(t.type=e),!0):!1}function r(t){var e,r=t.getAttribute(S);return""===t.value&&r?(t.setAttribute(I,"true"),t.value=r,t.className+=" "+k,e=t.getAttribute(P),e?t.type="text":"password"===t.type&&H.changeType(t,"text")&&t.setAttribute(P,"password"),!0):!1}function n(t,e){var r,n,a,u,i;if(t&&t.getAttribute(S))e(t);else for(r=t?t.getElementsByTagName("input"):v,n=t?t.getElementsByTagName("textarea"):b,i=0,u=r.length+n.length;u>i;i++)a=r.length>i?r[i]:n[i-r.length],e(a)}function a(t){n(t,e)}function u(t){n(t,r)}function i(t){return function(){f&&t.value===t.getAttribute(S)&&"true"===t.getAttribute(I)?H.moveCaret(t,0):e(t)}}function l(t){return function(){r(t)}}function c(t){return function(e){return p=t.value,"true"===t.getAttribute(I)?!(p===t.getAttribute(S)&&H.inArray(C,e.keyCode)):void 0}}function o(t){return function(){var e;"true"===t.getAttribute(I)&&t.value!==p&&(t.className=t.className.replace(R,""),t.value=t.value.replace(t.getAttribute(S),""),t.setAttribute(I,!1),e=t.getAttribute(P),e&&(t.type=e)),""===t.value&&(t.blur(),H.moveCaret(t,0))}}function s(t){return function(){t===document.activeElement&&t.value===t.getAttribute(S)&&"true"===t.getAttribute(I)&&H.moveCaret(t,0)}}function d(t){return function(){a(t)}}function g(t){t.form&&(x=t.form,x.getAttribute(U)||(H.addEventListener(x,"submit",d(x)),x.setAttribute(U,"true"))),H.addEventListener(t,"focus",i(t)),H.addEventListener(t,"blur",l(t)),f&&(H.addEventListener(t,"keydown",c(t)),H.addEventListener(t,"keyup",o(t)),H.addEventListener(t,"click",s(t))),t.setAttribute(j,"true"),t.setAttribute(S,y),r(t)}var v,b,f,h,p,m,A,y,E,x,T,N,L,w=["text","search","url","tel","email","password","number","textarea"],C=[27,33,34,35,36,37,38,39,40,8,46],B="#ccc",k="placeholdersjs",R=RegExp("\\b"+k+"\\b"),S="data-placeholder-value",I="data-placeholder-active",P="data-placeholder-type",U="data-placeholder-submit",j="data-placeholder-bound",V="data-placeholder-focus",q="data-placeholder-live",z=document.createElement("input"),D=document.getElementsByTagName("head")[0],F=document.documentElement,G=t.Placeholders,H=G.Utils;if(void 0===z.placeholder){for(v=document.getElementsByTagName("input"),b=document.getElementsByTagName("textarea"),f="false"===F.getAttribute(V),h="false"!==F.getAttribute(q),m=document.createElement("style"),m.type="text/css",A=document.createTextNode("."+k+" { color:"+B+"; }"),m.styleSheet?m.styleSheet.cssText=A.nodeValue:m.appendChild(A),D.insertBefore(m,D.firstChild),L=0,N=v.length+b.length;N>L;L++)T=v.length>L?v[L]:b[L-v.length],y=T.getAttribute("placeholder"),y&&H.inArray(w,T.type)&&g(T);E=setInterval(function(){for(L=0,N=v.length+b.length;N>L;L++)T=v.length>L?v[L]:b[L-v.length],y=T.getAttribute("placeholder"),y&&H.inArray(w,T.type)&&(T.getAttribute(j)||g(T),(y!==T.getAttribute(S)||"password"===T.type&&!T.getAttribute(P))&&("password"===T.type&&!T.getAttribute(P)&&H.changeType(T,"text")&&T.setAttribute(P,"password"),T.value===T.getAttribute(S)&&(T.value=y),T.setAttribute(S,y)));h||clearInterval(E)},100)}G.disable=a,G.enable=u}(this);
|
1208
|
+
Object.keys = Object.keys || function(o) { var result = []; for(var name in o) { if (o.hasOwnProperty(name)) result.push(name); } return result; };
|
1209
|
+
String.prototype.trim = String.prototype.trim || function () { return this.replace(/^\s+|\s+$/g,''); };
|
1210
|
+
Date.now = Date.now || function() { return +new Date; };
|
1211
|
+
console = window.console || { log:function(){} };
|
1212
|
+
|
1213
|
+
})(jQuery);
|