summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/extensions/jquery.jtable.aspnetpagemethods.js125
-rw-r--r--lib/extensions/jquery.jtable.aspnetpagemethods.min.js27
-rw-r--r--lib/external/json2.js487
-rw-r--r--lib/external/json2.min.js10
-rw-r--r--lib/jquery.jtable.js3562
-rw-r--r--lib/jquery.jtable.min.js125
-rw-r--r--lib/themes/lightcolor/bg-thead.pngbin0 -> 2811 bytes
-rw-r--r--lib/themes/lightcolor/blue/jtable.css89
-rw-r--r--lib/themes/lightcolor/blue/loading.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/lightcolor/close.pngbin0 -> 1217 bytes
-rw-r--r--lib/themes/lightcolor/column-asc.pngbin0 -> 362 bytes
-rw-r--r--lib/themes/lightcolor/column-desc.pngbin0 -> 349 bytes
-rw-r--r--lib/themes/lightcolor/column-sortable.pngbin0 -> 347 bytes
-rw-r--r--lib/themes/lightcolor/delete.pngbin0 -> 150 bytes
-rw-r--r--lib/themes/lightcolor/edit.pngbin0 -> 590 bytes
-rw-r--r--lib/themes/lightcolor/gray/jtable.css88
-rw-r--r--lib/themes/lightcolor/gray/loading.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/lightcolor/gray/loading2.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/lightcolor/green/jtable.css89
-rw-r--r--lib/themes/lightcolor/green/loading.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/lightcolor/jtable_lightcolor_base.css654
-rw-r--r--lib/themes/lightcolor/orange/jtable.css88
-rw-r--r--lib/themes/lightcolor/orange/loading.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/lightcolor/red/jtable.css89
-rw-r--r--lib/themes/lightcolor/red/loading.gifbin0 -> 723 bytes
-rw-r--r--lib/themes/standard/blue/header-bg.gifbin0 -> 54 bytes
-rw-r--r--lib/themes/standard/blue/jtable_blue.css176
-rw-r--r--lib/themes/standard/blue/loading.gifbin0 -> 673 bytes
-rw-r--r--lib/themes/standard/blue/title-bg.pngbin0 -> 140 bytes
-rw-r--r--lib/themes/standard/close.pngbin0 -> 831 bytes
-rw-r--r--lib/themes/standard/column-asc.pngbin0 -> 320 bytes
-rw-r--r--lib/themes/standard/column-desc.pngbin0 -> 311 bytes
-rw-r--r--lib/themes/standard/column-sortable.pngbin0 -> 314 bytes
-rw-r--r--lib/themes/standard/delete.pngbin0 -> 150 bytes
-rw-r--r--lib/themes/standard/edit.pngbin0 -> 618 bytes
-rw-r--r--lib/themes/standard/green/header-bg.gifbin0 -> 54 bytes
-rw-r--r--lib/themes/standard/green/jtable_green.css176
-rw-r--r--lib/themes/standard/green/loading.gifbin0 -> 673 bytes
-rw-r--r--lib/themes/standard/green/title-bg.pngbin0 -> 171 bytes
-rw-r--r--lib/themes/standard/jtable_standard_base.css535
-rw-r--r--lib/themes/standard/purple/jtable_purple.css199
-rw-r--r--lib/themes/standard/purple/loading.gifbin0 -> 673 bytes
-rw-r--r--lib/themes/standard/red/header-bg.gifbin0 -> 54 bytes
-rw-r--r--lib/themes/standard/red/jtable_red.css185
-rw-r--r--lib/themes/standard/red/loading.gifbin0 -> 673 bytes
-rw-r--r--lib/themes/standard/red/title-bg.pngbin0 -> 193 bytes
46 files changed, 6704 insertions, 0 deletions
diff --git a/lib/extensions/jquery.jtable.aspnetpagemethods.js b/lib/extensions/jquery.jtable.aspnetpagemethods.js
new file mode 100644
index 0000000..307381d
--- /dev/null
+++ b/lib/extensions/jquery.jtable.aspnetpagemethods.js
@@ -0,0 +1,125 @@
+/*
+
+ASP.NET WEB FORMS PAGE METHODS EXTENSION FOR JTABLE
+http://www.jtable.org
+
+---------------------------------------------------------------------------
+
+Copyright (C) 2011 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+(function ($) {
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /* OVERRIDES BASE METHOD */
+ _performAjaxCall: function (url, postData, async, success, error) {
+ var self = this;
+
+ if (postData == null || postData == undefined) {
+ postData = {};
+ } else if (typeof postData == 'string') {
+ postData = self._convertQueryStringToObject(postData);
+ }
+
+ var qmIndex = url.indexOf('?');
+ if (qmIndex > -1) {
+ $.extend(postData, self._convertQueryStringToObject(url.substring(qmIndex + 1)));
+ }
+
+ postData = JSON.stringify(postData);
+
+ $.ajax({
+ url: url,
+ type: 'POST',
+ dataType: 'json',
+ contentType: "application/json; charset=utf-8",
+ data: postData,
+ async: async,
+ success: function (data) {
+ data = self._normalizeJSONReturnData(data);
+ success(data);
+ },
+ error: function () {
+ error();
+ }
+ });
+ },
+
+ /* OVERRIDES BASE METHOD */
+ _submitFormUsingAjax: function (url, formData, success, error) {
+ var self = this;
+
+ formData = {
+ record: self._convertQueryStringToObject(formData)
+ };
+
+ var qmIndex = url.indexOf('?');
+ if (qmIndex > -1) {
+ $.extend(formData, self._convertQueryStringToObject(url.substring(qmIndex + 1)));
+ }
+
+ var postData = JSON.stringify(formData);
+
+ $.ajax({
+ url: url,
+ type: 'POST',
+ dataType: 'json',
+ contentType: "application/json; charset=utf-8",
+ data: postData,
+ success: function (data) {
+ data = self._normalizeJSONReturnData(data);
+ success(data);
+ },
+ error: function () {
+ error();
+ }
+ });
+ },
+
+ _convertQueryStringToObject: function (queryString) {
+ var jsonObj = {};
+ var e,
+ a = /\+/g,
+ r = /([^&=]+)=?([^&]*)/g,
+ d = function (s) { return decodeURIComponent(s.replace(a, " ")); };
+
+ while (e = r.exec(queryString)) {
+ jsonObj[d(e[1])] = d(e[2]);
+ }
+
+ return jsonObj;
+ },
+
+ /* Normalizes JSON data that is returned from server.
+ *************************************************************************/
+ _normalizeJSONReturnData: function (data) {
+ //JSON Normalization for ASP.NET
+ if (data.hasOwnProperty('d')) {
+ return data.d;
+ }
+
+ return data;
+ }
+ });
+
+})(jQuery); \ No newline at end of file
diff --git a/lib/extensions/jquery.jtable.aspnetpagemethods.min.js b/lib/extensions/jquery.jtable.aspnetpagemethods.min.js
new file mode 100644
index 0000000..974253e
--- /dev/null
+++ b/lib/extensions/jquery.jtable.aspnetpagemethods.min.js
@@ -0,0 +1,27 @@
+/*
+ASP.NET WEB FORMS PAGE METHODS EXTENSION FOR JTABLE
+http://www.jtable.org
+---------------------------------------------------------------------------
+Copyright (C) 2011 by Halil Ýbrahim Kalkan (http://www.halilibrahimkalkan.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+(function(c){c.extend(!0,c.hik.jtable.prototype,{_performAjaxCall:function(b,a,d,g,e){var f=this;null==a||void 0==a?a={}:"string"==typeof a&&(a=f._convertQueryStringToObject(a));var h=b.indexOf("?");-1<h&&c.extend(a,f._convertQueryStringToObject(b.substring(h+1)));a=JSON.stringify(a);c.ajax({url:b,type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:a,async:d,success:function(a){a=f._normalizeJSONReturnData(a);g(a)},error:function(){e()}})},_submitFormUsingAjax:function(b,
+a,d,g){var e=this,a={record:e._convertQueryStringToObject(a)},f=b.indexOf("?");-1<f&&c.extend(a,e._convertQueryStringToObject(b.substring(f+1)));a=JSON.stringify(a);c.ajax({url:b,type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:a,success:function(a){a=e._normalizeJSONReturnData(a);d(a)},error:function(){g()}})},_convertQueryStringToObject:function(b){for(var a={},d,c=/\+/g,e=/([^&=]+)=?([^&]*)/g;d=e.exec(b);)a[decodeURIComponent(d[1].replace(c," "))]=decodeURIComponent(d[2].replace(c,
+" "));return a},_normalizeJSONReturnData:function(b){return b.hasOwnProperty("d")?b.d:b}})})(jQuery); \ No newline at end of file
diff --git a/lib/external/json2.js b/lib/external/json2.js
new file mode 100644
index 0000000..0ddf117
--- /dev/null
+++ b/lib/external/json2.js
@@ -0,0 +1,487 @@
+/*
+http://www.JSON.org/json2.js
+2011-10-19
+
+Public Domain.
+
+NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+See http://www.JSON.org/js.html
+
+
+This code should be minified before deployment.
+See http://javascript.crockford.com/jsmin.html
+
+USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+NOT CONTROL.
+
+
+This file creates a global JSON object containing two methods: stringify
+and parse.
+
+JSON.stringify(value, replacer, space)
+value any JavaScript value, usually an object or array.
+
+replacer an optional parameter that determines how object
+values are stringified for objects. It can be a
+function or an array of strings.
+
+space an optional parameter that specifies the indentation
+of nested structures. If it is omitted, the text will
+be packed without extra whitespace. If it is a number,
+it will specify the number of spaces to indent at each
+level. If it is a string (such as '\t' or '&nbsp;'),
+it contains the characters used to indent at each level.
+
+This method produces a JSON text from a JavaScript value.
+
+When an object value is found, if the object contains a toJSON
+method, its toJSON method will be called and the result will be
+stringified. A toJSON method does not serialize: it returns the
+value represented by the name/value pair that should be serialized,
+or undefined if nothing should be serialized. The toJSON method
+will be passed the key associated with the value, and this will be
+bound to the value
+
+For example, this would serialize Dates as ISO strings.
+
+Date.prototype.toJSON = function (key) {
+function f(n) {
+// Format integers to have at least two digits.
+return n < 10 ? '0' + n : n;
+}
+
+return this.getUTCFullYear() + '-' +
+f(this.getUTCMonth() + 1) + '-' +
+f(this.getUTCDate()) + 'T' +
+f(this.getUTCHours()) + ':' +
+f(this.getUTCMinutes()) + ':' +
+f(this.getUTCSeconds()) + 'Z';
+};
+
+You can provide an optional replacer method. It will be passed the
+key and value of each member, with this bound to the containing
+object. The value that is returned from your method will be
+serialized. If your method returns undefined, then the member will
+be excluded from the serialization.
+
+If the replacer parameter is an array of strings, then it will be
+used to select the members to be serialized. It filters the results
+such that only members with keys listed in the replacer array are
+stringified.
+
+Values that do not have JSON representations, such as undefined or
+functions, will not be serialized. Such values in objects will be
+dropped; in arrays they will be replaced with null. You can use
+a replacer function to replace those with JSON values.
+JSON.stringify(undefined) returns undefined.
+
+The optional space parameter produces a stringification of the
+value that is filled with line breaks and indentation to make it
+easier to read.
+
+If the space parameter is a non-empty string, then that string will
+be used for indentation. If the space parameter is a number, then
+the indentation will be that many spaces.
+
+Example:
+
+text = JSON.stringify(['e', {pluribus: 'unum'}]);
+// text is '["e",{"pluribus":"unum"}]'
+
+
+text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+text = JSON.stringify([new Date()], function (key, value) {
+return this[key] instanceof Date ?
+'Date(' + this[key] + ')' : value;
+});
+// text is '["Date(---current time---)"]'
+
+
+JSON.parse(text, reviver)
+This method parses a JSON text to produce an object or array.
+It can throw a SyntaxError exception.
+
+The optional reviver parameter is a function that can filter and
+transform the results. It receives each of the keys and values,
+and its return value is used instead of the original value.
+If it returns what it received, then the structure is not modified.
+If it returns undefined then the member is deleted.
+
+Example:
+
+// Parse the text. Values that look like ISO date strings will
+// be converted to Date objects.
+
+myData = JSON.parse(text, function (key, value) {
+var a;
+if (typeof value === 'string') {
+a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+if (a) {
+return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
++a[5], +a[6]));
+}
+}
+return value;
+});
+
+myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+var d;
+if (typeof value === 'string' &&
+value.slice(0, 5) === 'Date(' &&
+value.slice(-1) === ')') {
+d = new Date(value.slice(5, -1));
+if (d) {
+return d;
+}
+}
+return value;
+});
+
+
+This is a reference implementation. You are free to copy, modify, or
+redistribute.
+*/
+
+/*jslint evil: true, regexp: true */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+lastIndex, length, parse, prototype, push, replace, slice, stringify,
+test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+var JSON;
+if (!JSON) {
+ JSON = {};
+}
+
+(function () {
+ 'use strict';
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ if (typeof Date.prototype.toJSON !== 'function') {
+
+ Date.prototype.toJSON = function (key) {
+
+ return isFinite(this.valueOf())
+ ? this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z'
+ : null;
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"': '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+ // If the string contains no control characters, no quote characters, and no
+ // backslash characters, then we can safely slap some quotes around it.
+ // Otherwise we must also replace the offending characters with safe escape
+ // sequences.
+
+ escapable.lastIndex = 0;
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string'
+ ? c
+ : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+ // Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ // If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ // If we were called with a replacer function, then call the replacer to
+ // obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ // What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+ // JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+ // If the value is a boolean or null, convert it to a string. Note:
+ // typeof null does not produce 'null'. The case is included here in
+ // the remote chance that this gets fixed someday.
+
+ return String(value);
+
+ // If the type is 'object', we might be dealing with an object or an array or
+ // null.
+
+ case 'object':
+
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
+ // so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+ // Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+ // Is the value an array?
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+ // The value is an array. Stringify every element. Use null as a placeholder
+ // for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ // Join all of the elements together, separated with commas, and wrap them in
+ // brackets.
+
+ v = partial.length === 0
+ ? '[]'
+ : gap
+ ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
+ : '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+ // If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ if (typeof rep[i] === 'string') {
+ k = rep[i];
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+ // Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ // Join all of the member texts together, separated with commas,
+ // and wrap them in braces.
+
+ v = partial.length === 0
+ ? '{}'
+ : gap
+ ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
+ : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ // If the JSON object does not yet have a stringify method, give it one.
+
+ if (typeof JSON.stringify !== 'function') {
+ JSON.stringify = function (value, replacer, space) {
+
+ // The stringify method takes a value and an optional replacer, and an optional
+ // space parameter, and returns a JSON text. The replacer can be a function
+ // that can replace values, or an array of strings that will select the keys.
+ // A default replacer method can be provided. Use of the space parameter can
+ // produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+ // If the space parameter is a number, make an indent string containing that
+ // many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+ // If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+ // If there is a replacer, it must be a function or an array.
+ // Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+ // Make a fake root object containing our value under the key of ''.
+ // Return the result of stringifying the value.
+
+ return str('', { '': value });
+ };
+ }
+
+
+ // If the JSON object does not yet have a parse method, give it one.
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+
+ // The parse method takes a text and an optional reviver function, and returns
+ // a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(holder, key) {
+
+ // The walk method is used to recursively walk the resulting structure so
+ // that modifications can be made.
+
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+
+ // Parsing happens in four stages. In the first stage, we replace certain
+ // Unicode characters with escape sequences. JavaScript handles many characters
+ // incorrectly, either silently deleting them, or treating them as line endings.
+
+ text = String(text);
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+ // In the second stage, we run the text against regular expressions that look
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
+ // because they can cause invocation, and '=' because it can cause mutation.
+ // But just to be safe, we want to reject all unexpected forms.
+
+ // We split the second stage into 4 regexp operations in order to work around
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+ // replace all simple value tokens with ']' characters. Third, we delete all
+ // open brackets that follow a colon or comma or that begin the text. Finally,
+ // we look to see that the remaining characters are only whitespace or ']' or
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+ if (/^[\],:{}\s]*$/
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+ // In the third stage we use the eval function to compile the text into a
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
+ // in parens to eliminate the ambiguity.
+
+ j = eval('(' + text + ')');
+
+ // In the optional fourth stage, we recursively walk the new structure, passing
+ // each name/value pair to a reviver function for possible transformation.
+
+ return typeof reviver === 'function'
+ ? walk({ '': j }, '')
+ : j;
+ }
+
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+} ()); \ No newline at end of file
diff --git a/lib/external/json2.min.js b/lib/external/json2.min.js
new file mode 100644
index 0000000..2072357
--- /dev/null
+++ b/lib/external/json2.min.js
@@ -0,0 +1,10 @@
+/*
+http://www.JSON.org/json2.js
+*/
+var JSON;JSON||(JSON={});
+(function(){function k(a){return 10>a?"0"+a:a}function o(a){p.lastIndex=0;return p.test(a)?'"'+a.replace(p,function(a){var c=r[a];return"string"===typeof c?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function m(a,j){var c,d,h,n,g=e,f,b=j[a];b&&"object"===typeof b&&"function"===typeof b.toJSON&&(b=b.toJSON(a));"function"===typeof i&&(b=i.call(j,a,b));switch(typeof b){case "string":return o(b);case "number":return isFinite(b)?""+b:"null";case "boolean":case "null":return""+b;
+case "object":if(!b)return"null";e+=l;f=[];if("[object Array]"===Object.prototype.toString.apply(b)){n=b.length;for(c=0;c<n;c+=1)f[c]=m(c,b)||"null";h=0===f.length?"[]":e?"[\n"+e+f.join(",\n"+e)+"\n"+g+"]":"["+f.join(",")+"]";e=g;return h}if(i&&"object"===typeof i){n=i.length;for(c=0;c<n;c+=1)"string"===typeof i[c]&&(d=i[c],(h=m(d,b))&&f.push(o(d)+(e?": ":":")+h))}else for(d in b)Object.prototype.hasOwnProperty.call(b,d)&&(h=m(d,b))&&f.push(o(d)+(e?": ":":")+h);h=0===f.length?"{}":e?"{\n"+e+f.join(",\n"+
+e)+"\n"+g+"}":"{"+f.join(",")+"}";e=g;return h}}if("function"!==typeof Date.prototype.toJSON)Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+k(this.getUTCMonth()+1)+"-"+k(this.getUTCDate())+"T"+k(this.getUTCHours())+":"+k(this.getUTCMinutes())+":"+k(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()};var q=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+p=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,e,l,r={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},i;if("function"!==typeof JSON.stringify)JSON.stringify=function(a,j,c){var d;l=e="";if("number"===typeof c)for(d=0;d<c;d+=1)l+=" ";else"string"===typeof c&&(l=c);if((i=j)&&"function"!==typeof j&&("object"!==typeof j||"number"!==typeof j.length))throw Error("JSON.stringify");return m("",
+{"":a})};if("function"!==typeof JSON.parse)JSON.parse=function(a,e){function c(a,d){var g,f,b=a[d];if(b&&"object"===typeof b)for(g in b)Object.prototype.hasOwnProperty.call(b,g)&&(f=c(b,g),void 0!==f?b[g]=f:delete b[g]);return e.call(a,d,b)}var d,a=""+a;q.lastIndex=0;q.test(a)&&(a=a.replace(q,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return d=eval("("+a+")"),"function"===typeof e?c({"":d},""):d;throw new SyntaxError("JSON.parse");}})(); \ No newline at end of file
diff --git a/lib/jquery.jtable.js b/lib/jquery.jtable.js
new file mode 100644
index 0000000..32abaa3
--- /dev/null
+++ b/lib/jquery.jtable.js
@@ -0,0 +1,3562 @@
+/*
+
+jTable 1.7.2
+http://www.jtable.org
+
+---------------------------------------------------------------------------
+
+Copyright (C) 2011-2012 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+/************************************************************************
+* CORE jTable module *
+*************************************************************************/
+(function ($) {
+
+ $.widget("hik.jtable", {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Options
+ actions: {},
+ fields: {},
+ animationsEnabled: true,
+ defaultDateFormat: 'yy-mm-dd',
+ dialogShowEffect: 'fade',
+ dialogHideEffect: 'fade',
+ showCloseButton: false,
+
+ //Events
+ closeRequested: function (event, data) { },
+ formCreated: function (event, data) { },
+ formSubmitting: function (event, data) { },
+ formClosed: function (event, data) { },
+ loadingRecords: function (event, data) { },
+ recordsLoaded: function (event, data) { },
+ rowInserted: function (event, data) { },
+ rowsRemoved: function (event, data) { },
+
+ //Localization
+ messages: {
+ serverCommunicationError: 'An error occured while communicating to the server.',
+ loadingMessage: 'Loading records...',
+ noDataAvailable: 'No data available!',
+ areYouSure: 'Are you sure?',
+ save: 'Save',
+ saving: 'Saving',
+ cancel: 'Cancel',
+ error: 'Error',
+ close: 'Close',
+ cannotLoadOptionsFor: 'Can not load options for field {0}'
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$mainContainer: null, //Reference to the main container of all elements that are created by this plug-in (jQuery object)
+
+ _$table: null, //Reference to the main <table> (jQuery object)
+ _$tableBody: null, //Reference to <body> in the table (jQuery object)
+ _$tableRows: null, //Array of all <tr> in the table (except "no data" row) (jQuery object array)
+
+ _$bottomPanel: null, //Reference to the panel at the bottom of the table (jQuery object)
+
+ _$busyDiv: null, //Reference to the div that is used to block UI while busy (jQuery object)
+ _$busyMessageDiv: null, //Reference to the div that is used to show some message when UI is blocked (jQuery object)
+ _$errorDialogDiv: null, //Reference to the error dialog div (jQuery object)
+
+ _columnList: null, //Name of all data columns in the table (select column and command columns are not included) (string array)
+ _fieldList: null, //Name of all fields of a record (defined in fields option) (string array)
+ _keyField: null, //Name of the key field of a record (that is defined as 'key: true' in the fields option) (string)
+
+ _firstDataColumnOffset: 0, //Start index of first record field in table columns (some columns can be placed before first data column, such as select checkbox column) (integer)
+ _lastPostData: null, //Last posted data on load method (object)
+
+ _cache: null, //General purpose cache dictionary (object)
+
+ /************************************************************************
+ * CONSTRUCTOR AND INITIALIZATION METHODS *
+ *************************************************************************/
+
+ /* Contructor.
+ *************************************************************************/
+ _create: function () {
+
+ //Initialization
+ this._normalizeFieldsOptions();
+ this._initializeFields();
+ this._createFieldAndColumnList();
+
+ //Creating DOM elements
+ this._createMainContainer();
+ this._createTableTitle();
+ this._createTable();
+ this._createBottomPanel();
+ this._createBusyPanel();
+ this._createErrorDialogDiv();
+ this._addNoDataRow();
+ },
+
+ /* Normalizes some options for all fields (sets default values).
+ *************************************************************************/
+ _normalizeFieldsOptions: function () {
+ var self = this;
+ $.each(self.options.fields, function (fieldName, props) {
+ self._normalizeFieldOptions(fieldName, props);
+ });
+ },
+
+ /* Normalizes some options for a field (sets default values).
+ *************************************************************************/
+ _normalizeFieldOptions: function (fieldName, props) {
+ props.listClass = props.listClass || '';
+ props.inputClass = props.inputClass || '';
+ },
+
+ /* Intializes some private variables.
+ *************************************************************************/
+ _initializeFields: function () {
+ this._lastPostData = {};
+ this._$tableRows = [];
+ this._columnList = [];
+ this._fieldList = [];
+ this._cache = [];
+ },
+
+ /* Fills _fieldList, _columnList arrays and sets _keyField variable.
+ *************************************************************************/
+ _createFieldAndColumnList: function () {
+ var self = this;
+
+ $.each(self.options.fields, function (name, props) {
+
+ //Add field to the field list
+ self._fieldList.push(name);
+
+ //Check if this field is the key field
+ if (props.key == true) {
+ self._keyField = name;
+ }
+
+ //Add field to column list if it is shown in the table
+ if (props.list != false && props.type != 'hidden') {
+ self._columnList.push(name);
+ }
+ });
+ },
+
+ /* Creates the main container div.
+ *************************************************************************/
+ _createMainContainer: function () {
+ this._$mainContainer = $('<div class="jtable-main-container"></div>').appendTo(this.element);
+ },
+
+ /* Creates title of the table if a title supplied in options.
+ *************************************************************************/
+ _createTableTitle: function () {
+ var self = this;
+ if (!self.options.title) {
+ return;
+ }
+
+ //TODO: May use caption element instead of a seperated div element?
+ var $titleDiv = $('<div class="jtable-title"></div>')
+ .appendTo(self._$mainContainer);
+ $('<div class="jtable-title-text"></div>')
+ .appendTo($titleDiv)
+ .append(self.options.title);
+ if (self.options.showCloseButton) {
+ $('<button class="jtable-command-button jtable-close-button" title="' + self.options.messages.close + '"><span>' + self.options.messages.close + '</span></button>')
+ .appendTo($titleDiv)
+ .click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ self._onCloseRequested();
+ });
+ }
+ },
+
+ /* Creates table.
+ *************************************************************************/
+ _createTable: function () {
+ this._$table = $('<table class="jtable"></table>').appendTo(this._$mainContainer);
+ this._createTableHead();
+ this._createTableBody();
+ },
+
+ /* Creates header (all column headers) of the table.
+ *************************************************************************/
+ _createTableHead: function () {
+ var $thead = $('<thead></thead>').appendTo(this._$table);
+ this._addRowToTableHead($thead);
+ },
+
+ /* Adds tr element to given thead element
+ *************************************************************************/
+ _addRowToTableHead: function ($thead) {
+ var $tr = $('<tr></tr>').appendTo($thead);
+ this._addColumnsToHeaderRow($tr);
+ },
+
+ /* Adds column header cells to given tr element.
+ *************************************************************************/
+ _addColumnsToHeaderRow: function ($tr) {
+ for (var i = 0; i < this._columnList.length; i++) {
+ var fieldName = this._columnList[i];
+ var $headerCell = this._createHeaderCellForField(fieldName, this.options.fields[fieldName]);
+ $headerCell.data('fieldName', fieldName).appendTo($tr);
+ }
+ },
+
+ /* Creates a header cell for given field.
+ * Returns th jQuery object.
+ *************************************************************************/
+ _createHeaderCellForField: function (fieldName, field) {
+ field.width = field.width || '10%';
+ return $('<th class="jtable-column-header" style="width:' + field.width + '">' +
+ '<div class="jtable-column-header-container"><span class="jtable-column-header-text">' + field.title +
+ '</span></div></th>')
+ .data('fieldName', fieldName);
+ },
+
+ /* Creates an empty header cell that can be used as command column headers.
+ *************************************************************************/
+ _createEmptyCommandHeader: function () {
+ return $('<th class="jtable-command-column-header" style="width:1%"></th>');
+ },
+
+ /* Creates tbody tag and adds to the table.
+ *************************************************************************/
+ _createTableBody: function () {
+ this._$tableBody = $('<tbody></tbody>').appendTo(this._$table);
+ },
+
+ /* Creates bottom panel and adds to the page.
+ *************************************************************************/
+ _createBottomPanel: function () {
+ this._$bottomPanel = $('<div class="jtable-bottom-panel"></div>').appendTo(this._$mainContainer);
+ this._$bottomPanel.append('<div class="jtable-left-area"></div>');
+ this._$bottomPanel.append('<div class="jtable-right-area"></div>');
+ },
+
+ /* Creates a div to block UI while jTable is busy.
+ *************************************************************************/
+ _createBusyPanel: function () {
+ this._$busyMessageDiv = $('<div class="jtable-busy-message"></div>').prependTo(this._$mainContainer);
+ this._$busyDiv = $('<div class="jtable-busy-panel-background"></div>').prependTo(this._$mainContainer);
+ this._hideBusy();
+ },
+
+ /* Creates and prepares error dialog div.
+ *************************************************************************/
+ _createErrorDialogDiv: function () {
+ var self = this;
+
+ self._$errorDialogDiv = $('<div></div>').appendTo(self._$mainContainer);
+ self._$errorDialogDiv.dialog({
+ autoOpen: false,
+ show: self.options.dialogShowEffect,
+ hide: self.options.dialogHideEffect,
+ modal: true,
+ title: self.options.messages.error,
+ buttons: [{
+ text: self.options.messages.close,
+ click: function () {
+ self._$errorDialogDiv.dialog('close');
+ }
+ }]
+ });
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Loads data using AJAX call, clears table and fills with new data.
+ *************************************************************************/
+ load: function (postData, completeCallback) {
+ this._lastPostData = postData;
+ this._reloadTable(completeCallback);
+ },
+
+ /* Refreshes (re-loads) table data with last postData.
+ *************************************************************************/
+ reload: function (completeCallback) {
+ this._reloadTable(completeCallback);
+ },
+
+ /* Completely removes the table from it's container.
+ *************************************************************************/
+ destroy: function () {
+ this.element.empty();
+ $.Widget.prototype.destroy.call(this);
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* LOADING RECORDS *****************************************************/
+
+ /* Performs an AJAX call to specified URL.
+ *************************************************************************/
+ _reloadTable: function (completeCallback) {
+ var self = this;
+
+ //Disable table since it's busy
+ self._showBusy(self.options.messages.loadingMessage);
+
+ //Generate URL (with query string parameters) to load records
+ var loadUrl = self._createRecordLoadUrl();
+
+ //Load data from server
+ self._onLoadingRecords();
+ self._performAjaxCall(
+ loadUrl,
+ self._lastPostData,
+ true, //asynchronous
+ function (data) { //success
+ self._hideBusy();
+
+ //Show the error message if server returns error
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ return;
+ }
+
+ //Re-generate table rows
+ self._removeAllRows('reloading');
+ self._addRecordsToTable(data.Records);
+
+ self._onRecordsLoaded(data);
+
+ //Call complete callback
+ if (completeCallback) {
+ completeCallback();
+ }
+ },
+ function () {
+ self._hideBusy();
+ self._showError(self.options.messages.serverCommunicationError);
+ });
+ },
+
+ /* Creates URL to load records.
+ *************************************************************************/
+ _createRecordLoadUrl: function () {
+ return this.options.actions.listAction;
+ },
+
+ /* TABLE MANIPULATION METHODS *******************************************/
+
+ /* Creates a row from given record
+ *************************************************************************/
+ _createRowFromRecord: function (record) {
+ var $newTableRow = $('<tr></tr>').data('record', record);
+ this._addCellsToRowUsingRecord($newTableRow);
+ return $newTableRow;
+ },
+
+ /* Adds all cells to given row.
+ *************************************************************************/
+ _addCellsToRowUsingRecord: function ($row) {
+ for (var i = 0; i < this._columnList.length; i++) {
+ this._createCellForRecordField($row.data('record'), this._columnList[i]).appendTo($row);
+ }
+ },
+
+ /* Create a cell for given field.
+ *************************************************************************/
+ _createCellForRecordField: function (record, fieldName) {
+ return $('<td class="' + this.options.fields[fieldName].listClass + '"></td>')
+ .append((this._getDisplayTextForRecordField(record, fieldName) || ''));
+ },
+
+ /* Adds a list of records to the table.
+ *************************************************************************/
+ _addRecordsToTable: function (records) {
+ var self = this;
+
+ $.each(records, function (index, record) {
+ self._addRowToTable(self._createRowFromRecord(record));
+ });
+
+ self._refreshRowStyles();
+ },
+
+ /* Adds a single row to a specific index of the table.
+ * If no index specified, adds to end of the table.
+ *************************************************************************/
+ _addRowToTable: function ($tableRow, index, isNewRow, animationsEnabled) {
+ var self = this;
+
+ //set default value
+ if (isNewRow != true) {
+ isNewRow = false;
+ }
+
+ if (animationsEnabled != false) {
+ animationsEnabled = true;
+ }
+
+ //Remove 'no data' row if this is first row
+ if (this._$tableRows.length <= 0) {
+ this._removeNoDataRow();
+ }
+
+ //Add new row to the table according to it's index
+ index = this._normalizeNumber(index, 0, this._$tableRows.length, this._$tableRows.length);
+ if (index == this._$tableRows.length) {
+ //add as last row
+ this._$tableBody.append($tableRow);
+ this._$tableRows.push($tableRow);
+ } else if (index == 0) {
+ //add as first row
+ this._$tableBody.prepend($tableRow);
+ this._$tableRows.unshift($tableRow);
+ } else {
+ //insert to specified index
+ this._$tableRows[index - 1].after($tableRow);
+ this._$tableRows.splice(index, 0, $tableRow);
+ }
+
+ this._onRowInserted($tableRow, isNewRow);
+
+ //Show animation if needed
+ if (isNewRow == true) {
+ self._refreshRowStyles();
+ if (self.options.animationsEnabled && animationsEnabled) {
+ self._showNewRowAnimation($tableRow);
+ }
+ }
+ },
+
+ /* Shows created animation for a table row
+ *************************************************************************/
+ _showNewRowAnimation: function ($tableRow) {
+ $tableRow.addClass('jtable-row-created', 'slow', '', function () {
+ $tableRow.removeClass('jtable-row-created', 5000);
+ });
+ },
+
+ /* Removes a row or rows (jQuery selection) from table.
+ *************************************************************************/
+ _removeRowsFromTable: function ($rows, reason) {
+ var self = this;
+
+ //Check if any row specified
+ if ($rows.length <= 0) {
+ return;
+ }
+
+ //remove from DOM
+ $rows.remove();
+
+ //remove from _$tableRows array
+ $rows.each(function () {
+ self._$tableRows.splice(self._findRowIndex($(this)), 1);
+ });
+
+ self._onRowsRemoved($rows, reason);
+
+ //Add 'no data' row if all rows removed from table
+ if (self._$tableRows.length == 0) {
+ self._addNoDataRow();
+ }
+
+ self._refreshRowStyles();
+ },
+
+ /* Finds index of a row in table.
+ *************************************************************************/
+ _findRowIndex: function ($row) {
+ return this._findIndexInArray($row, this._$tableRows, function ($row1, $row2) {
+ return $row1.data('record') == $row2.data('record');
+ });
+ },
+
+ /* Removes all rows in the table and adds 'no data' row.
+ *************************************************************************/
+ _removeAllRows: function (reason) {
+ //If no rows does exists, do nothing
+ if (this._$tableRows.length <= 0) {
+ return;
+ }
+
+ //Select all rows (to pass it on raising _onRowsRemoved event)
+ var $rows = this._$tableBody.find('tr');
+
+ //Remove all rows from DOM and the _$tableRows array
+ this._$tableBody.empty();
+ this._$tableRows = [];
+
+ this._onRowsRemoved($rows, reason);
+
+ //Add 'no data' row since we removed all rows
+ this._addNoDataRow();
+ },
+
+ /* Adds "no data available" row to the table.
+ *************************************************************************/
+ _addNoDataRow: function () {
+ var totalColumnCount = this._$table.find('thead th').length;
+ $('<tr class="jtable-no-data-row"></tr>')
+ .append('<td colspan="' + totalColumnCount + '">' + this.options.messages.noDataAvailable + '</td>')
+ .appendTo(this._$tableBody);
+ },
+
+ /* Removes "no data available" row from the table.
+ *************************************************************************/
+ _removeNoDataRow: function () {
+ this._$tableBody.find('.jtable-no-data-row').remove();
+ },
+
+ /* Refreshes styles of all rows in the table
+ *************************************************************************/
+ _refreshRowStyles: function () {
+ for (var i = 0; i < this._$tableRows.length; i++) {
+ if (i % 2 == 0) {
+ this._$tableRows[i].addClass('jtable-row-even');
+ } else {
+ this._$tableRows[i].removeClass('jtable-row-even');
+ }
+ }
+ },
+
+ /* RENDERING FIELD VALUES ***********************************************/
+
+ /* Gets text for a field of a record according to it's type.
+ *************************************************************************/
+ _getDisplayTextForRecordField: function (record, fieldName) {
+ var field = this.options.fields[fieldName];
+ var fieldValue = record[fieldName];
+
+ if (field.display) {
+ return field.display({ record: record });
+ }
+
+ if (field.type == 'date') {
+ return this._getDisplayTextForDateRecordField(field, fieldValue);
+ } else if (field.type == 'checkbox') {
+ return this._getCheckBoxTextForFieldByValue(fieldName, fieldValue);
+ } else if (field.options) {
+ var x = this._getOptionsWithCaching(fieldName)[fieldValue];
+ return x;
+ } else {
+ return fieldValue;
+ }
+ },
+
+ /* Gets text for a date field.
+ *************************************************************************/
+ _getDisplayTextForDateRecordField: function (field, fieldValue) {
+ if (!fieldValue) {
+ return '';
+ }
+
+ var displayFormat = field.displayFormat || this.options.defaultDateFormat;
+ var date = this._parseDate(fieldValue);
+ return $.datepicker.formatDate(displayFormat, date);
+ },
+
+ /* Parses given date string to a javascript Date object.
+ * Given string must be formatted one of the samples shown below:
+ * /Date(1320259705710)/
+ * 2011-01-01 20:32:42 (YYYY-MM-DD HH:MM:SS)
+ * 2011-01-01 (YYYY-MM-DD)
+ *************************************************************************/
+ _parseDate: function (dateString) {
+ if (dateString.indexOf('Date') >= 0) { //Format: /Date(1320259705710)/
+ return new Date(parseInt(dateString.substr(6)));
+ } else if (dateString.length == 10) { //Format: 2011-01-01
+ return new Date(parseInt(dateString.substr(0, 4)), parseInt(dateString.substr(5, 2)) - 1, parseInt(dateString.substr(8, 2)));
+ } else if (dateString.length == 19) { //Format: 2011-01-01 20:32:42
+ return new Date(parseInt(dateString.substr(0, 4)), parseInt(dateString.substr(5, 2)) - 1, parseInt(dateString.substr(8, 2)), parseInt(dateString.substr(11, 2)), parseInt(dateString.substr(14, 2)), parseInt(dateString.substr(17, 2)));
+ } else {
+ this._logWarn('Given date is no properly formatted: ' + dateString);
+ return new Date(); //Default value!
+ }
+ },
+
+ /* ERROR DIALOG *********************************************************/
+
+ /* Shows error message dialog with given message.
+ *************************************************************************/
+ _showError: function (message) {
+ this._$errorDialogDiv.html(message).dialog('open');
+ },
+
+ /* BUSY PANEL ***********************************************************/
+
+ /* Shows busy indicator and blocks table UI.
+ *************************************************************************/
+ _showBusy: function (message) {
+ if (!this._$busyMessageDiv.is(':visible')) {
+ this._$busyDiv.width(this._$mainContainer.width());
+ this._$busyDiv.height(this._$mainContainer.height());
+ this._$busyDiv.show();
+ this._$busyMessageDiv.show();
+ }
+
+ this._$busyMessageDiv.html(message);
+ },
+
+ /* Hides busy indicator and unblocks table UI.
+ *************************************************************************/
+ _hideBusy: function () {
+ this._$busyDiv.hide();
+ this._$busyMessageDiv.html('').hide();
+ },
+
+ /* Returns true if jTable is busy.
+ *************************************************************************/
+ _isBusy: function () {
+ return this._$busyMessageDiv.is(':visible');
+ },
+
+ /* COMMON METHODS *******************************************************/
+
+ /* Performs an AJAX call to specified URL.
+ *************************************************************************/
+ _performAjaxCall: function (url, postData, async, success, error) {
+ $.ajax({
+ url: url,
+ type: 'POST',
+ dataType: 'json',
+ data: postData,
+ async: async,
+ success: function (data) {
+ success(data);
+ },
+ error: function () {
+ error();
+ }
+ });
+ },
+
+ /* Gets a jQuery row object according to given record key
+ *************************************************************************/
+ getRowByKey: function (key) {
+ for (var i = 0; i < this._$tableRows.length; i++) {
+ if (key == this._$tableRows[i].data('record')[this._keyField]) {
+ return this._$tableRows[i];
+ }
+ }
+
+ return null;
+ },
+
+ /************************************************************************
+ * EVENT RAISING METHODS *
+ *************************************************************************/
+
+ _onLoadingRecords: function () {
+ this._trigger("loadingRecords", null, {});
+ },
+
+ _onRecordsLoaded: function (data) {
+ this._trigger("recordsLoaded", null, { records: data.Records, serverResponse: data });
+ },
+
+ _onRowInserted: function ($row, isNewRow) {
+ this._trigger("rowInserted", null, { row: $row, record: $row.data('record'), isNewRow: isNewRow });
+ },
+
+ _onRowsRemoved: function ($rows, reason) {
+ this._trigger("rowsRemoved", null, { rows: $rows, reason: reason });
+ },
+
+ _onCloseRequested: function () {
+ this._trigger("closeRequested", null, {});
+ }
+
+ });
+
+} (jQuery));
+
+/************************************************************************
+* Some UTULITY methods used by jTable *
+*************************************************************************/
+(function ($) {
+
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /* Gets property value of an object recursively.
+ *************************************************************************/
+ _getPropertyOfObject: function (obj, propName) {
+ if (propName.indexOf('.') < 0) {
+ return obj[propName];
+ } else {
+ var preDot = propName.substring(0, propName.indexOf('.'));
+ var postDot = propName.substring(propName.indexOf('.') + 1);
+ return this._getPropertyOfObject(obj[preDot], postDot);
+ }
+ },
+
+ /* Sets property value of an object recursively.
+ *************************************************************************/
+ _setPropertyOfObject: function (obj, propName, value) {
+ var self = this;
+
+ if (propName.indexOf('.') < 0) {
+ obj[propName] = value;
+ } else {
+ var preDot = propName.substring(0, propName.indexOf('.'));
+ var postDot = propName.substring(propName.indexOf('.') + 1);
+ self._setPropertyOfObject(obj[preDot], postDot, value);
+ }
+ },
+
+ /* Inserts a value to an array if it does not exists in the array.
+ *************************************************************************/
+ _insertToArrayIfDoesNotExists: function (array, value) {
+ if ($.inArray(value, array) < 0) {
+ array.push(value);
+ }
+ },
+
+ /* Finds index of an element in an array according to given comparision function
+ *************************************************************************/
+ _findIndexInArray: function (value, array, compareFunc) {
+
+ //If not defined, use default comparision
+ if (!compareFunc) {
+ compareFunc = function (a, b) {
+ return a == b;
+ };
+ }
+
+ for (var i = 0; i < array.length; i++) {
+ if (compareFunc(value, array[i])) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /* Normalizes a number between given bounds or sets to a defaultValue
+ * if it is undefined
+ *************************************************************************/
+ _normalizeNumber: function (number, min, max, defaultValue) {
+ if (number == undefined || number == null) {
+ return defaultValue;
+ }
+
+ if (number < min) {
+ return min;
+ }
+
+ if (number > max) {
+ return max;
+ }
+
+ return number;
+ },
+
+ /* Formats a string just like string.format in c#.
+ * Example:
+ * _formatString('Hello {0}','Halil') = 'Hello Halil'
+ *************************************************************************/
+ _formatString: function () {
+ if (arguments.length == 0) {
+ return null;
+ }
+
+ var str = arguments[0];
+ for (var i = 1; i < arguments.length; i++) {
+ var placeHolder = '{' + (i - 1) + '}';
+ str = str.replace(placeHolder, arguments[i]);
+ }
+
+ return str;
+ },
+
+ //Logging methods ////////////////////////////////////////////////////////
+
+ _logDebug: function (text) {
+ if (!window.console) {
+ return;
+ }
+
+ console.log('jTable DEBUG: ' + text);
+ },
+
+ _logInfo: function (text) {
+ if (!window.console) {
+ return;
+ }
+
+ console.log('jTable INFO: ' + text);
+ },
+
+ _logWarn: function (text) {
+ if (!window.console) {
+ return;
+ }
+
+ console.log('jTable WARNING: ' + text);
+ },
+
+ _logError: function (text) {
+ if (!window.console) {
+ return;
+ }
+
+ console.log('jTable ERROR: ' + text);
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* FORMS extension for jTable (base for edit/create forms) *
+*************************************************************************/
+(function ($) {
+
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Submits a form asynchronously using AJAX.
+ * This method is needed, since form submitting logic can be overrided
+ * by extensions.
+ *************************************************************************/
+ _submitFormUsingAjax: function (url, formData, success, error) {
+ this._performAjaxCall(url, formData, true, success, error);
+ },
+
+ /* Creates label for an input element.
+ *************************************************************************/
+ _createInputLabelForRecordField: function (fieldName) {
+ //TODO: May create label tag instead of a div.
+ return $('<div class="jtable-input-label">' + this.options.fields[fieldName].title + '</div>');
+ },
+
+ /* Creates an input element according to field type.
+ *************************************************************************/
+ _createInputForRecordField: function (fieldName, value, record) {
+
+ //Get the field
+ var field = this.options.fields[fieldName];
+
+ //If value if undefined, use defaultValue of the field
+ if (value == undefined) {
+ value = field.defaultValue;
+ }
+
+ //Use custom function if supplied
+ if (field.input) {
+ var $input = $(field.input({ value: value, record: record }));
+
+ //Add id attribute if does not exists
+ if (!$input.attr('id')) {
+ $input.attr('id', 'Edit-' + fieldName);
+ }
+
+ return $input;
+ }
+
+ //Create input according to field type
+ if (field.type == 'date') {
+ return this._createDateInputForField(field, fieldName, value);
+ } else if (field.type == 'textarea') {
+ return this._createTextAreaForField(field, fieldName, value);
+ } else if (field.type == 'password') {
+ return this._createPasswordInputForField(field, fieldName, value);
+ } else if (field.type == 'checkbox') {
+ return this._createCheckboxForField(field, fieldName, value);
+ } else if (field.options) {
+ if (field.type == 'radiobutton') {
+ return this._createRadioButtonListForField(field, fieldName, value);
+ } else {
+ return this._createDropDownListForField(field, fieldName, value);
+ }
+ } else {
+ return this._createTextInputForField(field, fieldName, value);
+ }
+ },
+
+ //Creates a hidden input element with given name and value.
+ _createInputForHidden: function (fieldName, value) {
+ if (value == undefined || value == null) {
+ value = "";
+ }
+
+ return $('<input type="hidden" value="' + value + '" name="' + fieldName + '" id="Edit-' + fieldName + '"></input>');
+ },
+
+ /* Creates a date input for a field.
+ *************************************************************************/
+ _createDateInputForField: function (field, fieldName, value) {
+ var $input = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input>');
+ var displayFormat = field.displayFormat || this.options.defaultDateFormat;
+ $input.datepicker({ dateFormat: displayFormat });
+ return $('<div class="jtable-input jtable-date-input"></div>').append($input);
+ },
+
+ /* Creates a standart textbox for a field.
+ *************************************************************************/
+ _createTextAreaForField: function (field, fieldName, value) {
+ return $('<div class="jtable-input jtable-textarea-input"><textarea class="' + field.inputClass + '" id="Edit-' + fieldName + '" name="' + fieldName + '">' + (value || '') + '</textarea></div>');
+ },
+
+ /* Creates a standart textbox for a field.
+ *************************************************************************/
+ _createTextInputForField: function (field, fieldName, value) {
+ return $('<div class="jtable-input jtable-text-input"><input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input></div>');
+ },
+
+ /* Creates a password input for a field.
+ *************************************************************************/
+ _createPasswordInputForField: function (field, fieldName, value) {
+ return $('<div class="jtable-input jtable-password-input"><input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="password"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input></div>');
+ },
+
+ /* Creates a checkboxfor a field.
+ *************************************************************************/
+ _createCheckboxForField: function (field, fieldName, value) {
+ var self = this;
+
+ //If value is undefined, get unchecked state's value
+ if (value == undefined) {
+ value = value || self._getCheckBoxPropertiesForFieldByState(fieldName, false).Value;
+ }
+
+ //Create a container div
+ var $containerDiv = $('<div class="jtable-input jtable-checkbox-input"></div>');
+
+ //Create checkbox and check if needed
+ var $checkBox = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="checkbox" name="' + fieldName + '" value="' + value + '" />').appendTo($containerDiv);
+
+ //Create display text of checkbox for current state
+ var $textSpan = $('<span>' + (field.formText || self._getCheckBoxTextForFieldByValue(fieldName, value)) + '</span>').appendTo($containerDiv);
+
+ //Check the checkbox if it's value is checked-value
+ if (self._getIsCheckBoxSelectedForFieldByValue(fieldName, value)) {
+ $checkBox.attr('checked', 'checked');
+ }
+
+ //This method sets checkbox's value and text according to state of the checkbox
+ var refreshCheckBoxValueAndText = function () {
+ var checkboxProps = self._getCheckBoxPropertiesForFieldByState(fieldName, $checkBox.is(':checked'));
+ $checkBox.attr('value', checkboxProps.Value);
+ $textSpan.html(field.formText || checkboxProps.DisplayText);
+ };
+
+ //Register to click event to change display text when state of checkbox is changed.
+ $checkBox.click(function () {
+ refreshCheckBoxValueAndText();
+ });
+
+ //Change checkbox state when clicked to text
+ if (field.setOnTextClick != false) {
+ $textSpan.addClass('jtable-option-text-clickable');
+ $textSpan.click(function () {
+ if ($checkBox.is(':checked')) {
+ $checkBox.attr('checked', false);
+ } else {
+ $checkBox.attr('checked', true);
+ }
+
+ refreshCheckBoxValueAndText();
+ });
+ }
+
+ return $containerDiv;
+ },
+
+ /* Creates a drop down list (combobox) input element for a field.
+ *************************************************************************/
+ _createDropDownListForField: function (field, fieldName, value) {
+ //Create a container div
+ var $containerDiv = $('<div class="jtable-input jtable-dropdown-input"></div>');
+
+ //Create select element
+ var $select = $('<select class="' + field.inputClass + '" id="Edit-' + fieldName + '" name=' + fieldName + '></select>').appendTo($containerDiv);
+
+ //add options
+ var options = this._getOptionsWithCaching(fieldName);
+ $.each(options, function (propName, propValue) {
+ $select.append('<option value="' + propName + '"' + (propName == value ? ' selected="selected"' : '') + '>' + propValue + '</option>');
+ });
+
+ return $containerDiv;
+ },
+ /* Creates a radio button list for a field.
+ *************************************************************************/
+ _createRadioButtonListForField: function (field, fieldName, value) {
+ //Create a container div
+ var $containerDiv = $('<div class="jtable-input jtable-radiobuttonlist-input"></div>');
+
+ //create radio buttons
+ var options = this._getOptionsWithCaching(fieldName);
+ var radioButtonIndex = 0;
+ $.each(options, function (propName, propValue) {
+ var $radioButtonDiv = $('<div class="jtable-radio-input"></div>').appendTo($containerDiv);
+ var $radioButton = $('<input type="radio" id="Edit-' + fieldName + (radioButtonIndex++) + '" class="' + field.inputClass + '" name="' + fieldName + '" value="' + propName + '"' + (propName == value ? ' checked="true"' : '') + ' />').appendTo($radioButtonDiv);
+ var $textSpan = $('<span>' + propValue + '</span>').appendTo($radioButtonDiv);
+
+ //Change checkbox state when clicked to text
+ if (field.setOnTextClick != false) {
+ $textSpan.addClass('jtable-option-text-clickable');
+ $textSpan.click(function () {
+ if (!$radioButton.is(':checked')) {
+ $radioButton.attr('checked', true);
+ }
+ });
+ }
+ });
+
+ return $containerDiv;
+ },
+
+ /* Gets display text for a checkbox field.
+ *************************************************************************/
+ _getCheckBoxTextForFieldByValue: function (fieldName, value) {
+ return this.options.fields[fieldName].values[value];
+ },
+
+ /* Returns true if given field's value must be checked state.
+ *************************************************************************/
+ _getIsCheckBoxSelectedForFieldByValue: function (fieldName, value) {
+ return (this._createCheckBoxStateArrayForFieldWithCaching(fieldName)[1].Value.toString() == value.toString());
+ },
+
+ /* Gets an object for a checkbox field that has Value and DisplayText
+ * properties.
+ *************************************************************************/
+ _getCheckBoxPropertiesForFieldByState: function (fieldName, checked) {
+ return this._createCheckBoxStateArrayForFieldWithCaching(fieldName)[(checked ? 1 : 0)];
+ },
+
+ /* Calls _createCheckBoxStateArrayForField with caching.
+ *************************************************************************/
+ _createCheckBoxStateArrayForFieldWithCaching: function (fieldName) {
+ var cacheKey = 'checkbox_' + fieldName;
+ if (!this._cache[cacheKey]) {
+
+ this._cache[cacheKey] = this._createCheckBoxStateArrayForField(fieldName);
+ }
+
+ return this._cache[cacheKey];
+ },
+
+ /* Creates a two element array of objects for states of a checkbox field.
+ * First element for unchecked state, second for checked state.
+ * Each object has two properties: Value and DisplayText
+ *************************************************************************/
+ _createCheckBoxStateArrayForField: function (fieldName) {
+ var stateArray = [];
+ var currentIndex = 0;
+ $.each(this.options.fields[fieldName].values, function (propName, propValue) {
+ if (currentIndex++ < 2) {
+ stateArray.push({ 'Value': propName, 'DisplayText': propValue });
+ }
+ });
+
+ return stateArray;
+ },
+
+ /* Gets options from cache if exists, else downloads and caches.
+ *************************************************************************/
+ _getOptionsWithCaching: function (fieldName) {
+ var cacheKey = 'options_' + fieldName;
+ if (!this._cache[cacheKey]) {
+ var optionsSource = this.options.fields[fieldName].options;
+ //Build options according to it's source type
+ if (typeof optionsSource == 'string') {
+ //It is an Url to rownload options
+ this._cache[cacheKey] = this._downloadOptions(fieldName, optionsSource);
+ } else if (jQuery.isArray(optionsSource)) {
+ //It is an array of options
+ this._cache[cacheKey] = this._buildOptionsFromArray(optionsSource);
+ } else {
+ //It is an object that it's properties are options, so use directly this object
+ this._cache[cacheKey] = optionsSource;
+ }
+ }
+
+ return this._cache[cacheKey];
+ },
+
+ /* Download options for a field from server.
+ *************************************************************************/
+ _downloadOptions: function (fieldName, url) {
+ var self = this;
+
+ var options = {};
+ self._performAjaxCall(
+ url,
+ undefined,
+ false,
+ function (data) { //success
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ return;
+ }
+
+ //Get options from incoming data
+ for (var i = 0; i < data.Options.length; i++) {
+ options[data.Options[i].Value] = data.Options[i].DisplayText;
+ }
+ },
+ function () {
+ var errMessage = self._formatString(self.options.messages.cannotLoadOptionsFor, fieldName);
+ self._showError(errMessage);
+ });
+
+ return options;
+ },
+
+ /* Creates an options object (that it's property is value, value is displaytext)
+ * from a simple array.
+ *************************************************************************/
+ _buildOptionsFromArray: function (optionsArray) {
+ var options = {};
+ for (var i = 0; i < optionsArray.length; i++) {
+ options[optionsArray[i]] = optionsArray[i];
+ }
+
+ return options;
+ },
+
+ /* Sets enabled/disabled state of a dialog button.
+ *************************************************************************/
+ _setEnabledOfDialogButton: function ($button, enabled, buttonText) {
+ if (!$button) {
+ return;
+ }
+
+ if (enabled != false) {
+ $button.removeAttr('disabled').removeClass('ui-state-disabled');
+ } else {
+ $button.attr('disabled', 'disabled').addClass('ui-state-disabled');
+ }
+
+ if (buttonText) {
+ $button.find('span').text(buttonText);
+ }
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* CREATE RECORD extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Events
+ recordAdded: function (event, data) { },
+
+ //Localization
+ messages: {
+ addNewRecord: '+ Add new record'
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$addRecordDiv: null, //Reference to the adding new record dialog div (jQuery object)
+
+ /************************************************************************
+ * CONSTRUCTOR *
+ *************************************************************************/
+
+ /* Overrides base method to do create-specific constructions.
+ *************************************************************************/
+ _create: function () {
+ base._create.apply(this, arguments);
+ this._createAddRecordDialogDiv();
+ },
+
+ /* Creates and prepares add new record dialog div
+ *************************************************************************/
+ _createAddRecordDialogDiv: function () {
+ var self = this;
+
+ //Check if createAction is supplied
+ if (!self.options.actions.createAction) {
+ return;
+ }
+
+ //Create a div for dialog and add to container element
+ self._$addRecordDiv = $('<div></div>').appendTo(self._$mainContainer);
+
+ //Prepare dialog
+ self._$addRecordDiv.dialog({
+ autoOpen: false,
+ show: self.options.dialogShowEffect,
+ hide: self.options.dialogHideEffect,
+ width: 'auto',
+ minWidth: '300',
+ modal: true,
+ title: self.options.messages.addNewRecord,
+ buttons:
+ [{ //Cancel button
+ text: self.options.messages.cancel,
+ click: function () {
+ self._$addRecordDiv.dialog('close');
+ }
+ }, { //Save button
+ id: 'AddRecordDialogSaveButton',
+ text: self.options.messages.save,
+ click: function () {
+ var $saveButton = $('#AddRecordDialogSaveButton');
+ var $addRecordForm = self._$addRecordDiv.find('form');
+
+ if (self._trigger("formSubmitting", null, { form: $addRecordForm, formType: 'create' }) != false) {
+ self._setEnabledOfDialogButton($saveButton, false, self.options.messages.saving);
+ self._saveAddRecordForm($addRecordForm, $saveButton);
+ }
+ }
+ }],
+ close: function () {
+ var $addRecordForm = self._$addRecordDiv.find('form').first();
+ var $saveButton = $('#AddRecordDialogSaveButton');
+ self._trigger("formClosed", null, { form: $addRecordForm, formType: 'create' });
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ $addRecordForm.remove();
+ }
+ });
+
+ //If not 'add record button' supplied, create a new one.
+ if (!self.options.addRecordButton) {
+ self.options.addRecordButton = self._createAddRecordButton();
+ }
+
+ //Bind click event to show dialog form
+ self.options.addRecordButton.click(function (e) {
+ e.preventDefault();
+ self._showAddRecordForm();
+ });
+ },
+
+ /* Creates and returns 'add new record' button/link.
+ *************************************************************************/
+ _createAddRecordButton: function () {
+ return $('<span class="jtable-add-record"><a href="#">' + this.options.messages.addNewRecord + '</a></span>').appendTo(this._$bottomPanel.find('.jtable-right-area'));
+ //return $('<button class="jtable-command-button jtable-add-command-button" title="' + this.options.messages.addNewRecord + '"><span>' + this.options.messages.addNewRecord + '</span></button>').appendTo(this._$bottomPanel.find('.jtable-right-area'));
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Shows add new record dialog form.
+ *************************************************************************/
+ showCreateForm: function () {
+ this._showAddRecordForm();
+ },
+
+ /* Adds a new record to the table (optionally to the server also)
+ *************************************************************************/
+ addRecord: function (options) {
+ var self = this;
+ options = $.extend({
+ clientOnly: false,
+ animationsEnabled: self.options.animationsEnabled,
+ url: self.options.actions.createAction,
+ success: function () { },
+ error: function () { }
+ }, options);
+
+ if (!options.record) {
+ self._logWarn('options parameter in addRecord method must contain a record property.');
+ return;
+ }
+
+ if (options.clientOnly) {
+ self._addRowToTable(self._createRowFromRecord(options.record), null, true, options.animationsEnabled);
+ options.success();
+ return;
+ }
+
+ self._submitFormUsingAjax(
+ options.url,
+ $.param(options.record),
+ function (data) {
+ //Check for errors
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ options.error(data);
+ return;
+ }
+
+ self._onRecordAdded(data);
+ self._addRowToTable(self._createRowFromRecord(data.Record), null, true, options.animationsEnabled);
+ options.success(data);
+ },
+ function () {
+ self._showError(self.options.messages.serverCommunicationError);
+ options.error();
+ });
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Shows add new record dialog form.
+ *************************************************************************/
+ _showAddRecordForm: function () {
+ var self = this;
+
+ //Create add new record form
+ var $addRecordForm = $('<form id="jtable-create-form" class="jtable-dialog-form jtable-create-form" action="' + self.options.actions.createAction + '" method="POST"></form>');
+
+ //Create input elements
+ for (var i = 0; i < self._fieldList.length; i++) {
+
+ //Do not create input for fields that are not creatable
+ if (self.options.fields[self._fieldList[i]].create == false) {
+ continue;
+ }
+
+ if (self.options.fields[self._fieldList[i]].type == 'hidden') {
+ $addRecordForm.append(self._createInputForHidden(self._fieldList[i], self.options.fields[self._fieldList[i]].defaultValue));
+ continue;
+ }
+
+ //Create a container div for this input field and add to form
+ var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($addRecordForm);
+
+ //Create a label for input
+ $fieldContainer.append(self._createInputLabelForRecordField(self._fieldList[i]));
+
+ //Create input element
+ $fieldContainer.append(self._createInputForRecordField(self._fieldList[i]));
+ }
+
+ //Open the form
+ self._$addRecordDiv.append($addRecordForm).dialog('open');
+ self._trigger("formCreated", null, { form: $addRecordForm, formType: 'create' });
+ },
+
+ /* Saves new added record to the server and updates table.
+ *************************************************************************/
+ _saveAddRecordForm: function ($addRecordForm, $saveButton) {
+ var self = this;
+
+ //Make an Ajax call to update record
+ $addRecordForm.data('submitting', true);
+
+ self._submitFormUsingAjax(
+ $addRecordForm.attr('action'),
+ $addRecordForm.serialize(),
+ function (data) {
+ //Check for errors
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ return;
+ }
+
+ self._onRecordAdded(data);
+ self._addRowToTable(self._createRowFromRecord(data.Record), null, true);
+ self._$addRecordDiv.dialog("close");
+ },
+ function () {
+ self._showError(self.options.messages.serverCommunicationError);
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ });
+ },
+
+ _onRecordAdded: function (data) {
+ this._trigger("recordAdded", null, { record: data.Record, serverResponse: data });
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* EDIT RECORD extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
+ _addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Events
+ recordUpdated: function (event, data) { },
+ rowUpdated: function (event, data) { },
+
+ //Localization
+ messages: {
+ editRecord: 'Edit Record'
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$editDiv: null, //Reference to the editing dialog div (jQuery object)
+ _$editingRow: null, //Reference to currently editing row (jQuery object)
+
+ /************************************************************************
+ * CONSTRUCTOR AND INITIALIZATION METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to do editing-specific constructions.
+ *************************************************************************/
+ _create: function () {
+ base._create.apply(this, arguments);
+ this._createEditDialogDiv();
+ },
+
+ /* Creates and prepares edit dialog div
+ *************************************************************************/
+ _createEditDialogDiv: function () {
+ var self = this;
+
+ //Create a div for dialog and add to container element
+ self._$editDiv = $('<div></div>').appendTo(self._$mainContainer);
+
+ //Prepare dialog
+ self._$editDiv.dialog({
+ autoOpen: false,
+ show: self.options.dialogShowEffect,
+ hide: self.options.dialogHideEffect,
+ width: 'auto',
+ minWidth: '300',
+ modal: true,
+ title: self.options.messages.editRecord,
+ buttons:
+ [{ //cancel button
+ text: self.options.messages.cancel,
+ click: function () {
+ self._$editDiv.dialog('close');
+ }
+ }, { //save button
+ id: 'EditDialogSaveButton',
+ text: self.options.messages.save,
+ click: function () {
+ var $saveButton = self._$editDiv.find('#EditDialogSaveButton');
+ var $editForm = self._$editDiv.find('form');
+ if (self._trigger("formSubmitting", null, { form: $editForm, formType: 'edit' }) != false) {
+ self._setEnabledOfDialogButton($saveButton, false, self.options.messages.saving);
+ self._saveEditForm($editForm, $saveButton);
+ }
+ }
+ }],
+ close: function () {
+ var $editForm = self._$editDiv.find('form:first');
+ var $saveButton = $('#EditDialogSaveButton');
+ self._trigger("formClosed", null, { form: $editForm, formType: 'edit' });
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ $editForm.remove();
+ }
+ });
+ },
+
+ /************************************************************************
+ * PUNLIC METHODS *
+ *************************************************************************/
+
+ /* Updates a record on the table (optionally on the server also)
+ *************************************************************************/
+ updateRecord: function (options) {
+ var self = this;
+ options = $.extend({
+ clientOnly: false,
+ animationsEnabled: self.options.animationsEnabled,
+ url: self.options.actions.updateAction,
+ success: function () { },
+ error: function () { }
+ }, options);
+
+ var key = options.record[self._keyField];
+ if (!options.record || !key) {
+ self._logWarn('options parameter in updateRecord method must contain a record that contains the key field property.');
+ return;
+ }
+
+ var $updatingRow = self.getRowByKey(key);
+ if ($updatingRow == null) {
+ self._logWarn('Can not found any row by key: ' + key);
+ return;
+ }
+
+ if (options.clientOnly) {
+ $.extend($updatingRow.data('record'), options.record);
+ self._updateRowTexts($updatingRow);
+
+ self._onRecordUpdated($updatingRow, null);
+
+ if (options.animationsEnabled) {
+ self._showUpdateAnimationForRow($updatingRow);
+ }
+
+ options.success();
+ return;
+ }
+
+ self._submitFormUsingAjax(
+ options.url,
+ $.param(options.record),
+ function (data) {
+ //Check for errors
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ options.error(data);
+ return;
+ }
+
+ $.extend($updatingRow.data('record'), options.record);
+ self._updateRowTexts($updatingRow);
+
+ self._onRecordUpdated($updatingRow, data);
+
+ if (options.animationsEnabled) {
+ self._showUpdateAnimationForRow($updatingRow);
+ }
+
+ options.success(data);
+ },
+ function () {
+ self._showError(self.options.messages.serverCommunicationError);
+ options.error();
+ });
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to add a 'editing column cell' to header row.
+ *************************************************************************/
+ _addColumnsToHeaderRow: function ($tr) {
+ base._addColumnsToHeaderRow.apply(this, arguments);
+ if (this.options.actions.updateAction != undefined) {
+ $tr.append(this._createEmptyCommandHeader());
+ }
+ },
+
+ /* Overrides base method to add a 'edit command cell' to a row.
+ *************************************************************************/
+ _addCellsToRowUsingRecord: function ($row) {
+ var self = this;
+ base._addCellsToRowUsingRecord.apply(this, arguments);
+ if (self.options.actions.updateAction != undefined) {
+ var $editCell = $('<td class="jtable-command-column"></td>').appendTo($row);
+ $('<button class="jtable-command-button jtable-edit-command-button" title="' + self.options.messages.editRecord + '"><span>' + self.options.messages.editRecord + '</span></button>')
+ .appendTo($editCell)
+ .click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ self._showEditForm($row);
+ });
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Shows edit form for a row.
+ *************************************************************************/
+ _showEditForm: function ($tableRow) {
+ var self = this;
+ var record = $tableRow.data('record');
+
+ //Create edit form
+ var $editForm = $('<form id="jtable-edit-form" class="jtable-dialog-form jtable-edit-form" action="' + self.options.actions.updateAction + '" method="POST"></form>');
+
+ //Create input fields
+ for (var i = 0; i < self._fieldList.length; i++) {
+
+ //Create hidden input for 'key' field
+ if (self.options.fields[self._fieldList[i]].key == true) {
+ $editForm.append(self._createInputForHidden(self._fieldList[i], record[self._fieldList[i]]));
+ continue;
+ }
+
+ //Do not create element for non-editable fields
+ if (self.options.fields[self._fieldList[i]].edit == false) {
+ continue;
+ }
+
+ //Hidden field
+ if (self.options.fields[self._fieldList[i]].type == 'hidden') {
+ $editForm.append(self._createInputForHidden(self._fieldList[i], record[self._fieldList[i]]));
+ continue;
+ }
+
+ //Create a container div for this input field and add to form
+ var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($editForm);
+
+ //Create a label for input
+ $fieldContainer.append(self._createInputLabelForRecordField(self._fieldList[i]));
+
+ //Create input element with it's current value
+ var currentValue = self._getValueForRecordField(record, self._fieldList[i]);
+ $fieldContainer.append(self._createInputForRecordField(self._fieldList[i], currentValue, record));
+ }
+
+ //Open dialog
+ self._$editingRow = $tableRow;
+ self._$editDiv.append($editForm).dialog('open');
+ self._trigger("formCreated", null, { form: $editForm, formType: 'edit', record: record });
+ },
+
+ /* Saves editing form to the server and updates the record on the table.
+ *************************************************************************/
+ _saveEditForm: function ($editForm, $saveButton) {
+ var self = this;
+ self._submitFormUsingAjax(
+ $editForm.attr('action'),
+ $editForm.serialize(),
+ function (data) {
+ //Check for errors
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ return;
+ }
+
+ var $editingRow = self._$editingRow;
+
+ self._updateRecordValuesFromEditForm($editingRow.data('record'), $editForm);
+ self._updateRowTexts($editingRow);
+
+ self._onRecordUpdated($editingRow, data);
+
+ if (self.options.animationsEnabled) {
+ self._showUpdateAnimationForRow($editingRow);
+ }
+
+ self._$editDiv.dialog("close");
+ },
+ function () {
+ self._showError(self.options.messages.serverCommunicationError);
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ });
+ },
+
+ /* Updates values of a record from given edit form
+ *************************************************************************/
+ _updateRecordValuesFromEditForm: function (record, $form) {
+ for (var i = 0; i < this._fieldList.length; i++) {
+ var fieldName = this._fieldList[i];
+ var field = this.options.fields[fieldName];
+
+ //Do not update non-editable fields
+ if (field.edit == false) {
+ continue;
+ }
+
+ //Get field name and the input element of this field in the form
+ var $inputElement = $form.find('[name="' + fieldName + '"]');
+
+ //Update field in record according to it's type
+ if (field.type == 'date') {
+ var displayFormat = field.displayFormat || this.options.defaultDateFormat;
+ try {
+ var date = $.datepicker.parseDate(displayFormat, $inputElement.val());
+ record[fieldName] = '/Date(' + date.getTime() + ')/';
+ } catch (e) {
+ //TODO: Handle incorrect/different date formats
+ record[fieldName] = '/Date(' + (new Date()).getTime() + ')/';
+ }
+ } else if (field.options && field.type == 'radiobutton') {
+ var $checkedElement = $inputElement.filter('[checked="true"]');
+ if ($checkedElement.length) {
+ record[fieldName] = $checkedElement.val();
+ } else {
+ record[fieldName] = undefined;
+ }
+ } else {
+ record[fieldName] = $inputElement.val();
+ }
+ }
+ },
+
+ /* Gets text for a field of a record according to it's type.
+ *************************************************************************/
+ _getValueForRecordField: function (record, fieldName) {
+ var field = this.options.fields[fieldName];
+ var fieldValue = record[fieldName];
+ if (field.type == 'date') {
+ return this._getDisplayTextForDateRecordField(field, fieldValue);
+ } else {
+ return fieldValue;
+ }
+ },
+
+ /* Updates cells of a table row's text values from row's record values.
+ *************************************************************************/
+ _updateRowTexts: function ($tableRow) {
+ var record = $tableRow.data('record');
+ var $columns = $tableRow.find('td');
+ for (var i = 0; i < this._columnList.length; i++) {
+ var displayItem = this._getDisplayTextForRecordField(record, this._columnList[i]);
+ $columns.eq(this._firstDataColumnOffset + i).html(displayItem || '');
+ }
+
+ this._onRowUpdated($tableRow);
+ },
+
+ /* Shows 'updated' animation for a table row.
+ *************************************************************************/
+ _showUpdateAnimationForRow: function ($tableRow) {
+ $tableRow.stop(true, true).addClass('jtable-row-updated', 'slow', '', function () {
+ $tableRow.removeClass('jtable-row-updated', 5000);
+ });
+ },
+
+ /************************************************************************
+ * EVENT RAISING METHODS *
+ *************************************************************************/
+
+ _onRowUpdated: function ($row) {
+ this._trigger("rowUpdated", null, { row: $row, record: $row.data('record') });
+ },
+
+ _onRecordUpdated: function ($row, data) {
+ this._trigger("recordUpdated", null, { record: $row.data('record'), row: $row, serverResponse: data });
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* DELETION extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
+ _addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Options
+ deleteConfirmation: true,
+
+ //Events
+ recordDeleted: function (event, data) { },
+
+ //Localization
+ messages: {
+ deleteConfirmation: 'This record will be deleted. Are you sure?',
+ deleteText: 'Delete',
+ deleting: 'Deleting',
+ canNotDeletedRecords: 'Can not deleted {0} of {1} records!',
+ deleteProggress: 'Deleted {0} of {1} records, processing...'
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$deleteRecordDiv: null, //Reference to the adding new record dialog div (jQuery object)
+ _$deletingRow: null, //Reference to currently deleting row (jQuery object)
+
+ /************************************************************************
+ * CONSTRUCTOR *
+ *************************************************************************/
+
+ /* Overrides base method to do deletion-specific constructions.
+ *************************************************************************/
+ _create: function () {
+ base._create.apply(this, arguments);
+ this._createDeleteDialogDiv();
+ },
+
+ /* Creates and prepares delete record confirmation dialog div.
+ *************************************************************************/
+ _createDeleteDialogDiv: function () {
+ var self = this;
+
+ //Create div element for delete confirmation dialog
+ self._$deleteRecordDiv = $('<div><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span><span class="jtable-delete-confirm-message"></span></p></div>').appendTo(self._$mainContainer);
+
+ //Prepare dialog
+ self._$deleteRecordDiv.dialog({
+ autoOpen: false,
+ show: self.options.dialogShowEffect,
+ hide: self.options.dialogHideEffect,
+ modal: true,
+ title: self.options.messages.areYouSure,
+ buttons:
+ [{ //cancel button
+ text: self.options.messages.cancel,
+ click: function () {
+ self._$deleteRecordDiv.dialog("close");
+ }
+ }, {//delete button
+ id: 'DeleteDialogButton',
+ text: self.options.messages.deleteText,
+ click: function () {
+ var $deleteButton = $('#DeleteDialogButton');
+ self._setEnabledOfDialogButton($deleteButton, false, self.options.messages.deleting);
+ self._deleteRecordFromServer(
+ self._$deletingRow,
+ function () {
+ self._removeRowsFromTableWithAnimation(self._$deletingRow);
+ self._$deleteRecordDiv.dialog('close');
+ },
+ function (message) { //error
+ self._showError(message);
+ self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
+ }
+ );
+ }
+ }],
+ close: function () {
+ var $deleteButton = $('#DeleteDialogButton');
+ self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
+ }
+ });
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* This method is used to delete one or more rows from server and the table.
+ *************************************************************************/
+ deleteRows: function ($rows) {
+ var self = this;
+
+ //If no rows specified, or jTable is already busy, no action.
+ if ($rows.length <= 0 || self._isBusy()) {
+ return;
+ }
+
+ //Deleting just one row
+ if ($rows.length == 1) {
+ self._deleteRecordFromServer(
+ $rows,
+ function () { //success
+ self._removeRowsFromTableWithAnimation($rows);
+ },
+ function (message) { //error
+ self._showError(message);
+ }
+ );
+
+ return;
+ }
+
+ //Deleting multiple rows
+ self._showBusy(self._formatString(self.options.messages.deleteProggress, 0, $rows.length));
+
+ //This method checks if deleting of all records is completed
+ var completedCount = 0;
+ var isCompleted = function () {
+ return (completedCount >= $rows.length);
+ };
+
+ //This method is called when deleting of all records completed
+ var completed = function () {
+ var $deletedRows = $rows.filter('.jtable-row-ready-to-remove');
+ if ($deletedRows.length < $rows.length) {
+ self._showError(self._formatString(self.options.messages.canNotDeletedRecords, $rows.length - $deletedRows.length, $rows.length));
+ }
+
+ if ($deletedRows.length > 0) {
+ self._removeRowsFromTableWithAnimation($deletedRows);
+ }
+
+ self._hideBusy();
+ };
+
+ //Delete all rows
+ var deletedCount = 0;
+ $rows.each(function () {
+ var $row = $(this);
+ self._deleteRecordFromServer(
+ $row,
+ function () { //success
+ ++deletedCount; ++completedCount;
+ $row.addClass('jtable-row-ready-to-remove');
+ self._showBusy(self._formatString(self.options.messages.deleteProggress, deletedCount, $rows.length));
+ if (isCompleted()) {
+ completed();
+ }
+ },
+ function () { //error
+ ++completedCount;
+ if (isCompleted()) {
+ completed();
+ }
+ }
+ );
+ });
+ },
+
+ /* Deletes a record from the table (optionally from the server also).
+ *************************************************************************/
+ deleteRecord: function (options) {
+ var self = this;
+ options = $.extend({
+ clientOnly: false,
+ animationsEnabled: self.options.animationsEnabled,
+ url: self.options.actions.deleteAction,
+ success: function () { },
+ error: function () { }
+ }, options);
+
+ if (!options.key) {
+ self._logWarn('options parameter in deleteRecord method must contain a record key.');
+ return;
+ }
+
+ var $deletingRow = self.getRowByKey(options.key);
+ if ($deletingRow == null) {
+ self._logWarn('Can not found any row by key: ' + options.key);
+ return;
+ }
+
+ if (options.clientOnly) {
+ self._removeRowsFromTableWithAnimation($deletingRow, options.animationsEnabled);
+ options.success();
+ return;
+ }
+
+ self._deleteRecordFromServer(
+ $deletingRow,
+ function (data) { //success
+ self._removeRowsFromTableWithAnimation($deletingRow, options.animationsEnabled);
+ options.success(data);
+ },
+ function (message) { //error
+ self._showError(message);
+ options.error(message);
+ },
+ options.url
+ );
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to add a 'deletion column cell' to header row.
+ *************************************************************************/
+ _addColumnsToHeaderRow: function ($tr) {
+ base._addColumnsToHeaderRow.apply(this, arguments);
+ if (this.options.actions.deleteAction != undefined) {
+ $tr.append(this._createEmptyCommandHeader());
+ }
+ },
+
+ /* Overrides base method to add a 'delete command cell' to a row.
+ *************************************************************************/
+ _addCellsToRowUsingRecord: function ($row) {
+ base._addCellsToRowUsingRecord.apply(this, arguments);
+
+ var self = this;
+ if (self.options.actions.deleteAction != undefined) {
+ var $deleteCell = $('<td class="jtable-command-column"></td>').appendTo($row);
+ $('<button class="jtable-command-button jtable-delete-command-button" title="' + self.options.messages.deleteText + '"><span>' + self.options.messages.deleteText + '</span></button>')
+ .appendTo($deleteCell)
+ .click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ self._deleteButtonClickedForRow($row);
+ });
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* This method is called when user clicks delete button on a row.
+ *************************************************************************/
+ _deleteButtonClickedForRow: function ($row) {
+ var self = this;
+
+ var deleteConfirm;
+ var deleteConfirmMessage = self.options.messages.deleteConfirmation;
+
+ //If options.deleteConfirmation is function then call it
+ if ($.isFunction(self.options.deleteConfirmation)) {
+ var data = { row: $row, record: $row.data('record'), deleteConfirm: true, deleteConfirmMessage: deleteConfirmMessage, cancel: false, cancelMessage: null };
+ self.options.deleteConfirmation(data);
+
+ //If delete progress is cancelled
+ if (data.cancel) {
+
+ //If a canlellation reason is specified
+ if (data.cancelMessage) {
+ self._showError(data.cancelMessage); //TODO: show warning/stop message instead of error (also show warning/error ui icon)!
+ }
+
+ return;
+ }
+
+ deleteConfirmMessage = data.deleteConfirmMessage;
+ deleteConfirm = data.deleteConfirm;
+ } else {
+ deleteConfirm = self.options.deleteConfirmation;
+ }
+
+ if (deleteConfirm != false) {
+ //Confirmation
+ self._$deleteRecordDiv.find('.jtable-delete-confirm-message').html(deleteConfirmMessage);
+ self._showDeleteDialog($row);
+ } else {
+ //No confirmation
+ self._deleteRecordFromServer(
+ $row,
+ function () { //success
+ self._removeRowsFromTableWithAnimation($row);
+ },
+ function (message) { //error
+ self._showError(message);
+ }
+ );
+ }
+ },
+
+ /* Shows delete comfirmation dialog.
+ *************************************************************************/
+ _showDeleteDialog: function ($row) {
+ this._$deletingRow = $row;
+ this._$deleteRecordDiv.dialog('open');
+ },
+
+ /* Performs an ajax call to server to delete record
+ * and removesd row of record from table if ajax call success.
+ *************************************************************************/
+ _deleteRecordFromServer: function ($row, success, error, url) {
+ var self = this;
+
+ //Check if it is already being deleted right now
+ if ($row.data('deleting') == true) {
+ return;
+ }
+
+ $row.data('deleting', true);
+
+ var postData = {};
+ postData[self._keyField] = $row.data('record')[self._keyField];
+ self._performAjaxCall(
+ (url || self.options.actions.deleteAction),
+ postData,
+ true,
+ function (data) { //success
+ //Check for errors
+ if (data.Result != 'OK') {
+ $row.data('deleting', false);
+ if (error) {
+ error(data.Message);
+ }
+
+ return;
+ }
+
+ self._trigger("recordDeleted", null, { record: $row.data('record'), row: $row, serverResponse: data });
+
+ if (success) {
+ success(data);
+ }
+ },
+ function () {
+ $row.data('deleting', false);
+ if (error) {
+ error(self.options.messages.serverCommunicationError);
+ }
+ });
+ },
+
+ /* Removes a row from table after a 'deleting' animation.
+ *************************************************************************/
+ _removeRowsFromTableWithAnimation: function ($rows, animationsEnabled) {
+ var self = this;
+
+ if (animationsEnabled == undefined) {
+ animationsEnabled = self.options.animationsEnabled;
+ }
+
+ if (animationsEnabled) {
+ //Stop current animation (if does exists) and begin 'deleting' animation.
+ $rows.stop(true, true).addClass('jtable-row-deleting', 'slow', '').promise().done(function () {
+ self._removeRowsFromTable($rows, 'deleted');
+ });
+ } else {
+ self._removeRowsFromTable($rows, 'deleted');
+ }
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* SELECTING extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
+ _addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord,
+ _onLoadingRecords: $.hik.jtable.prototype._onLoadingRecords,
+ _onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded,
+ _onRowsRemoved: $.hik.jtable.prototype._onRowsRemoved
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Options
+ selecting: false,
+ multiselect: false,
+ selectingCheckboxes: false,
+ selectOnRowClick: true,
+
+ //Events
+ selectionChanged: function (event, data) { }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _selectedRecordIdsBeforeLoad: null, //This array is used to store selected row Id's to restore them after a page refresh (string array).
+ _$selectAllCheckbox: null, //Reference to the 'select/deselect all' checkbox (jQuery object)
+ _shiftKeyDown: false, //True, if shift key is currently down.
+
+ /************************************************************************
+ * CONSTRUCTOR *
+ *************************************************************************/
+
+ /* Overrides base method to do selecting-specific constructions.
+ *************************************************************************/
+ _create: function () {
+ if (this.options.selecting && this.options.selectingCheckboxes) {
+ ++this._firstDataColumnOffset;
+ }
+
+ this._bindKeyboardEvents();
+
+ //Call base method
+ base._create.apply(this, arguments);
+ },
+
+ /* Registers to keyboard events those are needed for selection
+ *************************************************************************/
+ _bindKeyboardEvents: function () {
+ var self = this;
+ //Register to events to set _shiftKeyDown value
+ $(document).keydown(function (event) {
+ switch (event.which) {
+ case 16: //shift key
+ self._shiftKeyDown = true;
+ break;
+ }
+ }).keyup(function (event) {
+ switch (event.which) {
+ case 16: //shift key
+ self._shiftKeyDown = false;
+ break;
+ }
+ });
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Gets jQuery selection for currently selected rows.
+ *************************************************************************/
+ selectedRows: function () {
+ return this._getSelectedRows();
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to add a 'select column' to header row.
+ *************************************************************************/
+ _addColumnsToHeaderRow: function ($tr) {
+ if (this.options.selecting && this.options.selectingCheckboxes) {
+ if (this.options.multiselect) {
+ $tr.append(this._createSelectAllHeader());
+ } else {
+ $tr.append(this._createEmptyCommandHeader());
+ }
+ }
+
+ base._addColumnsToHeaderRow.apply(this, arguments);
+ },
+
+ /* Overrides base method to add a 'delete command cell' to a row.
+ *************************************************************************/
+ _addCellsToRowUsingRecord: function ($row) {
+ if (this.options.selecting) {
+ this._makeRowSelectable($row);
+ }
+
+ base._addCellsToRowUsingRecord.apply(this, arguments);
+ },
+
+ /* Overrides base event to store selection list
+ *************************************************************************/
+ _onLoadingRecords: function () {
+ this._storeSelectionList();
+ base._onLoadingRecords.apply(this, arguments);
+ },
+
+ /* Overrides base event to restore selection list
+ *************************************************************************/
+ _onRecordsLoaded: function () {
+ this._restoreSelectionList();
+ base._onRecordsLoaded.apply(this, arguments);
+ },
+
+ /* Overrides base event to check is any selected row is being removed.
+ *************************************************************************/
+ _onRowsRemoved: function ($rows, reason) {
+ if ((reason != 'reloading') && this.options.selecting && ($rows.filter('.jtable-row-selected').length > 0)) {
+ this._onSelectionChanged();
+ }
+
+ base._onRowsRemoved.apply(this, arguments);
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Creates a header column to select/deselect all rows.
+ *************************************************************************/
+ _createSelectAllHeader: function () {
+ var self = this;
+
+ var $columnHeader = $('<th class="jtable-command-column-header jtable-column-header-selecting"></th>');
+ var $headerContainer = $('<div class="jtable-column-header-container"></div>').appendTo($columnHeader);
+ self._$selectAllCheckbox = $('<input type="checkbox" />').appendTo($headerContainer);
+
+ self._$selectAllCheckbox.click(function () {
+ if (self._$tableRows.length <= 0) {
+ self._$selectAllCheckbox.attr('checked', false);
+ return;
+ }
+
+ var allRows = self._$tableBody.find('tr');
+ if (self._$selectAllCheckbox.is(':checked')) {
+ self._selectRows(allRows);
+ } else {
+ self._deselectRows(allRows);
+ }
+
+ self._onSelectionChanged();
+ });
+
+ return $columnHeader;
+ },
+
+ /* Stores Id's of currently selected records to _selectedRecordIdsBeforeLoad.
+ *************************************************************************/
+ _storeSelectionList: function () {
+ var self = this;
+
+ if (!self.options.selecting) {
+ return;
+ }
+
+ self._selectedRecordIdsBeforeLoad = [];
+ self._getSelectedRows().each(function () {
+ self._selectedRecordIdsBeforeLoad.push($(this).data('record')[self._keyField]);
+ });
+ },
+
+ /* Selects rows whose Id is in _selectedRecordIdsBeforeLoad;
+ *************************************************************************/
+ _restoreSelectionList: function () {
+ var self = this;
+
+ if (!self.options.selecting) {
+ return;
+ }
+
+ var selectedRowCount = 0;
+ for (var i = 0; i < self._$tableRows.length; ++i) {
+ if ($.inArray(self._$tableRows[i].data('record')[self._keyField], self._selectedRecordIdsBeforeLoad) > -1) {
+ self._selectRows(self._$tableRows[i]);
+ ++selectedRowCount;
+ }
+ }
+
+ if (self._selectedRecordIdsBeforeLoad.length > 0 && self._selectedRecordIdsBeforeLoad.length != selectedRowCount) {
+ self._onSelectionChanged();
+ }
+
+ self._selectedRecordIdsBeforeLoad = [];
+ self._refreshSelectAllCheckboxState();
+ },
+
+ /* Gets all selected rows.
+ *************************************************************************/
+ _getSelectedRows: function () {
+ return this._$tableBody.find('.jtable-row-selected');
+ },
+
+ /* Adds selectable feature to a row.
+ *************************************************************************/
+ _makeRowSelectable: function ($row) {
+ var self = this;
+
+ //Select/deselect on row click
+ if (self.options.selectOnRowClick) {
+ $row.click(function () {
+ self._invertRowSelection($row);
+ });
+ }
+
+ //'select/deselect' checkbox column
+ if (self.options.selectingCheckboxes) {
+ var $cell = $('<td class="jtable-selecting-column"></td>');
+ var $selectCheckbox = $('<input type="checkbox" />').appendTo($cell);
+
+ if (!self.options.selectOnRowClick) {
+ $selectCheckbox.click(function () {
+ self._invertRowSelection($row);
+ });
+ }
+
+ $row.append($cell);
+ }
+ },
+
+ /* Inverts selection state of a single row.
+ *************************************************************************/
+ _invertRowSelection: function ($row) {
+ if ($row.hasClass('jtable-row-selected')) {
+ this._deselectRows($row);
+ } else {
+ //Shift key?
+ if (this._shiftKeyDown) {
+ var rowIndex = this._findRowIndex($row);
+ //try to select row and above rows until first selected row
+ var beforeIndex = this._findFirstSelectedRowIndexBeforeIndex(rowIndex) + 1;
+ if (beforeIndex > 0 && beforeIndex < rowIndex) {
+ this._selectRows(this._$tableBody.find('tr').slice(beforeIndex, rowIndex + 1));
+ } else {
+ //try to select row and below rows until first selected row
+ var afterIndex = this._findFirstSelectedRowIndexAfterIndex(rowIndex) - 1;
+ if (afterIndex > rowIndex) {
+ this._selectRows(this._$tableBody.find('tr').slice(rowIndex, afterIndex + 1));
+ } else {
+ //just select this row
+ this._selectRows($row);
+ }
+ }
+ } else {
+ this._selectRows($row);
+ }
+ }
+
+ this._onSelectionChanged();
+ },
+
+ /* Search for a selected row (that is before given row index) to up and returns it's index
+ *************************************************************************/
+ _findFirstSelectedRowIndexBeforeIndex: function (rowIndex) {
+ for (var i = rowIndex - 1; i >= 0; --i) {
+ if (this._$tableRows[i].hasClass('jtable-row-selected')) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /* Search for a selected row (that is after given row index) to down and returns it's index
+ *************************************************************************/
+ _findFirstSelectedRowIndexAfterIndex: function (rowIndex) {
+ for (var i = rowIndex + 1; i < this._$tableRows.length; ++i) {
+ if (this._$tableRows[i].hasClass('jtable-row-selected')) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /* Makes row/rows 'selected'.
+ *************************************************************************/
+ _selectRows: function ($rows) {
+
+ if (!this.options.multiselect) {
+ this._deselectRows(this._getSelectedRows());
+ }
+
+ $rows.addClass('jtable-row-selected');
+ if (this.options.selectingCheckboxes) {
+ $rows.find('td.jtable-selecting-column input').attr('checked', true);
+ }
+
+ this._refreshSelectAllCheckboxState();
+ },
+
+ /* Makes row/rows 'non selected'.
+ *************************************************************************/
+ _deselectRows: function ($rows) {
+ $rows.removeClass('jtable-row-selected');
+ if (this.options.selectingCheckboxes) {
+ $rows.find('td.jtable-selecting-column input').removeAttr('checked');
+ }
+
+ this._refreshSelectAllCheckboxState();
+ },
+
+ /* Updates state of the 'select/deselect' all checkbox according to count of selected rows.
+ *************************************************************************/
+ _refreshSelectAllCheckboxState: function () {
+ if (!this.options.selectingCheckboxes || !this.options.multiselect) {
+ return;
+ }
+
+ var totalRowCount = this._$tableRows.length;
+ var selectedRowCount = this._getSelectedRows().length;
+
+ if (selectedRowCount == 0) {
+ this._$selectAllCheckbox.prop('indeterminate', false);
+ this._$selectAllCheckbox.attr('checked', false);
+ } else if (selectedRowCount == totalRowCount) {
+ this._$selectAllCheckbox.prop('indeterminate', false);
+ this._$selectAllCheckbox.attr('checked', true);
+ } else {
+ this._$selectAllCheckbox.attr('checked', false);
+ this._$selectAllCheckbox.prop('indeterminate', true);
+ }
+ },
+
+ /************************************************************************
+ * EVENT RAISING METHODS *
+ *************************************************************************/
+
+ _onSelectionChanged: function () {
+ this._trigger("selectionChanged", null, {});
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* PAGING extension for jTable *
+*************************************************************************/
+(function($) {
+
+ //Reference to base object members
+ var base = {
+ load: $.hik.jtable.prototype.load,
+ _create: $.hik.jtable.prototype._create,
+ _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
+ _addRowToTable: $.hik.jtable.prototype._addRowToTable,
+ _removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable,
+ _onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+ paging: false,
+ pageSize: 10,
+
+ messages: {
+ pagingInfo: 'Showing {0} to {1} of {2} records'
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$pagingListArea: null, //Reference to the page list area in to bottom panel
+ _totalRecordCount: 0, //Total count of records on all pages
+ _currentPageNo: 1, //Current page number
+
+ /************************************************************************
+ * CONSTRUCTOR AND INITIALIZING METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to do paging-specific constructions.
+ *************************************************************************/
+ _create: function() {
+ base._create.apply(this, arguments);
+ this._createPageListArea();
+ },
+
+ /* Creates page list area if paging enabled.
+ *************************************************************************/
+ _createPageListArea: function() {
+ if (!this.options.paging) {
+ return;
+ }
+
+ this._$pagingListArea = $('<span class="jtable-page-list"></span>').prependTo(this._$bottomPanel.find('.jtable-left-area'));
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides load method to set current page to 1.
+ *************************************************************************/
+ load: function() {
+ this._currentPageNo = 1;
+ base.load.apply(this, arguments);
+ },
+
+ /* Overrides _createRecordLoadUrl method to add paging info to URL.
+ *************************************************************************/
+ _createRecordLoadUrl: function() {
+ var loadUrl = base._createRecordLoadUrl.apply(this, arguments);
+ loadUrl = this._addPagingInfoToUrl(loadUrl, this._currentPageNo);
+ return loadUrl;
+ },
+
+ /* Overrides _addRowToTable method to re-load table when a new row is created.
+ *************************************************************************/
+ _addRowToTable: function($tableRow, index, isNewRow) {
+ if (isNewRow && this.options.paging) {
+ this._reloadTable();
+ return;
+ }
+
+ base._addRowToTable.apply(this, arguments);
+ },
+
+ /* Overrides _removeRowsFromTable method to re-load table when a row is removed from table.
+ *************************************************************************/
+ _removeRowsFromTable: function($rows, reason) {
+ base._removeRowsFromTable.apply(this, arguments);
+
+ if (this.options.paging) {
+ if (this._$tableRows.length <= 0 && this._currentPageNo > 1) {
+ --this._currentPageNo;
+ }
+
+ this._reloadTable();
+ }
+ },
+
+ /* Overrides _onRecordsLoaded method to to do paging specific tasks.
+ *************************************************************************/
+ _onRecordsLoaded: function(data) {
+ this._totalRecordCount = data.TotalRecordCount;
+ this._createPagingList();
+ base._onRecordsLoaded.apply(this, arguments);
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Adds jtStartIndex and jtPageSize parameters to a URL as query string.
+ *************************************************************************/
+ _addPagingInfoToUrl: function(url, pageNumber) {
+ if (!this.options.paging) {
+ return url;
+ }
+
+ var jtStartIndex = (pageNumber - 1) * this.options.pageSize;
+ var jtPageSize = this.options.pageSize;
+
+ return (url + (url.indexOf('?') < 0 ? '?' : '&') + 'jtStartIndex=' + jtStartIndex + '&jtPageSize=' + jtPageSize);
+ },
+
+ /* Creates and shows the page list.
+ *************************************************************************/
+ _createPagingList: function() {
+ if (!this.options.paging || this.options.pageSize <= 0) {
+ return;
+ }
+
+ this._$pagingListArea.empty();
+ var pageCount = this._calculatePageCount();
+
+ this._createFirstAndPreviousPageButtons();
+ this._createPageNumberButtons(this._calculatePageNumbers(pageCount));
+ this._createLastAndNextPageButtons(pageCount);
+ this._createPagingInfo();
+ this._bindClickEventsToPageNumberButtons();
+ },
+
+ /* Creates and shows previous and first page links.
+ *************************************************************************/
+ _createFirstAndPreviousPageButtons: function() {
+ if (this._currentPageNo > 1) {
+ $('<span class="jtable-page-number-first">|&lt</span>')
+ .data('pageNumber', 1)
+ .appendTo(this._$pagingListArea);
+ $('<span class="jtable-page-number-previous">&lt</span>')
+ .data('pageNumber', this._currentPageNo - 1)
+ .appendTo(this._$pagingListArea);
+ }
+ },
+
+ /* Creates and shows next and last page links.
+ *************************************************************************/
+ _createLastAndNextPageButtons: function(pageCount) {
+ if (this._currentPageNo < pageCount) {
+ $('<span class="jtable-page-number-next">&gt</span>')
+ .data('pageNumber', this._currentPageNo + 1)
+ .appendTo(this._$pagingListArea);
+ $('<span class="jtable-page-number-last">&gt|</span>')
+ .data('pageNumber', pageCount)
+ .appendTo(this._$pagingListArea);
+ }
+ },
+
+ /* Creates and shows page number links for given number array.
+ *************************************************************************/
+ _createPageNumberButtons: function(pageNumbers) {
+ var previousNumber = 0;
+ for (var i = 0; i < pageNumbers.length; i++) {
+ //Create "..." between page numbers if needed
+ if ((pageNumbers[i] - previousNumber) > 1) {
+ $('<span class="jtable-page-number-space">...</span>').appendTo(this._$pagingListArea);
+ }
+
+ this._createPageNumberButton(pageNumbers[i]);
+ previousNumber = pageNumbers[i];
+ }
+ },
+
+ /* Creates a page number link and adds to paging area.
+ *************************************************************************/
+ _createPageNumberButton: function(pageNumber) {
+ $('<span class="' + (this._currentPageNo == pageNumber ? 'jtable-page-number-active' : 'jtable-page-number') + '">' + pageNumber + '</span>')
+ .data('pageNumber', pageNumber)
+ .appendTo(this._$pagingListArea);
+ },
+
+ /* Calculates total page count according to page size and total record count.
+ *************************************************************************/
+ _calculatePageCount: function() {
+ var pageCount = Math.floor(this._totalRecordCount / this.options.pageSize);
+ if (this._totalRecordCount % this.options.pageSize != 0) {
+ ++pageCount;
+ }
+
+ return pageCount;
+ },
+
+ /* Calculates page numbers and returns an array of these numbers.
+ *************************************************************************/
+ _calculatePageNumbers: function(pageCount) {
+ if (pageCount <= 6) {
+ //Show all pages
+ var pageNumbers = [];
+ for (var i = 1; i <= pageCount; ++i) {
+ pageNumbers.push(i);
+ }
+
+ return pageNumbers;
+ } else {
+ //show first three, last three, current, previous and next page numbers
+ var shownPageNumbers = [1, 2, 3, pageCount - 2, pageCount - 1, pageCount];
+ var previousPageNo = this._normalizeNumber(this._currentPageNo - 1, 1, pageCount, 1);
+ var nextPageNo = this._normalizeNumber(this._currentPageNo + 1, 1, pageCount, 1);
+
+ this._insertToArrayIfDoesNotExists(shownPageNumbers, previousPageNo);
+ this._insertToArrayIfDoesNotExists(shownPageNumbers, this._currentPageNo);
+ this._insertToArrayIfDoesNotExists(shownPageNumbers, nextPageNo);
+
+ shownPageNumbers.sort(function(a, b) { return a - b; });
+ return shownPageNumbers;
+ }
+ },
+
+ /* Creates and shows paging informations.
+ *************************************************************************/
+ _createPagingInfo: function() {
+ var startNo = (this._currentPageNo - 1) * this.options.pageSize + 1;
+ var endNo = this._currentPageNo * this.options.pageSize;
+ endNo = this._normalizeNumber(endNo, startNo, this._totalRecordCount, 0);
+
+ if (endNo >= startNo) {
+ var pagingInfoMessage = this._formatString(this.options.messages.pagingInfo, startNo, endNo, this._totalRecordCount);
+ $('<span class="jtable-page-info">' + pagingInfoMessage + '</span>').appendTo(this._$pagingListArea);
+ }
+ },
+
+ /* Binds click events of all page links to change the page.
+ *************************************************************************/
+ _bindClickEventsToPageNumberButtons: function() {
+ var self = this;
+ self._$pagingListArea
+ .find('.jtable-page-number,.jtable-page-number-previous,.jtable-page-number-next,.jtable-page-number-first,.jtable-page-number-last')
+ .click(function(e) {
+ e.preventDefault();
+ var $this = $(this);
+ self._currentPageNo = $this.data('pageNumber');
+ self._reloadTable();
+ });
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* SORTING extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
+ _createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
+ _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+ sorting: false,
+ defaultSorting: ''
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _lastSorting: '', //Last sorting of the table
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides _normalizeFieldOptions method to normalize sorting option for fields.
+ *************************************************************************/
+ _normalizeFieldOptions: function (fieldName, props) {
+ base._normalizeFieldOptions.apply(this, arguments);
+ props.sorting = (props.sorting != false);
+ },
+
+ /* Overrides _createHeaderCellForField to make columns sortable.
+ *************************************************************************/
+ _createHeaderCellForField: function (fieldName, field) {
+ var $headerCell = base._createHeaderCellForField.apply(this, arguments);
+ if (this.options.sorting && field.sorting) {
+ this._makeColumnSortable($headerCell, fieldName);
+ }
+
+ return $headerCell;
+ },
+
+ /* Overrides _createRecordLoadUrl to add sorting specific info to URL.
+ *************************************************************************/
+ _createRecordLoadUrl: function () {
+ var loadUrl = base._createRecordLoadUrl.apply(this, arguments);
+ loadUrl = this._addSortingInfoToUrl(loadUrl);
+ return loadUrl;
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Makes a column sortable.
+ *************************************************************************/
+ _makeColumnSortable: function ($columnHeader, fieldName) {
+ var self = this;
+ $columnHeader
+ .addClass('jtable-column-header-sortable')
+ .click(function(e) {
+ e.preventDefault();
+ self._sortTableByColumn($columnHeader);
+ });
+
+ //Default sorting?
+ if (self.options.defaultSorting.indexOf(fieldName) > -1) {
+ if (self.options.defaultSorting.indexOf('DESC') > -1) {
+ $columnHeader.addClass('jtable-column-header-sorted-desc');
+ self._lastSorting = fieldName + " DESC";
+ } else {
+ $columnHeader.addClass('jtable-column-header-sorted-asc');
+ self._lastSorting = fieldName + " ASC";
+ }
+ }
+ },
+
+ /* Sorts table according to a column header.
+ *************************************************************************/
+ _sortTableByColumn: function ($columnHeader) {
+ //Remove sorting styles from all columns except this one
+ $columnHeader.siblings().removeClass('jtable-column-header-sorted-asc jtable-column-header-sorted-desc');
+
+ //Sort ASC or DESC according to current sorting state
+ if ($columnHeader.hasClass('jtable-column-header-sorted-asc')) {
+ $columnHeader.removeClass('jtable-column-header-sorted-asc').addClass('jtable-column-header-sorted-desc');
+ this._lastSorting = $columnHeader.data('fieldName') + " DESC";
+ } else {
+ $columnHeader.removeClass('jtable-column-header-sorted-desc').addClass('jtable-column-header-sorted-asc');
+ this._lastSorting = $columnHeader.data('fieldName') + " ASC";
+ }
+
+ //Load current page again
+ this._reloadTable();
+ },
+
+ /* Adds jtSorting parameter to a URL as query string.
+ *************************************************************************/
+ _addSortingInfoToUrl: function (url) {
+ if (!this.options.sorting || this._lastSorting == '') {
+ return url;
+ }
+
+ return (url + (url.indexOf('?') < 0 ? '?' : '&') + 'jtSorting=' + this._lastSorting);
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* DYNAMIC COLUMNS extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
+ _createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
+ _createCellForRecordField: $.hik.jtable.prototype._createCellForRecordField
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+
+ options: {
+ tableId: undefined,
+ columnResizable: true,
+ columnSelectable: true,
+ saveUserPreferences: true
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$columnSelectionDiv: null,
+ _$columnResizeBar: null,
+ _cookieKeyPrefix: null,
+ _currentResizeArgs: null,
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides _addRowToTableHead method.
+ *************************************************************************/
+
+ _create: function () {
+ base._create.apply(this, arguments);
+
+ this._createColumnResizeBar();
+ this._createColumnSelection();
+
+ this._cookieKeyPrefix = this._generateCookieKeyPrefix();
+ if (this.options.saveUserPreferences) {
+ this._loadColumnSettings();
+ }
+
+ this._normalizeColumnWidths();
+ },
+
+ /* Normalizes some options for a field (sets default values).
+ *************************************************************************/
+ _normalizeFieldOptions: function (fieldName, props) {
+ base._normalizeFieldOptions.apply(this, arguments);
+
+ //columnResizable
+ if (this.options.columnResizable) {
+ props.columnResizable = (props.columnResizable != false);
+ }
+
+ //visibility
+ if (!props.visibility) {
+ props.visibility = 'visible';
+ }
+ },
+
+ /* Overrides _createHeaderCellForField to make columns dynamic.
+ *************************************************************************/
+ _createHeaderCellForField: function (fieldName, field) {
+ var $headerCell = base._createHeaderCellForField.apply(this, arguments);
+
+ //Make data columns resizable except the last one
+ if (this.options.columnResizable && field.columnResizable && (fieldName != this._columnList[this._columnList.length - 1])) {
+ this._makeColumnResizable($headerCell);
+ }
+
+ //Hide column if needed
+ if (field.visibility == 'hidden') {
+ $headerCell.hide();
+ }
+
+ return $headerCell;
+ },
+
+ /* Overrides _createHeaderCellForField to decide show or hide a column.
+ *************************************************************************/
+ _createCellForRecordField: function (record, fieldName) {
+ var $column = base._createCellForRecordField.apply(this, arguments);
+
+ var field = this.options.fields[fieldName];
+ if (field.visibility == 'hidden') {
+ $column.hide();
+ }
+
+ return $column;
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Changes visibility of a column.
+ *************************************************************************/
+ changeColumnVisibility: function (columnName, visibility) {
+ this._changeColumnVisibilityInternal(columnName, visibility);
+ this._normalizeColumnWidths();
+ if (this.options.saveUserPreferences) {
+ this._saveColumnSettings();
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Changes visibility of a column.
+ *************************************************************************/
+ _changeColumnVisibilityInternal: function (columnName, visibility) {
+ //Check if there is a column with given name
+ var columnIndex = this._columnList.indexOf(columnName);
+ if (columnIndex < 0) {
+ this._logWarn('Column "' + columnName + '" does not exist in fields!');
+ return;
+ }
+
+ //Check if visibility value is valid
+ if (['visible', 'hidden', 'fixed'].indexOf(visibility) < 0) {
+ this._logWarn('Visibility value is not valid: "' + visibility + '"! Options are: visible, hidden, fixed.');
+ return;
+ }
+
+ //Get the field
+ var field = this.options.fields[columnName];
+ if (field.visibility == visibility) {
+ return; //No action if new value is same as old one.
+ }
+
+ //Hide or show the column if needed
+ var columnIndexInTable = this._firstDataColumnOffset + columnIndex + 1;
+ if (field.visibility != 'hidden' && visibility == 'hidden') {
+ this._$table
+ .find('th:nth-child(' + columnIndexInTable + '),td:nth-child(' + columnIndexInTable + ')')
+ .hide();
+ } else if (field.visibility == 'hidden' && visibility != 'hidden') {
+ this._$table
+ .find('th:nth-child(' + columnIndexInTable + '),td:nth-child(' + columnIndexInTable + ')')
+ .show()
+ .css('display', 'table-cell');
+ }
+
+ field.visibility = visibility;
+ },
+
+ /* Prepares dialog to change settings.
+ *************************************************************************/
+ _createColumnSelection: function () {
+ var self = this;
+
+ //Create a div for dialog and add to container element
+ this._$columnSelectionDiv = $('<div class="jtable-column-selection-container"></div>').appendTo(self._$mainContainer);
+ this._$table.find('thead').bind('contextmenu', function (e) {
+ if (!self.options.columnSelectable) {
+ return;
+ }
+
+ e.preventDefault();
+ //Make an overlay div to disable page clicks
+ $('<div class="jtable-contextmenu-overlay"></div>')
+ .click(function () {
+ $(this).remove();
+ self._$columnSelectionDiv.hide();
+ })
+ .bind('contextmenu', function () { return false; })
+ .appendTo(document.body);
+
+ self._fillColumnSelection();
+ self._$columnSelectionDiv.css({ left: e.pageX - $(document).scrollLeft(), top: e.pageY - $(document).scrollTop() }).show();
+ });
+ },
+
+ /* Prepares content of settings dialog.
+ *************************************************************************/
+ _fillColumnSelection: function () {
+ var self = this;
+
+ var $columnsUl = $('<ul class="jtable-column-select-list"></ul>');
+ for (var i = 0; i < this._columnList.length; i++) {
+ var columnName = this._columnList[i];
+ var field = this.options.fields[columnName];
+
+ //Crete li element
+ var $columnLi = $('<li></li>').appendTo($columnsUl);
+
+ //Create label for the checkbox
+ var $label = $('<label for="' + columnName + '"><span>' + (field.title || columnName) + '</span><label>')
+ .appendTo($columnLi);
+
+ //Create checkbox
+ var $checkbox = $('<input type="checkbox" name="' + columnName + '">')
+ .prependTo($label)
+ .click(function () {
+ var $clickedCheckbox = $(this);
+ var clickedColumnName = $clickedCheckbox.attr('name');
+ var clickedField = self.options.fields[clickedColumnName];
+ if (clickedField.visibility == 'fixed') {
+ return;
+ }
+
+ self.changeColumnVisibility(clickedColumnName, $clickedCheckbox.is(':checked') ? 'visible' : 'hidden');
+ });
+
+ //Check, if column if shown
+ if (field.visibility != 'hidden') {
+ $checkbox.attr('checked', 'checked');
+ }
+
+ //Disable, if column is fixed
+ if (field.visibility == 'fixed') {
+ $checkbox.attr('disabled', 'disabled');
+ }
+ }
+
+ this._$columnSelectionDiv.html($columnsUl);
+ },
+
+ /* creates a vertical bar that is shown while resizing columns.
+ *************************************************************************/
+ _createColumnResizeBar: function () {
+ this._$columnResizeBar = $('<div class="jtable-column-resize-bar" style="position: fixed; top: -100px; left: -100px;"></div>')
+ .appendTo(this._$mainContainer)
+ .hide();
+ },
+
+ /* Makes a column sortable.
+ *************************************************************************/
+ _makeColumnResizable: function ($columnHeader) {
+ var self = this;
+
+ //Create a handler to handle mouse click event
+ $('<div class="jtable-column-resize-handler"></div>')
+ .appendTo($columnHeader.find('.jtable-column-header-container')) //Append the handler to the column
+ .mousedown(function (downevent) { //handle mousedown event for the handler
+ downevent.preventDefault();
+ downevent.stopPropagation();
+
+ //Get a reference to the next column
+ var $nextColumnHeader = $columnHeader.nextAll('th.jtable-column-header:visible:first');
+ if (!$nextColumnHeader.length) {
+ return;
+ }
+
+ //Store some information to be used on resizing
+ var minimumColumnWidth = 10; //A column's width can not be smaller than 10 pixel.
+ self._currentResizeArgs = {
+ currentColumnStartWidth: $columnHeader.outerWidth(),
+ minWidth: minimumColumnWidth,
+ maxWidth: $columnHeader.outerWidth() + $nextColumnHeader.outerWidth() - minimumColumnWidth,
+ mouseStartX: downevent.pageX,
+ minResizeX: function () { return this.mouseStartX - (this.currentColumnStartWidth - this.minWidth); },
+ maxResizeX: function () { return this.mouseStartX + (this.maxWidth - this.currentColumnStartWidth); }
+ };
+
+ //Handle mouse move event to move resizing bar
+ var resizeonmouseove = function (moveevent) {
+ if (!self._currentResizeArgs) {
+ return;
+ }
+
+ var resizeBarX = self._normalizeNumber(moveevent.pageX, self._currentResizeArgs.minResizeX(), self._currentResizeArgs.maxResizeX());
+ self._$columnResizeBar.css('left', resizeBarX + 'px');
+ };
+
+ //Handle mouse up event to finish resizing of the column
+ var resizeonmouseup = function (upevent) {
+ if (!self._currentResizeArgs) {
+ return;
+ }
+
+ $(document).unbind('mousemove', resizeonmouseove);
+ $(document).unbind('mouseup', resizeonmouseup);
+
+ self._$columnResizeBar.hide();
+
+ //Calculate new widths in pixels
+ var mouseChangeX = upevent.pageX - self._currentResizeArgs.mouseStartX;
+ var currentColumnFinalWidth = self._normalizeNumber(self._currentResizeArgs.currentColumnStartWidth + mouseChangeX, self._currentResizeArgs.minWidth, self._currentResizeArgs.maxWidth);
+ var nextColumnFinalWidth = $nextColumnHeader.outerWidth() + (self._currentResizeArgs.currentColumnStartWidth - currentColumnFinalWidth);
+
+ //Calculate widths as percent
+ var pixelToPercentRatio = $columnHeader.data('width-in-percent') / self._currentResizeArgs.currentColumnStartWidth;
+ $columnHeader.data('width-in-percent', currentColumnFinalWidth * pixelToPercentRatio);
+ $nextColumnHeader.data('width-in-percent', nextColumnFinalWidth * pixelToPercentRatio);
+
+ //Set new widths to columns (resize!)
+ $columnHeader.css('width', $columnHeader.data('width-in-percent') + '%');
+ $nextColumnHeader.css('width', $nextColumnHeader.data('width-in-percent') + '%');
+
+ //Normalize all column widths
+ self._normalizeColumnWidths();
+
+ //Finish resizing
+ self._currentResizeArgs = null;
+
+ //Save current preferences
+ if (self.options.saveUserPreferences) {
+ self._saveColumnSettings();
+ }
+ };
+
+ //Show vertical resize bar
+ self._$columnResizeBar
+ .show()
+ .css({
+ top: ($columnHeader.offset().top - $(document).scrollTop()) + 'px',
+ left: (downevent.pageX - $(document).scrollLeft()) + 'px',
+ height: self._$table.height() + 'px'
+ });
+
+ //Bind events
+ $(document).bind('mousemove', resizeonmouseove);
+ $(document).bind('mouseup', resizeonmouseup);
+ });
+ },
+
+ /* Normalizes column widths as percent for current view.
+ *************************************************************************/
+ _normalizeColumnWidths: function () {
+
+ //Set command column width
+ var commandColumnHeaders = this._$table
+ .find('thead th.jtable-command-column-header')
+ .data('width-in-percent', 1)
+ .css('width', '1%');
+
+ //Find data columns
+ var headerCells = this._$table.find('thead th.jtable-column-header');
+
+ //Calculate total width of data columns
+ var totalWidthInPixel = 0;
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ totalWidthInPixel += $cell.outerWidth();
+ }
+ });
+
+ //Calculate width of each column
+ var columnWidhts = {};
+ var availableWidthInPercent = 100.0 - commandColumnHeaders.length;
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ var fieldName = $cell.data('fieldName');
+ var widthInPercent = $cell.outerWidth() * availableWidthInPercent / totalWidthInPixel;
+ columnWidhts[fieldName] = widthInPercent;
+ }
+ });
+
+ //Set width of each column
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ var fieldName = $cell.data('fieldName');
+ $cell.data('width-in-percent', columnWidhts[fieldName]).css('width', columnWidhts[fieldName] + '%');
+ }
+ });
+ },
+
+ /* Saves field setting to cookie.
+ * Saved setting will be a string like that:
+ * fieldName1=visible;23|fieldName2=hidden;17|...
+ *************************************************************************/
+ _saveColumnSettings: function () {
+ var self = this;
+ var fieldSettings = '';
+ this._$table.find('thead th.jtable-column-header').each(function () {
+ var $cell = $(this);
+ var fieldName = $cell.data('fieldName');
+ var columnWidth = $cell.data('width-in-percent');
+ var fieldVisibility = self.options.fields[fieldName].visibility;
+ var fieldSetting = fieldName + "=" + fieldVisibility + ';' + columnWidth;
+ fieldSettings = fieldSettings + fieldSetting + '|';
+ });
+
+ this._setCookie('column-settings', fieldSettings.substr(0, fieldSettings.length - 1));
+ this._logDebug("saved");
+ },
+
+ /* Loads field settings from cookie that is saved by _saveFieldSettings method.
+ *************************************************************************/
+ _loadColumnSettings: function () {
+ var self = this;
+ var columnSettingsCookie = this._getCookie('column-settings');
+ if (!columnSettingsCookie) {
+ return;
+ }
+
+ var columnSettings = {};
+ $.each(columnSettingsCookie.split('|'), function (inx, fieldSetting) {
+ var splitted = fieldSetting.split('=');
+ var fieldName = splitted[0];
+ var settings = splitted[1].split(';');
+ columnSettings[fieldName] = {
+ columnVisibility: settings[0],
+ columnWidth: settings[1]
+ }; ;
+ });
+
+ var headerCells = this._$table.find('thead th.jtable-column-header');
+ headerCells.each(function () {
+ var $cell = $(this);
+ var fieldName = $cell.data('fieldName');
+ var field = self.options.fields[fieldName];
+ if (columnSettings[fieldName]) {
+ if (field.visibility != 'fixed') {
+ self._changeColumnVisibilityInternal(fieldName, columnSettings[fieldName].columnVisibility);
+ }
+
+ $cell.data('width-in-percent', columnSettings[fieldName].columnWidth).css('width', columnSettings[fieldName].columnWidth + '%');
+ }
+ });
+ this._logDebug("loaded");
+ },
+
+ /************************************************************************
+ * COOKIE *
+ *************************************************************************/
+
+ /* Sets a cookie with given key.
+ *************************************************************************/
+ _setCookie: function (key, value) {
+ key = this._cookieKeyPrefix + key;
+
+ var expireDate = new Date();
+ expireDate.setDate(expireDate.getDate() + 30);
+ document.cookie = encodeURIComponent(key) + '=' + encodeURIComponent(value) + "; expires=" + expireDate.toUTCString();
+ },
+
+ /* Gets a cookie with given key.
+ *************************************************************************/
+ _getCookie: function (key) {
+ key = this._cookieKeyPrefix + key;
+
+ var equalities = document.cookie.split('; ');
+ for (var i = 0; i < equalities.length; i++) {
+ if (!equalities[i]) {
+ continue;
+ }
+
+ var splitted = equalities[i].split('=');
+ if (splitted.length != 2) {
+ continue;
+ }
+
+ if (decodeURIComponent(splitted[0]) === key) {
+ return decodeURIComponent(splitted[1] || '');
+ }
+ }
+
+ return null;
+ },
+
+ /* Generates a hash key to be prefix for all cookies for this jtable instance.
+ *************************************************************************/
+ _generateCookieKeyPrefix: function () {
+
+ var simpleHash = function (value) {
+ var hash = 0;
+ if (value.length == 0) {
+ return hash;
+ }
+
+ for (var i = 0; i < value.length; i++) {
+ var ch = value.charCodeAt(i);
+ hash = ((hash << 5) - hash) + ch;
+ hash = hash & hash;
+ }
+
+ return hash;
+ };
+
+ var strToHash = '';
+ if (this.options.tableId) {
+ strToHash = strToHash + this.options.tableId + '#';
+ }
+
+ strToHash = strToHash + this._columnList.join('$') + '#c' + this._$table.find('thead th').length;
+ return 'jtable#' + simpleHash(strToHash);
+ }
+
+ });
+
+})(jQuery);
+
+/************************************************************************
+* MASTER/CHILD tables extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+ openChildAsAccordion: false
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Creates and opens a new child table for given row.
+ *************************************************************************/
+ openChildTable: function ($row, tableOptions, opened) {
+ var self = this;
+
+ //Show close button as default
+ tableOptions.showCloseButton = (tableOptions.showCloseButton != false);
+
+ //Close child table when close button is clicked (default behavior)
+ if (tableOptions.showCloseButton && !tableOptions.closeRequested) {
+ tableOptions.closeRequested = function () {
+ self.closeChildTable($row);
+ };
+ }
+
+ //If accordion style, close open child table (if it does exists)
+ if (self.options.openChildAsAccordion) {
+ $row.siblings().each(function () {
+ self.closeChildTable($(this));
+ });
+ }
+
+ //Close child table for this row and open new one for child table
+ self.closeChildTable($row, function () {
+ var $childRowColumn = self.getChildRow($row).find('td').empty();
+ var $childTableContainer = $('<div class="jtable-child-table-container"></div>').appendTo($childRowColumn);
+ $childRowColumn.data('childTable', $childTableContainer);
+ $childTableContainer.jtable(tableOptions);
+ self.openChildRow($row);
+ $childTableContainer.hide().slideDown('fast', function () {
+ if (opened) {
+ opened({ childTable: $childTableContainer });
+ }
+ });
+ });
+ },
+
+ /* Closes child table for given row.
+ *************************************************************************/
+ closeChildTable: function ($row, closed) {
+ var self = this;
+
+ var $childRowColumn = this.getChildRow($row).find('td');
+ var $childTable = $childRowColumn.data('childTable');
+ if (!$childTable) {
+ if (closed) {
+ closed();
+ }
+
+ return;
+ }
+
+ $childRowColumn.data('childTable', null);
+ $childTable.slideUp('fast', function () {
+ $childTable.jtable('destroy');
+ $childTable.remove();
+ self.closeChildRow($row);
+ if (closed) {
+ closed();
+ }
+ });
+ },
+
+ /* Returns a boolean value indicates that if a child row is open for given row.
+ *************************************************************************/
+ isChildRowOpen: function ($row) {
+ return (this.getChildRow($row).is(':visible'));
+ },
+
+ /* Gets child row for given row, opens it if it's closed (Creates if needed).
+ *************************************************************************/
+ getChildRow: function ($row) {
+ return $row.data('childRow') || this._createChildRow($row);
+ },
+
+ /* Creates and opens child row for given row.
+ *************************************************************************/
+ openChildRow: function ($row) {
+ var $childRow = this.getChildRow($row);
+ if (!$childRow.is(':visible')) {
+ $childRow.show();
+ }
+
+ return $childRow;
+ },
+
+ /* Closes child row if it's open.
+ *************************************************************************/
+ closeChildRow: function ($row) {
+ var $childRow = this.getChildRow($row);
+ if ($childRow.is(':visible')) {
+ $childRow.hide();
+ }
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides _removeRowsFromTable method to remove child rows of deleted rows.
+ *************************************************************************/
+ _removeRowsFromTable: function ($rows, reason) {
+ var self = this;
+
+ if (reason == 'deleted') {
+ $rows.each(function () {
+ var $row = $(this);
+ var $childRow = $row.data('childRow');
+ if ($childRow) {
+ self.closeChildTable($row);
+ $childRow.remove();
+ }
+ });
+ }
+
+ base._removeRowsFromTable.apply(this, arguments);
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Creates a child row for a row, hides and returns it.
+ *************************************************************************/
+ _createChildRow: function ($row) {
+ var index = this._findRowIndex($row);
+ var totalColumnCount = this._$table.find('thead th').length;
+ var $childRow = $('<tr class="jtable-child-row"></tr>').append('<td colspan="' + totalColumnCount + '"></td>');
+ this._addRowToTable($childRow, index + 1);
+ $row.data('childRow', $childRow);
+ $childRow.hide();
+ return $childRow;
+ }
+
+ });
+
+})(jQuery);
diff --git a/lib/jquery.jtable.min.js b/lib/jquery.jtable.min.js
new file mode 100644
index 0000000..8d809fa
--- /dev/null
+++ b/lib/jquery.jtable.min.js
@@ -0,0 +1,125 @@
+/*
+jTable 1.7.2
+http://www.jtable.org
+---------------------------------------------------------------------------
+Copyright (C) 2011-2012 by Halil Ýbrahim Kalkan (http://www.halilibrahimkalkan.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+(function(c){c.widget("hik.jtable",{options:{actions:{},fields:{},animationsEnabled:!0,defaultDateFormat:"yy-mm-dd",dialogShowEffect:"fade",dialogHideEffect:"fade",showCloseButton:!1,closeRequested:function(){},formCreated:function(){},formSubmitting:function(){},formClosed:function(){},loadingRecords:function(){},recordsLoaded:function(){},rowInserted:function(){},rowsRemoved:function(){},messages:{serverCommunicationError:"An error occured while communicating to the server.",loadingMessage:"Loading records...",
+noDataAvailable:"No data available!",areYouSure:"Are you sure?",save:"Save",saving:"Saving",cancel:"Cancel",error:"Error",close:"Close",cannotLoadOptionsFor:"Can not load options for field {0}"}},_$mainContainer:null,_$table:null,_$tableBody:null,_$tableRows:null,_$bottomPanel:null,_$busyDiv:null,_$busyMessageDiv:null,_$errorDialogDiv:null,_columnList:null,_fieldList:null,_keyField:null,_firstDataColumnOffset:0,_lastPostData:null,_cache:null,_create:function(){this._normalizeFieldsOptions();this._initializeFields();
+this._createFieldAndColumnList();this._createMainContainer();this._createTableTitle();this._createTable();this._createBottomPanel();this._createBusyPanel();this._createErrorDialogDiv();this._addNoDataRow()},_normalizeFieldsOptions:function(){var b=this;c.each(b.options.fields,function(a,c){b._normalizeFieldOptions(a,c)})},_normalizeFieldOptions:function(b,a){a.listClass=a.listClass||"";a.inputClass=a.inputClass||""},_initializeFields:function(){this._lastPostData={};this._$tableRows=[];this._columnList=
+[];this._fieldList=[];this._cache=[]},_createFieldAndColumnList:function(){var b=this;c.each(b.options.fields,function(a,c){b._fieldList.push(a);!0==c.key&&(b._keyField=a);!1!=c.list&&"hidden"!=c.type&&b._columnList.push(a)})},_createMainContainer:function(){this._$mainContainer=c('<div class="jtable-main-container"></div>').appendTo(this.element)},_createTableTitle:function(){var b=this;if(b.options.title){var a=c('<div class="jtable-title"></div>').appendTo(b._$mainContainer);c('<div class="jtable-title-text"></div>').appendTo(a).append(b.options.title);
+b.options.showCloseButton&&c('<button class="jtable-command-button jtable-close-button" title="'+b.options.messages.close+'"><span>'+b.options.messages.close+"</span></button>").appendTo(a).click(function(a){a.preventDefault();a.stopPropagation();b._onCloseRequested()})}},_createTable:function(){this._$table=c('<table class="jtable"></table>').appendTo(this._$mainContainer);this._createTableHead();this._createTableBody()},_createTableHead:function(){this._addRowToTableHead(c("<thead></thead>").appendTo(this._$table))},
+_addRowToTableHead:function(b){this._addColumnsToHeaderRow(c("<tr></tr>").appendTo(b))},_addColumnsToHeaderRow:function(b){for(var a=0;a<this._columnList.length;a++){var c=this._columnList[a];this._createHeaderCellForField(c,this.options.fields[c]).data("fieldName",c).appendTo(b)}},_createHeaderCellForField:function(b,a){a.width=a.width||"10%";return c('<th class="jtable-column-header" style="width:'+a.width+'"><div class="jtable-column-header-container"><span class="jtable-column-header-text">'+
+a.title+"</span></div></th>").data("fieldName",b)},_createEmptyCommandHeader:function(){return c('<th class="jtable-command-column-header" style="width:1%"></th>')},_createTableBody:function(){this._$tableBody=c("<tbody></tbody>").appendTo(this._$table)},_createBottomPanel:function(){this._$bottomPanel=c('<div class="jtable-bottom-panel"></div>').appendTo(this._$mainContainer);this._$bottomPanel.append('<div class="jtable-left-area"></div>');this._$bottomPanel.append('<div class="jtable-right-area"></div>')},
+_createBusyPanel:function(){this._$busyMessageDiv=c('<div class="jtable-busy-message"></div>').prependTo(this._$mainContainer);this._$busyDiv=c('<div class="jtable-busy-panel-background"></div>').prependTo(this._$mainContainer);this._hideBusy()},_createErrorDialogDiv:function(){var b=this;b._$errorDialogDiv=c("<div></div>").appendTo(b._$mainContainer);b._$errorDialogDiv.dialog({autoOpen:!1,show:b.options.dialogShowEffect,hide:b.options.dialogHideEffect,modal:!0,title:b.options.messages.error,buttons:[{text:b.options.messages.close,
+click:function(){b._$errorDialogDiv.dialog("close")}}]})},load:function(b,a){this._lastPostData=b;this._reloadTable(a)},reload:function(b){this._reloadTable(b)},destroy:function(){this.element.empty();c.Widget.prototype.destroy.call(this)},_reloadTable:function(b){var a=this;a._showBusy(a.options.messages.loadingMessage);var c=a._createRecordLoadUrl();a._onLoadingRecords();a._performAjaxCall(c,a._lastPostData,!0,function(d){a._hideBusy();if(d.Result!="OK")a._showError(d.Message);else{a._removeAllRows("reloading");
+a._addRecordsToTable(d.Records);a._onRecordsLoaded(d);b&&b()}},function(){a._hideBusy();a._showError(a.options.messages.serverCommunicationError)})},_createRecordLoadUrl:function(){return this.options.actions.listAction},_createRowFromRecord:function(b){b=c("<tr></tr>").data("record",b);this._addCellsToRowUsingRecord(b);return b},_addCellsToRowUsingRecord:function(b){for(var a=0;a<this._columnList.length;a++)this._createCellForRecordField(b.data("record"),this._columnList[a]).appendTo(b)},_createCellForRecordField:function(b,
+a){return c('<td class="'+this.options.fields[a].listClass+'"></td>').append(this._getDisplayTextForRecordField(b,a)||"")},_addRecordsToTable:function(b){var a=this;c.each(b,function(b,d){a._addRowToTable(a._createRowFromRecord(d))});a._refreshRowStyles()},_addRowToTable:function(b,a,c,d){!0!=c&&(c=!1);!1!=d&&(d=!0);0>=this._$tableRows.length&&this._removeNoDataRow();a=this._normalizeNumber(a,0,this._$tableRows.length,this._$tableRows.length);a==this._$tableRows.length?(this._$tableBody.append(b),
+this._$tableRows.push(b)):0==a?(this._$tableBody.prepend(b),this._$tableRows.unshift(b)):(this._$tableRows[a-1].after(b),this._$tableRows.splice(a,0,b));this._onRowInserted(b,c);!0==c&&(this._refreshRowStyles(),this.options.animationsEnabled&&d&&this._showNewRowAnimation(b))},_showNewRowAnimation:function(b){b.addClass("jtable-row-created","slow","",function(){b.removeClass("jtable-row-created",5E3)})},_removeRowsFromTable:function(b,a){var f=this;0>=b.length||(b.remove(),b.each(function(){f._$tableRows.splice(f._findRowIndex(c(this)),
+1)}),f._onRowsRemoved(b,a),0==f._$tableRows.length&&f._addNoDataRow(),f._refreshRowStyles())},_findRowIndex:function(b){return this._findIndexInArray(b,this._$tableRows,function(a,b){return a.data("record")==b.data("record")})},_removeAllRows:function(b){if(!(0>=this._$tableRows.length)){var a=this._$tableBody.find("tr");this._$tableBody.empty();this._$tableRows=[];this._onRowsRemoved(a,b);this._addNoDataRow()}},_addNoDataRow:function(){var b=this._$table.find("thead th").length;c('<tr class="jtable-no-data-row"></tr>').append('<td colspan="'+
+b+'">'+this.options.messages.noDataAvailable+"</td>").appendTo(this._$tableBody)},_removeNoDataRow:function(){this._$tableBody.find(".jtable-no-data-row").remove()},_refreshRowStyles:function(){for(var b=0;b<this._$tableRows.length;b++)0==b%2?this._$tableRows[b].addClass("jtable-row-even"):this._$tableRows[b].removeClass("jtable-row-even")},_getDisplayTextForRecordField:function(b,a){var c=this.options.fields[a],d=b[a];return c.display?c.display({record:b}):"date"==c.type?this._getDisplayTextForDateRecordField(c,
+d):"checkbox"==c.type?this._getCheckBoxTextForFieldByValue(a,d):c.options?this._getOptionsWithCaching(a)[d]:d},_getDisplayTextForDateRecordField:function(b,a){if(!a)return"";var f=b.displayFormat||this.options.defaultDateFormat,d=this._parseDate(a);return c.datepicker.formatDate(f,d)},_parseDate:function(b){if(0<=b.indexOf("Date"))return new Date(parseInt(b.substr(6)));if(10==b.length)return new Date(parseInt(b.substr(0,4)),parseInt(b.substr(5,2))-1,parseInt(b.substr(8,2)));if(19==b.length)return new Date(parseInt(b.substr(0,
+4)),parseInt(b.substr(5,2))-1,parseInt(b.substr(8,2)),parseInt(b.substr(11,2)),parseInt(b.substr(14,2)),parseInt(b.substr(17,2)));this._logWarn("Given date is no properly formatted: "+b);return new Date},_showError:function(b){this._$errorDialogDiv.html(b).dialog("open")},_showBusy:function(b){this._$busyMessageDiv.is(":visible")||(this._$busyDiv.width(this._$mainContainer.width()),this._$busyDiv.height(this._$mainContainer.height()),this._$busyDiv.show(),this._$busyMessageDiv.show());this._$busyMessageDiv.html(b)},
+_hideBusy:function(){this._$busyDiv.hide();this._$busyMessageDiv.html("").hide()},_isBusy:function(){return this._$busyMessageDiv.is(":visible")},_performAjaxCall:function(b,a,f,d,i){c.ajax({url:b,type:"POST",dataType:"json",data:a,async:f,success:function(a){d(a)},error:function(){i()}})},getRowByKey:function(b){for(var a=0;a<this._$tableRows.length;a++)if(b==this._$tableRows[a].data("record")[this._keyField])return this._$tableRows[a];return null},_onLoadingRecords:function(){this._trigger("loadingRecords",
+null,{})},_onRecordsLoaded:function(b){this._trigger("recordsLoaded",null,{records:b.Records,serverResponse:b})},_onRowInserted:function(b,a){this._trigger("rowInserted",null,{row:b,record:b.data("record"),isNewRow:a})},_onRowsRemoved:function(b,a){this._trigger("rowsRemoved",null,{rows:b,reason:a})},_onCloseRequested:function(){this._trigger("closeRequested",null,{})}})})(jQuery);
+(function(c){c.extend(!0,c.hik.jtable.prototype,{_getPropertyOfObject:function(b,a){if(a.indexOf(".")<0)return b[a];var c=a.substring(0,a.indexOf(".")),d=a.substring(a.indexOf(".")+1);return this._getPropertyOfObject(b[c],d)},_setPropertyOfObject:function(b,a,c){if(a.indexOf(".")<0)b[a]=c;else{var d=a.substring(0,a.indexOf(".")),a=a.substring(a.indexOf(".")+1);this._setPropertyOfObject(b[d],a,c)}},_insertToArrayIfDoesNotExists:function(b,a){c.inArray(a,b)<0&&b.push(a)},_findIndexInArray:function(b,
+a,c){c||(c=function(a,d){return a==d});for(var d=0;d<a.length;d++)if(c(b,a[d]))return d;return-1},_normalizeNumber:function(b,a,c,d){return b==void 0||b==null?d:b<a?a:b>c?c:b},_formatString:function(){if(arguments.length==0)return null;for(var b=arguments[0],a=1;a<arguments.length;a++)b=b.replace("{"+(a-1)+"}",arguments[a]);return b},_logDebug:function(b){window.console&&console.log("jTable DEBUG: "+b)},_logInfo:function(b){window.console&&console.log("jTable INFO: "+b)},_logWarn:function(b){window.console&&
+console.log("jTable WARNING: "+b)},_logError:function(b){window.console&&console.log("jTable ERROR: "+b)}})})(jQuery);
+(function(c){c.extend(!0,c.hik.jtable.prototype,{_submitFormUsingAjax:function(b,a,c,d){this._performAjaxCall(b,a,true,c,d)},_createInputLabelForRecordField:function(b){return c('<div class="jtable-input-label">'+this.options.fields[b].title+"</div>")},_createInputForRecordField:function(b,a,f){var d=this.options.fields[b];if(a==void 0)a=d.defaultValue;if(d.input){a=c(d.input({value:a,record:f}));a.attr("id")||a.attr("id","Edit-"+b);return a}return d.type=="date"?this._createDateInputForField(d,b,
+a):d.type=="textarea"?this._createTextAreaForField(d,b,a):d.type=="password"?this._createPasswordInputForField(d,b,a):d.type=="checkbox"?this._createCheckboxForField(d,b,a):d.options?d.type=="radiobutton"?this._createRadioButtonListForField(d,b,a):this._createDropDownListForField(d,b,a):this._createTextInputForField(d,b,a)},_createInputForHidden:function(b,a){if(a==void 0||a==null)a="";return c('<input type="hidden" value="'+a+'" name="'+b+'" id="Edit-'+b+'"></input>')},_createDateInputForField:function(b,
+a,f){a=c('<input class="'+b.inputClass+'" id="Edit-'+a+'" type="text"'+(f!=void 0?'value="'+f+'"':"")+' name="'+a+'"></input>');a.datepicker({dateFormat:b.displayFormat||this.options.defaultDateFormat});return c('<div class="jtable-input jtable-date-input"></div>').append(a)},_createTextAreaForField:function(b,a,f){return c('<div class="jtable-input jtable-textarea-input"><textarea class="'+b.inputClass+'" id="Edit-'+a+'" name="'+a+'">'+(f||"")+"</textarea></div>")},_createTextInputForField:function(b,
+a,f){return c('<div class="jtable-input jtable-text-input"><input class="'+b.inputClass+'" id="Edit-'+a+'" type="text"'+(f!=void 0?'value="'+f+'"':"")+' name="'+a+'"></input></div>')},_createPasswordInputForField:function(b,a,f){return c('<div class="jtable-input jtable-password-input"><input class="'+b.inputClass+'" id="Edit-'+a+'" type="password"'+(f!=void 0?'value="'+f+'"':"")+' name="'+a+'"></input></div>')},_createCheckboxForField:function(b,a,f){var d=this;f==void 0&&(f=f||d._getCheckBoxPropertiesForFieldByState(a,
+false).Value);var i=c('<div class="jtable-input jtable-checkbox-input"></div>'),e=c('<input class="'+b.inputClass+'" id="Edit-'+a+'" type="checkbox" name="'+a+'" value="'+f+'" />').appendTo(i),g=c("<span>"+(b.formText||d._getCheckBoxTextForFieldByValue(a,f))+"</span>").appendTo(i);d._getIsCheckBoxSelectedForFieldByValue(a,f)&&e.attr("checked","checked");var h=function(){var c=d._getCheckBoxPropertiesForFieldByState(a,e.is(":checked"));e.attr("value",c.Value);g.html(b.formText||c.DisplayText)};e.click(function(){h()});
+if(b.setOnTextClick!=false){g.addClass("jtable-option-text-clickable");g.click(function(){e.is(":checked")?e.attr("checked",false):e.attr("checked",true);h()})}return i},_createDropDownListForField:function(b,a,f){var d=c('<div class="jtable-input jtable-dropdown-input"></div>'),i=c('<select class="'+b.inputClass+'" id="Edit-'+a+'" name='+a+"></select>").appendTo(d),b=this._getOptionsWithCaching(a);c.each(b,function(a,d){i.append('<option value="'+a+'"'+(a==f?' selected="selected"':"")+">"+d+"</option>")});
+return d},_createRadioButtonListForField:function(b,a,f){var d=c('<div class="jtable-input jtable-radiobuttonlist-input"></div>'),i=this._getOptionsWithCaching(a),e=0;c.each(i,function(g,i){var j=c('<div class="jtable-radio-input"></div>').appendTo(d),k=c('<input type="radio" id="Edit-'+a+e++ +'" class="'+b.inputClass+'" name="'+a+'" value="'+g+'"'+(g==f?' checked="true"':"")+" />").appendTo(j),j=c("<span>"+i+"</span>").appendTo(j);if(b.setOnTextClick!=false){j.addClass("jtable-option-text-clickable");
+j.click(function(){k.is(":checked")||k.attr("checked",true)})}});return d},_getCheckBoxTextForFieldByValue:function(b,a){return this.options.fields[b].values[a]},_getIsCheckBoxSelectedForFieldByValue:function(b,a){return this._createCheckBoxStateArrayForFieldWithCaching(b)[1].Value.toString()==a.toString()},_getCheckBoxPropertiesForFieldByState:function(b,a){return this._createCheckBoxStateArrayForFieldWithCaching(b)[a?1:0]},_createCheckBoxStateArrayForFieldWithCaching:function(b){var a="checkbox_"+
+b;this._cache[a]||(this._cache[a]=this._createCheckBoxStateArrayForField(b));return this._cache[a]},_createCheckBoxStateArrayForField:function(b){var a=[],f=0;c.each(this.options.fields[b].values,function(d,b){f++<2&&a.push({Value:d,DisplayText:b})});return a},_getOptionsWithCaching:function(b){var a="options_"+b;if(!this._cache[a]){var c=this.options.fields[b].options;this._cache[a]=typeof c=="string"?this._downloadOptions(b,c):jQuery.isArray(c)?this._buildOptionsFromArray(c):c}return this._cache[a]},
+_downloadOptions:function(b,a){var c=this,d={};c._performAjaxCall(a,void 0,false,function(a){if(a.Result!="OK")c._showError(a.Message);else for(var b=0;b<a.Options.length;b++)d[a.Options[b].Value]=a.Options[b].DisplayText},function(){var a=c._formatString(c.options.messages.cannotLoadOptionsFor,b);c._showError(a)});return d},_buildOptionsFromArray:function(b){for(var a={},c=0;c<b.length;c++)a[b[c]]=b[c];return a},_setEnabledOfDialogButton:function(b,a,c){if(b){a!=false?b.removeAttr("disabled").removeClass("ui-state-disabled"):
+b.attr("disabled","disabled").addClass("ui-state-disabled");c&&b.find("span").text(c)}}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._create;c.extend(!0,c.hik.jtable.prototype,{options:{recordAdded:function(){},messages:{addNewRecord:"+ Add new record"}},_$addRecordDiv:null,_create:function(){b.apply(this,arguments);this._createAddRecordDialogDiv()},_createAddRecordDialogDiv:function(){var a=this;if(a.options.actions.createAction){a._$addRecordDiv=c("<div></div>").appendTo(a._$mainContainer);a._$addRecordDiv.dialog({autoOpen:false,show:a.options.dialogShowEffect,hide:a.options.dialogHideEffect,
+width:"auto",minWidth:"300",modal:true,title:a.options.messages.addNewRecord,buttons:[{text:a.options.messages.cancel,click:function(){a._$addRecordDiv.dialog("close")}},{id:"AddRecordDialogSaveButton",text:a.options.messages.save,click:function(){var b=c("#AddRecordDialogSaveButton"),d=a._$addRecordDiv.find("form");if(a._trigger("formSubmitting",null,{form:d,formType:"create"})!=false){a._setEnabledOfDialogButton(b,false,a.options.messages.saving);a._saveAddRecordForm(d,b)}}}],close:function(){var b=
+a._$addRecordDiv.find("form").first(),d=c("#AddRecordDialogSaveButton");a._trigger("formClosed",null,{form:b,formType:"create"});a._setEnabledOfDialogButton(d,true,a.options.messages.save);b.remove()}});if(!a.options.addRecordButton)a.options.addRecordButton=a._createAddRecordButton();a.options.addRecordButton.click(function(b){b.preventDefault();a._showAddRecordForm()})}},_createAddRecordButton:function(){return c('<span class="jtable-add-record"><a href="#">'+this.options.messages.addNewRecord+
+"</a></span>").appendTo(this._$bottomPanel.find(".jtable-right-area"))},showCreateForm:function(){this._showAddRecordForm()},addRecord:function(a){var b=this,a=c.extend({clientOnly:false,animationsEnabled:b.options.animationsEnabled,url:b.options.actions.createAction,success:function(){},error:function(){}},a);if(a.record)if(a.clientOnly){b._addRowToTable(b._createRowFromRecord(a.record),null,true,a.animationsEnabled);a.success()}else b._submitFormUsingAjax(a.url,c.param(a.record),function(d){if(d.Result!=
+"OK"){b._showError(d.Message);a.error(d)}else{b._onRecordAdded(d);b._addRowToTable(b._createRowFromRecord(d.Record),null,true,a.animationsEnabled);a.success(d)}},function(){b._showError(b.options.messages.serverCommunicationError);a.error()});else b._logWarn("options parameter in addRecord method must contain a record property.")},_showAddRecordForm:function(){for(var a=c('<form id="jtable-create-form" class="jtable-dialog-form jtable-create-form" action="'+this.options.actions.createAction+'" method="POST"></form>'),
+b=0;b<this._fieldList.length;b++)if(this.options.fields[this._fieldList[b]].create!=false)if(this.options.fields[this._fieldList[b]].type=="hidden")a.append(this._createInputForHidden(this._fieldList[b],this.options.fields[this._fieldList[b]].defaultValue));else{var d=c('<div class="jtable-input-field-container"></div>').appendTo(a);d.append(this._createInputLabelForRecordField(this._fieldList[b]));d.append(this._createInputForRecordField(this._fieldList[b]))}this._$addRecordDiv.append(a).dialog("open");
+this._trigger("formCreated",null,{form:a,formType:"create"})},_saveAddRecordForm:function(a,b){var d=this;a.data("submitting",true);d._submitFormUsingAjax(a.attr("action"),a.serialize(),function(a){if(a.Result!="OK"){d._showError(a.Message);d._setEnabledOfDialogButton(b,true,d.options.messages.save)}else{d._onRecordAdded(a);d._addRowToTable(d._createRowFromRecord(a.Record),null,true);d._$addRecordDiv.dialog("close")}},function(){d._showError(d.options.messages.serverCommunicationError);d._setEnabledOfDialogButton(b,
+true,d.options.messages.save)})},_onRecordAdded:function(a){this._trigger("recordAdded",null,{record:a.Record,serverResponse:a})}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._create,a=c.hik.jtable.prototype._addColumnsToHeaderRow,f=c.hik.jtable.prototype._addCellsToRowUsingRecord;c.extend(!0,c.hik.jtable.prototype,{options:{recordUpdated:function(){},rowUpdated:function(){},messages:{editRecord:"Edit Record"}},_$editDiv:null,_$editingRow:null,_create:function(){b.apply(this,arguments);this._createEditDialogDiv()},_createEditDialogDiv:function(){var a=this;a._$editDiv=c("<div></div>").appendTo(a._$mainContainer);a._$editDiv.dialog({autoOpen:false,
+show:a.options.dialogShowEffect,hide:a.options.dialogHideEffect,width:"auto",minWidth:"300",modal:true,title:a.options.messages.editRecord,buttons:[{text:a.options.messages.cancel,click:function(){a._$editDiv.dialog("close")}},{id:"EditDialogSaveButton",text:a.options.messages.save,click:function(){var b=a._$editDiv.find("#EditDialogSaveButton"),c=a._$editDiv.find("form");if(a._trigger("formSubmitting",null,{form:c,formType:"edit"})!=false){a._setEnabledOfDialogButton(b,false,a.options.messages.saving);
+a._saveEditForm(c,b)}}}],close:function(){var b=a._$editDiv.find("form:first"),e=c("#EditDialogSaveButton");a._trigger("formClosed",null,{form:b,formType:"edit"});a._setEnabledOfDialogButton(e,true,a.options.messages.save);b.remove()}})},updateRecord:function(a){var b=this,a=c.extend({clientOnly:false,animationsEnabled:b.options.animationsEnabled,url:b.options.actions.updateAction,success:function(){},error:function(){}},a),e=a.record[b._keyField];if(!a.record||!e)b._logWarn("options parameter in updateRecord method must contain a record that contains the key field property.");
+else{var g=b.getRowByKey(e);if(g==null)b._logWarn("Can not found any row by key: "+e);else if(a.clientOnly){c.extend(g.data("record"),a.record);b._updateRowTexts(g);b._onRecordUpdated(g,null);a.animationsEnabled&&b._showUpdateAnimationForRow(g);a.success()}else b._submitFormUsingAjax(a.url,c.param(a.record),function(e){if(e.Result!="OK"){b._showError(e.Message);a.error(e)}else{c.extend(g.data("record"),a.record);b._updateRowTexts(g);b._onRecordUpdated(g,e);a.animationsEnabled&&b._showUpdateAnimationForRow(g);
+a.success(e)}},function(){b._showError(b.options.messages.serverCommunicationError);a.error()})}},_addColumnsToHeaderRow:function(b){a.apply(this,arguments);this.options.actions.updateAction!=void 0&&b.append(this._createEmptyCommandHeader())},_addCellsToRowUsingRecord:function(a){var b=this;f.apply(this,arguments);if(b.options.actions.updateAction!=void 0){var e=c('<td class="jtable-command-column"></td>').appendTo(a);c('<button class="jtable-command-button jtable-edit-command-button" title="'+b.options.messages.editRecord+
+'"><span>'+b.options.messages.editRecord+"</span></button>").appendTo(e).click(function(c){c.preventDefault();c.stopPropagation();b._showEditForm(a)})}},_showEditForm:function(a){for(var b=a.data("record"),e=c('<form id="jtable-edit-form" class="jtable-dialog-form jtable-edit-form" action="'+this.options.actions.updateAction+'" method="POST"></form>'),g=0;g<this._fieldList.length;g++)if(this.options.fields[this._fieldList[g]].key==true)e.append(this._createInputForHidden(this._fieldList[g],b[this._fieldList[g]]));
+else if(this.options.fields[this._fieldList[g]].edit!=false)if(this.options.fields[this._fieldList[g]].type=="hidden")e.append(this._createInputForHidden(this._fieldList[g],b[this._fieldList[g]]));else{var h=c('<div class="jtable-input-field-container"></div>').appendTo(e);h.append(this._createInputLabelForRecordField(this._fieldList[g]));var j=this._getValueForRecordField(b,this._fieldList[g]);h.append(this._createInputForRecordField(this._fieldList[g],j,b))}this._$editingRow=a;this._$editDiv.append(e).dialog("open");
+this._trigger("formCreated",null,{form:e,formType:"edit",record:b})},_saveEditForm:function(a,b){var c=this;c._submitFormUsingAjax(a.attr("action"),a.serialize(),function(g){if(g.Result!="OK"){c._showError(g.Message);c._setEnabledOfDialogButton(b,true,c.options.messages.save)}else{var h=c._$editingRow;c._updateRecordValuesFromEditForm(h.data("record"),a);c._updateRowTexts(h);c._onRecordUpdated(h,g);c.options.animationsEnabled&&c._showUpdateAnimationForRow(h);c._$editDiv.dialog("close")}},function(){c._showError(c.options.messages.serverCommunicationError);
+c._setEnabledOfDialogButton(b,true,c.options.messages.save)})},_updateRecordValuesFromEditForm:function(a,b){for(var e=0;e<this._fieldList.length;e++){var g=this._fieldList[e],h=this.options.fields[g];if(h.edit!=false){var j=b.find('[name="'+g+'"]');if(h.type=="date"){h=h.displayFormat||this.options.defaultDateFormat;try{var f=c.datepicker.parseDate(h,j.val());a[g]="/Date("+f.getTime()+")/"}catch(m){a[g]="/Date("+(new Date).getTime()+")/"}}else if(h.options&&h.type=="radiobutton"){j=j.filter('[checked="true"]');
+a[g]=j.length?j.val():void 0}else a[g]=j.val()}}},_getValueForRecordField:function(a,b){var c=this.options.fields[b],g=a[b];return c.type=="date"?this._getDisplayTextForDateRecordField(c,g):g},_updateRowTexts:function(a){for(var b=a.data("record"),c=a.find("td"),g=0;g<this._columnList.length;g++){var h=this._getDisplayTextForRecordField(b,this._columnList[g]);c.eq(this._firstDataColumnOffset+g).html(h||"")}this._onRowUpdated(a)},_showUpdateAnimationForRow:function(a){a.stop(true,true).addClass("jtable-row-updated",
+"slow","",function(){a.removeClass("jtable-row-updated",5E3)})},_onRowUpdated:function(a){this._trigger("rowUpdated",null,{row:a,record:a.data("record")})},_onRecordUpdated:function(a,b){this._trigger("recordUpdated",null,{record:a.data("record"),row:a,serverResponse:b})}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._create,a=c.hik.jtable.prototype._addColumnsToHeaderRow,f=c.hik.jtable.prototype._addCellsToRowUsingRecord;c.extend(!0,c.hik.jtable.prototype,{options:{deleteConfirmation:!0,recordDeleted:function(){},messages:{deleteConfirmation:"This record will be deleted. Are you sure?",deleteText:"Delete",deleting:"Deleting",canNotDeletedRecords:"Can not deleted {0} of {1} records!",deleteProggress:"Deleted {0} of {1} records, processing..."}},_$deleteRecordDiv:null,
+_$deletingRow:null,_create:function(){b.apply(this,arguments);this._createDeleteDialogDiv()},_createDeleteDialogDiv:function(){var a=this;a._$deleteRecordDiv=c('<div><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span><span class="jtable-delete-confirm-message"></span></p></div>').appendTo(a._$mainContainer);a._$deleteRecordDiv.dialog({autoOpen:false,show:a.options.dialogShowEffect,hide:a.options.dialogHideEffect,modal:true,title:a.options.messages.areYouSure,buttons:[{text:a.options.messages.cancel,
+click:function(){a._$deleteRecordDiv.dialog("close")}},{id:"DeleteDialogButton",text:a.options.messages.deleteText,click:function(){var b=c("#DeleteDialogButton");a._setEnabledOfDialogButton(b,false,a.options.messages.deleting);a._deleteRecordFromServer(a._$deletingRow,function(){a._removeRowsFromTableWithAnimation(a._$deletingRow);a._$deleteRecordDiv.dialog("close")},function(c){a._showError(c);a._setEnabledOfDialogButton(b,true,a.options.messages.deleteText)})}}],close:function(){var b=c("#DeleteDialogButton");
+a._setEnabledOfDialogButton(b,true,a.options.messages.deleteText)}})},deleteRows:function(a){var b=this;if(!(a.length<=0||b._isBusy()))if(a.length==1)b._deleteRecordFromServer(a,function(){b._removeRowsFromTableWithAnimation(a)},function(a){b._showError(a)});else{b._showBusy(b._formatString(b.options.messages.deleteProggress,0,a.length));var e=0,g=function(){var c=a.filter(".jtable-row-ready-to-remove");c.length<a.length&&b._showError(b._formatString(b.options.messages.canNotDeletedRecords,a.length-
+c.length,a.length));c.length>0&&b._removeRowsFromTableWithAnimation(c);b._hideBusy()},h=0;a.each(function(){var f=c(this);b._deleteRecordFromServer(f,function(){++h;++e;f.addClass("jtable-row-ready-to-remove");b._showBusy(b._formatString(b.options.messages.deleteProggress,h,a.length));e>=a.length&&g()},function(){++e;e>=a.length&&g()})})}},deleteRecord:function(a){var b=this,a=c.extend({clientOnly:false,animationsEnabled:b.options.animationsEnabled,url:b.options.actions.deleteAction,success:function(){},
+error:function(){}},a);if(a.key){var e=b.getRowByKey(a.key);if(e==null)b._logWarn("Can not found any row by key: "+a.key);else if(a.clientOnly){b._removeRowsFromTableWithAnimation(e,a.animationsEnabled);a.success()}else b._deleteRecordFromServer(e,function(c){b._removeRowsFromTableWithAnimation(e,a.animationsEnabled);a.success(c)},function(c){b._showError(c);a.error(c)},a.url)}else b._logWarn("options parameter in deleteRecord method must contain a record key.")},_addColumnsToHeaderRow:function(b){a.apply(this,
+arguments);this.options.actions.deleteAction!=void 0&&b.append(this._createEmptyCommandHeader())},_addCellsToRowUsingRecord:function(a){f.apply(this,arguments);var b=this;if(b.options.actions.deleteAction!=void 0){var e=c('<td class="jtable-command-column"></td>').appendTo(a);c('<button class="jtable-command-button jtable-delete-command-button" title="'+b.options.messages.deleteText+'"><span>'+b.options.messages.deleteText+"</span></button>").appendTo(e).click(function(c){c.preventDefault();c.stopPropagation();
+b._deleteButtonClickedForRow(a)})}},_deleteButtonClickedForRow:function(a){var b=this,e,g=b.options.messages.deleteConfirmation;if(c.isFunction(b.options.deleteConfirmation)){e={row:a,record:a.data("record"),deleteConfirm:true,deleteConfirmMessage:g,cancel:false,cancelMessage:null};b.options.deleteConfirmation(e);if(e.cancel){e.cancelMessage&&b._showError(e.cancelMessage);return}g=e.deleteConfirmMessage;e=e.deleteConfirm}else e=b.options.deleteConfirmation;if(e!=false){b._$deleteRecordDiv.find(".jtable-delete-confirm-message").html(g);
+b._showDeleteDialog(a)}else b._deleteRecordFromServer(a,function(){b._removeRowsFromTableWithAnimation(a)},function(a){b._showError(a)})},_showDeleteDialog:function(a){this._$deletingRow=a;this._$deleteRecordDiv.dialog("open")},_deleteRecordFromServer:function(a,b,c,g){var h=this;if(a.data("deleting")!=true){a.data("deleting",true);var f={};f[h._keyField]=a.data("record")[h._keyField];h._performAjaxCall(g||h.options.actions.deleteAction,f,true,function(g){if(g.Result!="OK"){a.data("deleting",false);
+c&&c(g.Message)}else{h._trigger("recordDeleted",null,{record:a.data("record"),row:a,serverResponse:g});b&&b(g)}},function(){a.data("deleting",false);c&&c(h.options.messages.serverCommunicationError)})}},_removeRowsFromTableWithAnimation:function(a,b){var c=this;if(b==void 0)b=c.options.animationsEnabled;b?a.stop(true,true).addClass("jtable-row-deleting","slow","").promise().done(function(){c._removeRowsFromTable(a,"deleted")}):c._removeRowsFromTable(a,"deleted")}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._create,a=c.hik.jtable.prototype._addColumnsToHeaderRow,f=c.hik.jtable.prototype._addCellsToRowUsingRecord,d=c.hik.jtable.prototype._onLoadingRecords,i=c.hik.jtable.prototype._onRecordsLoaded,e=c.hik.jtable.prototype._onRowsRemoved;c.extend(!0,c.hik.jtable.prototype,{options:{selecting:!1,multiselect:!1,selectingCheckboxes:!1,selectOnRowClick:!0,selectionChanged:function(){}},_selectedRecordIdsBeforeLoad:null,_$selectAllCheckbox:null,_shiftKeyDown:!1,_create:function(){this.options.selecting&&
+this.options.selectingCheckboxes&&++this._firstDataColumnOffset;this._bindKeyboardEvents();b.apply(this,arguments)},_bindKeyboardEvents:function(){var a=this;c(document).keydown(function(b){switch(b.which){case 16:a._shiftKeyDown=true}}).keyup(function(b){switch(b.which){case 16:a._shiftKeyDown=false}})},selectedRows:function(){return this._getSelectedRows()},_addColumnsToHeaderRow:function(b){this.options.selecting&&this.options.selectingCheckboxes&&(this.options.multiselect?b.append(this._createSelectAllHeader()):
+b.append(this._createEmptyCommandHeader()));a.apply(this,arguments)},_addCellsToRowUsingRecord:function(a){this.options.selecting&&this._makeRowSelectable(a);f.apply(this,arguments)},_onLoadingRecords:function(){this._storeSelectionList();d.apply(this,arguments)},_onRecordsLoaded:function(){this._restoreSelectionList();i.apply(this,arguments)},_onRowsRemoved:function(a,b){b!="reloading"&&(this.options.selecting&&a.filter(".jtable-row-selected").length>0)&&this._onSelectionChanged();e.apply(this,arguments)},
+_createSelectAllHeader:function(){var a=this,b=c('<th class="jtable-command-column-header jtable-column-header-selecting"></th>'),e=c('<div class="jtable-column-header-container"></div>').appendTo(b);a._$selectAllCheckbox=c('<input type="checkbox" />').appendTo(e);a._$selectAllCheckbox.click(function(){if(a._$tableRows.length<=0)a._$selectAllCheckbox.attr("checked",false);else{var b=a._$tableBody.find("tr");a._$selectAllCheckbox.is(":checked")?a._selectRows(b):a._deselectRows(b);a._onSelectionChanged()}});
+return b},_storeSelectionList:function(){var a=this;if(a.options.selecting){a._selectedRecordIdsBeforeLoad=[];a._getSelectedRows().each(function(){a._selectedRecordIdsBeforeLoad.push(c(this).data("record")[a._keyField])})}},_restoreSelectionList:function(){if(this.options.selecting){for(var a=0,b=0;b<this._$tableRows.length;++b)if(c.inArray(this._$tableRows[b].data("record")[this._keyField],this._selectedRecordIdsBeforeLoad)>-1){this._selectRows(this._$tableRows[b]);++a}this._selectedRecordIdsBeforeLoad.length>
+0&&this._selectedRecordIdsBeforeLoad.length!=a&&this._onSelectionChanged();this._selectedRecordIdsBeforeLoad=[];this._refreshSelectAllCheckboxState()}},_getSelectedRows:function(){return this._$tableBody.find(".jtable-row-selected")},_makeRowSelectable:function(a){var b=this;b.options.selectOnRowClick&&a.click(function(){b._invertRowSelection(a)});if(b.options.selectingCheckboxes){var e=c('<td class="jtable-selecting-column"></td>'),d=c('<input type="checkbox" />').appendTo(e);b.options.selectOnRowClick||
+d.click(function(){b._invertRowSelection(a)});a.append(e)}},_invertRowSelection:function(a){if(a.hasClass("jtable-row-selected"))this._deselectRows(a);else if(this._shiftKeyDown){var b=this._findRowIndex(a),c=this._findFirstSelectedRowIndexBeforeIndex(b)+1;if(c>0&&c<b)this._selectRows(this._$tableBody.find("tr").slice(c,b+1));else{c=this._findFirstSelectedRowIndexAfterIndex(b)-1;c>b?this._selectRows(this._$tableBody.find("tr").slice(b,c+1)):this._selectRows(a)}}else this._selectRows(a);this._onSelectionChanged()},
+_findFirstSelectedRowIndexBeforeIndex:function(a){for(a=a-1;a>=0;--a)if(this._$tableRows[a].hasClass("jtable-row-selected"))return a;return-1},_findFirstSelectedRowIndexAfterIndex:function(a){for(a=a+1;a<this._$tableRows.length;++a)if(this._$tableRows[a].hasClass("jtable-row-selected"))return a;return-1},_selectRows:function(a){this.options.multiselect||this._deselectRows(this._getSelectedRows());a.addClass("jtable-row-selected");this.options.selectingCheckboxes&&a.find("td.jtable-selecting-column input").attr("checked",
+true);this._refreshSelectAllCheckboxState()},_deselectRows:function(a){a.removeClass("jtable-row-selected");this.options.selectingCheckboxes&&a.find("td.jtable-selecting-column input").removeAttr("checked");this._refreshSelectAllCheckboxState()},_refreshSelectAllCheckboxState:function(){if(this.options.selectingCheckboxes&&this.options.multiselect){var a=this._$tableRows.length,b=this._getSelectedRows().length;if(b==0){this._$selectAllCheckbox.prop("indeterminate",false);this._$selectAllCheckbox.attr("checked",
+false)}else if(b==a){this._$selectAllCheckbox.prop("indeterminate",false);this._$selectAllCheckbox.attr("checked",true)}else{this._$selectAllCheckbox.attr("checked",false);this._$selectAllCheckbox.prop("indeterminate",true)}}},_onSelectionChanged:function(){this._trigger("selectionChanged",null,{})}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype.load,a=c.hik.jtable.prototype._create,f=c.hik.jtable.prototype._createRecordLoadUrl,d=c.hik.jtable.prototype._addRowToTable,i=c.hik.jtable.prototype._removeRowsFromTable,e=c.hik.jtable.prototype._onRecordsLoaded;c.extend(!0,c.hik.jtable.prototype,{options:{paging:!1,pageSize:10,messages:{pagingInfo:"Showing {0} to {1} of {2} records"}},_$pagingListArea:null,_totalRecordCount:0,_currentPageNo:1,_create:function(){a.apply(this,arguments);this._createPageListArea()},
+_createPageListArea:function(){if(this.options.paging)this._$pagingListArea=c('<span class="jtable-page-list"></span>').prependTo(this._$bottomPanel.find(".jtable-left-area"))},load:function(){this._currentPageNo=1;b.apply(this,arguments)},_createRecordLoadUrl:function(){var a=f.apply(this,arguments);return a=this._addPagingInfoToUrl(a,this._currentPageNo)},_addRowToTable:function(a,b,c){c&&this.options.paging?this._reloadTable():d.apply(this,arguments)},_removeRowsFromTable:function(a,b){i.apply(this,
+arguments);if(this.options.paging){this._$tableRows.length<=0&&this._currentPageNo>1&&--this._currentPageNo;this._reloadTable()}},_onRecordsLoaded:function(a){this._totalRecordCount=a.TotalRecordCount;this._createPagingList();e.apply(this,arguments)},_addPagingInfoToUrl:function(a,b){if(!this.options.paging)return a;var c=(b-1)*this.options.pageSize,e=this.options.pageSize;return a+(a.indexOf("?")<0?"?":"&")+"jtStartIndex="+c+"&jtPageSize="+e},_createPagingList:function(){if(this.options.paging&&
+!(this.options.pageSize<=0)){this._$pagingListArea.empty();var a=this._calculatePageCount();this._createFirstAndPreviousPageButtons();this._createPageNumberButtons(this._calculatePageNumbers(a));this._createLastAndNextPageButtons(a);this._createPagingInfo();this._bindClickEventsToPageNumberButtons()}},_createFirstAndPreviousPageButtons:function(){if(this._currentPageNo>1){c('<span class="jtable-page-number-first">|&lt</span>').data("pageNumber",1).appendTo(this._$pagingListArea);c('<span class="jtable-page-number-previous">&lt</span>').data("pageNumber",
+this._currentPageNo-1).appendTo(this._$pagingListArea)}},_createLastAndNextPageButtons:function(a){if(this._currentPageNo<a){c('<span class="jtable-page-number-next">&gt</span>').data("pageNumber",this._currentPageNo+1).appendTo(this._$pagingListArea);c('<span class="jtable-page-number-last">&gt|</span>').data("pageNumber",a).appendTo(this._$pagingListArea)}},_createPageNumberButtons:function(a){for(var b=0,e=0;e<a.length;e++){a[e]-b>1&&c('<span class="jtable-page-number-space">...</span>').appendTo(this._$pagingListArea);
+this._createPageNumberButton(a[e]);b=a[e]}},_createPageNumberButton:function(a){c('<span class="'+(this._currentPageNo==a?"jtable-page-number-active":"jtable-page-number")+'">'+a+"</span>").data("pageNumber",a).appendTo(this._$pagingListArea)},_calculatePageCount:function(){var a=Math.floor(this._totalRecordCount/this.options.pageSize);this._totalRecordCount%this.options.pageSize!=0&&++a;return a},_calculatePageNumbers:function(a){if(a<=6){for(var b=[],c=1;c<=a;++c)b.push(c);return b}b=[1,2,3,a-2,
+a-1,a];c=this._normalizeNumber(this._currentPageNo-1,1,a,1);a=this._normalizeNumber(this._currentPageNo+1,1,a,1);this._insertToArrayIfDoesNotExists(b,c);this._insertToArrayIfDoesNotExists(b,this._currentPageNo);this._insertToArrayIfDoesNotExists(b,a);b.sort(function(a,b){return a-b});return b},_createPagingInfo:function(){var a=(this._currentPageNo-1)*this.options.pageSize+1,b=this._currentPageNo*this.options.pageSize,b=this._normalizeNumber(b,a,this._totalRecordCount,0);if(b>=a){a=this._formatString(this.options.messages.pagingInfo,
+a,b,this._totalRecordCount);c('<span class="jtable-page-info">'+a+"</span>").appendTo(this._$pagingListArea)}},_bindClickEventsToPageNumberButtons:function(){var a=this;a._$pagingListArea.find(".jtable-page-number,.jtable-page-number-previous,.jtable-page-number-next,.jtable-page-number-first,.jtable-page-number-last").click(function(b){b.preventDefault();b=c(this);a._currentPageNo=b.data("pageNumber");a._reloadTable()})}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._normalizeFieldOptions,a=c.hik.jtable.prototype._createHeaderCellForField,f=c.hik.jtable.prototype._createRecordLoadUrl;c.extend(!0,c.hik.jtable.prototype,{options:{sorting:!1,defaultSorting:""},_lastSorting:"",_normalizeFieldOptions:function(a,c){b.apply(this,arguments);c.sorting=c.sorting!=false},_createHeaderCellForField:function(b,c){var e=a.apply(this,arguments);this.options.sorting&&c.sorting&&this._makeColumnSortable(e,b);return e},_createRecordLoadUrl:function(){var a=
+f.apply(this,arguments);return a=this._addSortingInfoToUrl(a)},_makeColumnSortable:function(a,b){var c=this;a.addClass("jtable-column-header-sortable").click(function(b){b.preventDefault();c._sortTableByColumn(a)});if(c.options.defaultSorting.indexOf(b)>-1)if(c.options.defaultSorting.indexOf("DESC")>-1){a.addClass("jtable-column-header-sorted-desc");c._lastSorting=b+" DESC"}else{a.addClass("jtable-column-header-sorted-asc");c._lastSorting=b+" ASC"}},_sortTableByColumn:function(a){a.siblings().removeClass("jtable-column-header-sorted-asc jtable-column-header-sorted-desc");
+if(a.hasClass("jtable-column-header-sorted-asc")){a.removeClass("jtable-column-header-sorted-asc").addClass("jtable-column-header-sorted-desc");this._lastSorting=a.data("fieldName")+" DESC"}else{a.removeClass("jtable-column-header-sorted-desc").addClass("jtable-column-header-sorted-asc");this._lastSorting=a.data("fieldName")+" ASC"}this._reloadTable()},_addSortingInfoToUrl:function(a){return!this.options.sorting||this._lastSorting==""?a:a+(a.indexOf("?")<0?"?":"&")+"jtSorting="+this._lastSorting}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._create,a=c.hik.jtable.prototype._normalizeFieldOptions,f=c.hik.jtable.prototype._createHeaderCellForField,d=c.hik.jtable.prototype._createCellForRecordField;c.extend(!0,c.hik.jtable.prototype,{options:{tableId:void 0,columnResizable:!0,columnSelectable:!0,saveUserPreferences:!0},_$columnSelectionDiv:null,_$columnResizeBar:null,_cookieKeyPrefix:null,_currentResizeArgs:null,_create:function(){b.apply(this,arguments);this._createColumnResizeBar();this._createColumnSelection();
+this._cookieKeyPrefix=this._generateCookieKeyPrefix();this.options.saveUserPreferences&&this._loadColumnSettings();this._normalizeColumnWidths()},_normalizeFieldOptions:function(b,c){a.apply(this,arguments);if(this.options.columnResizable)c.columnResizable=c.columnResizable!=false;if(!c.visibility)c.visibility="visible"},_createHeaderCellForField:function(a,b){var c=f.apply(this,arguments);this.options.columnResizable&&(b.columnResizable&&a!=this._columnList[this._columnList.length-1])&&this._makeColumnResizable(c);
+b.visibility=="hidden"&&c.hide();return c},_createCellForRecordField:function(a,b){var c=d.apply(this,arguments);this.options.fields[b].visibility=="hidden"&&c.hide();return c},changeColumnVisibility:function(a,b){this._changeColumnVisibilityInternal(a,b);this._normalizeColumnWidths();this.options.saveUserPreferences&&this._saveColumnSettings()},_changeColumnVisibilityInternal:function(a,b){var c=this._columnList.indexOf(a);if(c<0)this._logWarn('Column "'+a+'" does not exist in fields!');else if(["visible",
+"hidden","fixed"].indexOf(b)<0)this._logWarn('Visibility value is not valid: "'+b+'"! Options are: visible, hidden, fixed.');else{var d=this.options.fields[a];if(d.visibility!=b){c=this._firstDataColumnOffset+c+1;d.visibility!="hidden"&&b=="hidden"?this._$table.find("th:nth-child("+c+"),td:nth-child("+c+")").hide():d.visibility=="hidden"&&b!="hidden"&&this._$table.find("th:nth-child("+c+"),td:nth-child("+c+")").show().css("display","table-cell");d.visibility=b}}},_createColumnSelection:function(){var a=
+this;this._$columnSelectionDiv=c('<div class="jtable-column-selection-container"></div>').appendTo(a._$mainContainer);this._$table.find("thead").bind("contextmenu",function(b){if(a.options.columnSelectable){b.preventDefault();c('<div class="jtable-contextmenu-overlay"></div>').click(function(){c(this).remove();a._$columnSelectionDiv.hide()}).bind("contextmenu",function(){return false}).appendTo(document.body);a._fillColumnSelection();a._$columnSelectionDiv.css({left:b.pageX-c(document).scrollLeft(),
+top:b.pageY-c(document).scrollTop()}).show()}})},_fillColumnSelection:function(){for(var a=this,b=c('<ul class="jtable-column-select-list"></ul>'),d=0;d<this._columnList.length;d++){var f=this._columnList[d],j=this.options.fields[f],k=c("<li></li>").appendTo(b),k=c('<label for="'+f+'"><span>'+(j.title||f)+"</span><label>").appendTo(k),f=c('<input type="checkbox" name="'+f+'">').prependTo(k).click(function(){var b=c(this),e=b.attr("name");a.options.fields[e].visibility!="fixed"&&a.changeColumnVisibility(e,
+b.is(":checked")?"visible":"hidden")});j.visibility!="hidden"&&f.attr("checked","checked");j.visibility=="fixed"&&f.attr("disabled","disabled")}this._$columnSelectionDiv.html(b)},_createColumnResizeBar:function(){this._$columnResizeBar=c('<div class="jtable-column-resize-bar" style="position: fixed; top: -100px; left: -100px;"></div>').appendTo(this._$mainContainer).hide()},_makeColumnResizable:function(a){var b=this;c('<div class="jtable-column-resize-handler"></div>').appendTo(a.find(".jtable-column-header-container")).mousedown(function(d){d.preventDefault();
+d.stopPropagation();var f=a.nextAll("th.jtable-column-header:visible:first");if(f.length){b._currentResizeArgs={currentColumnStartWidth:a.outerWidth(),minWidth:10,maxWidth:a.outerWidth()+f.outerWidth()-10,mouseStartX:d.pageX,minResizeX:function(){return this.mouseStartX-(this.currentColumnStartWidth-this.minWidth)},maxResizeX:function(){return this.mouseStartX+(this.maxWidth-this.currentColumnStartWidth)}};var j=function(a){if(b._currentResizeArgs){a=b._normalizeNumber(a.pageX,b._currentResizeArgs.minResizeX(),
+b._currentResizeArgs.maxResizeX());b._$columnResizeBar.css("left",a+"px")}},k=function(d){if(b._currentResizeArgs){c(document).unbind("mousemove",j);c(document).unbind("mouseup",k);b._$columnResizeBar.hide();var d=b._normalizeNumber(b._currentResizeArgs.currentColumnStartWidth+(d.pageX-b._currentResizeArgs.mouseStartX),b._currentResizeArgs.minWidth,b._currentResizeArgs.maxWidth),g=f.outerWidth()+(b._currentResizeArgs.currentColumnStartWidth-d),l=a.data("width-in-percent")/b._currentResizeArgs.currentColumnStartWidth;
+a.data("width-in-percent",d*l);f.data("width-in-percent",g*l);a.css("width",a.data("width-in-percent")+"%");f.css("width",f.data("width-in-percent")+"%");b._normalizeColumnWidths();b._currentResizeArgs=null;b.options.saveUserPreferences&&b._saveColumnSettings()}};b._$columnResizeBar.show().css({top:a.offset().top-c(document).scrollTop()+"px",left:d.pageX-c(document).scrollLeft()+"px",height:b._$table.height()+"px"});c(document).bind("mousemove",j);c(document).bind("mouseup",k)}})},_normalizeColumnWidths:function(){var a=
+this._$table.find("thead th.jtable-command-column-header").data("width-in-percent",1).css("width","1%"),b=this._$table.find("thead th.jtable-column-header"),d=0;b.each(function(){var a=c(this);a.is(":visible")&&(d=d+a.outerWidth())});var f={},j=100-a.length;b.each(function(){var a=c(this);if(a.is(":visible")){var b=a.data("fieldName"),a=a.outerWidth()*j/d;f[b]=a}});b.each(function(){var a=c(this);if(a.is(":visible")){var b=a.data("fieldName");a.data("width-in-percent",f[b]).css("width",f[b]+"%")}})},
+_saveColumnSettings:function(){var a=this,b="";this._$table.find("thead th.jtable-column-header").each(function(){var d=c(this),f=d.data("fieldName"),d=d.data("width-in-percent");b=b+(f+"="+a.options.fields[f].visibility+";"+d)+"|"});this._setCookie("column-settings",b.substr(0,b.length-1));this._logDebug("saved")},_loadColumnSettings:function(){var a=this,b=this._getCookie("column-settings");if(b){var d={};c.each(b.split("|"),function(a,b){var c=b.split("="),e=c[0],c=c[1].split(";");d[e]={columnVisibility:c[0],
+columnWidth:c[1]}});this._$table.find("thead th.jtable-column-header").each(function(){var b=c(this),e=b.data("fieldName"),f=a.options.fields[e];if(d[e]){f.visibility!="fixed"&&a._changeColumnVisibilityInternal(e,d[e].columnVisibility);b.data("width-in-percent",d[e].columnWidth).css("width",d[e].columnWidth+"%")}});this._logDebug("loaded")}},_setCookie:function(a,b){var a=this._cookieKeyPrefix+a,c=new Date;c.setDate(c.getDate()+30);document.cookie=encodeURIComponent(a)+"="+encodeURIComponent(b)+"; expires="+
+c.toUTCString()},_getCookie:function(a){for(var a=this._cookieKeyPrefix+a,b=document.cookie.split("; "),c=0;c<b.length;c++)if(b[c]){var d=b[c].split("=");if(d.length==2&&decodeURIComponent(d[0])===a)return decodeURIComponent(d[1]||"")}return null},_generateCookieKeyPrefix:function(){var a="";this.options.tableId&&(a=a+this.options.tableId+"#");a=a+this._columnList.join("$")+"#c"+this._$table.find("thead th").length;var b=0;if(a.length!=0)for(var c=0;c<a.length;c++)var d=a.charCodeAt(c),b=(b<<5)-b+
+d,b=b&b;return"jtable#"+b}})})(jQuery);
+(function(c){var b=c.hik.jtable.prototype._removeRowsFromTable;c.extend(!0,c.hik.jtable.prototype,{options:{openChildAsAccordion:!1},openChildTable:function(a,b,d){var i=this;b.showCloseButton=b.showCloseButton!=false;if(b.showCloseButton&&!b.closeRequested)b.closeRequested=function(){i.closeChildTable(a)};i.options.openChildAsAccordion&&a.siblings().each(function(){i.closeChildTable(c(this))});i.closeChildTable(a,function(){var e=i.getChildRow(a).find("td").empty(),g=c('<div class="jtable-child-table-container"></div>').appendTo(e);
+e.data("childTable",g);g.jtable(b);i.openChildRow(a);g.hide().slideDown("fast",function(){d&&d({childTable:g})})})},closeChildTable:function(a,b){var c=this,i=this.getChildRow(a).find("td"),e=i.data("childTable");if(e){i.data("childTable",null);e.slideUp("fast",function(){e.jtable("destroy");e.remove();c.closeChildRow(a);b&&b()})}else b&&b()},isChildRowOpen:function(a){return this.getChildRow(a).is(":visible")},getChildRow:function(a){return a.data("childRow")||this._createChildRow(a)},openChildRow:function(a){a=
+this.getChildRow(a);a.is(":visible")||a.show();return a},closeChildRow:function(a){a=this.getChildRow(a);a.is(":visible")&&a.hide()},_removeRowsFromTable:function(a,f){var d=this;f=="deleted"&&a.each(function(){var a=c(this),b=a.data("childRow");if(b){d.closeChildTable(a);b.remove()}});b.apply(this,arguments)},_createChildRow:function(a){var b=this._findRowIndex(a),d=this._$table.find("thead th").length,d=c('<tr class="jtable-child-row"></tr>').append('<td colspan="'+d+'"></td>');this._addRowToTable(d,
+b+1);a.data("childRow",d);d.hide();return d}})})(jQuery); \ No newline at end of file
diff --git a/lib/themes/lightcolor/bg-thead.png b/lib/themes/lightcolor/bg-thead.png
new file mode 100644
index 0000000..a7b6969
--- /dev/null
+++ b/lib/themes/lightcolor/bg-thead.png
Binary files differ
diff --git a/lib/themes/lightcolor/blue/jtable.css b/lib/themes/lightcolor/blue/jtable.css
new file mode 100644
index 0000000..9e906c7
--- /dev/null
+++ b/lib/themes/lightcolor/blue/jtable.css
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'Light color - Orange' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'orange' colors for jtable light color theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_lightcolor_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background: rgb(120,177,237); /* Old browsers */
+ background: -moz-linear-gradient(top, rgba(120,177,237,1) 0%, rgba(65,123,181,1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(120,177,237,1)), color-stop(100%,rgba(65,123,181,1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(120,177,237,1) 0%,rgba(65,123,181,1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(120,177,237,1) 0%,rgba(65,123,181,1) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(120,177,237,1) 0%,rgba(65,123,181,1) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(120,177,237,1) 0%,rgba(65,123,181,1) 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#78b1ed', endColorstr='#417bb5',GradientType=0 ); /* IE6-9 */
+ border-color: #2B5177;
+}
+
+div.jtable-title-text
+{
+ color: #fff;
+ text-shadow: 0 1px 0 #666;
+ filter: progid:DXImageTransform.Microsoft.Shadow(direction=135,strength=2,color=666666);
+}
+
+/* PAGING ********************************************************************/
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #2D5580;
+ border-color: #123458;
+}
+
+/* ROWS **********************************************************************/
+
+/* Selected row */
+table.jtable tr.jtable-row-selected,
+table.jtable tr.jtable-row-selected:hover
+{
+ background-color: #5f9cdc;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #5f9cdc;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #5f9cdc;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #5f9cdc;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #2B5177;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ border-color: #2B5177;
+ background: url('loading.gif') no-repeat;
+ background-color: #78B1ED;
+ background-position: 5px;
+} \ No newline at end of file
diff --git a/lib/themes/lightcolor/blue/loading.gif b/lib/themes/lightcolor/blue/loading.gif
new file mode 100644
index 0000000..e7c9c35
--- /dev/null
+++ b/lib/themes/lightcolor/blue/loading.gif
Binary files differ
diff --git a/lib/themes/lightcolor/close.png b/lib/themes/lightcolor/close.png
new file mode 100644
index 0000000..dde8804
--- /dev/null
+++ b/lib/themes/lightcolor/close.png
Binary files differ
diff --git a/lib/themes/lightcolor/column-asc.png b/lib/themes/lightcolor/column-asc.png
new file mode 100644
index 0000000..bc512de
--- /dev/null
+++ b/lib/themes/lightcolor/column-asc.png
Binary files differ
diff --git a/lib/themes/lightcolor/column-desc.png b/lib/themes/lightcolor/column-desc.png
new file mode 100644
index 0000000..d991088
--- /dev/null
+++ b/lib/themes/lightcolor/column-desc.png
Binary files differ
diff --git a/lib/themes/lightcolor/column-sortable.png b/lib/themes/lightcolor/column-sortable.png
new file mode 100644
index 0000000..135cf46
--- /dev/null
+++ b/lib/themes/lightcolor/column-sortable.png
Binary files differ
diff --git a/lib/themes/lightcolor/delete.png b/lib/themes/lightcolor/delete.png
new file mode 100644
index 0000000..55e388b
--- /dev/null
+++ b/lib/themes/lightcolor/delete.png
Binary files differ
diff --git a/lib/themes/lightcolor/edit.png b/lib/themes/lightcolor/edit.png
new file mode 100644
index 0000000..cd77c30
--- /dev/null
+++ b/lib/themes/lightcolor/edit.png
Binary files differ
diff --git a/lib/themes/lightcolor/gray/jtable.css b/lib/themes/lightcolor/gray/jtable.css
new file mode 100644
index 0000000..757d92d
--- /dev/null
+++ b/lib/themes/lightcolor/gray/jtable.css
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'Light color - Gray' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'gray' colors for jtable light color theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_lightcolor_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background: #dedede; /* Old browsers */
+ background: -moz-linear-gradient(top, rgba(232,232,232,1) 0%, rgba(186,186,186,1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(232,232,232,1)), color-stop(100%,rgba(186,186,186,1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(232,232,232,1) 0%,rgba(186,186,186,1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(232,232,232,1) 0%,rgba(186,186,186,1) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(232,232,232,1) 0%,rgba(186,186,186,1) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(232,232,232,1) 0%,rgba(186,186,186,1) 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e8e8e8', endColorstr='#bababa',GradientType=0 ); /* IE6-9 */
+ border-color: #949494;
+}
+
+div.jtable-title-text
+{
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+}
+
+/* PAGING ********************************************************************/
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #8e8e8e;
+ border-color: #5f5f5f;
+}
+
+/* ROWS **********************************************************************/
+
+/* Selected row */
+table.jtable tr.jtable-row-selected,
+table.jtable tr.jtable-row-selected:hover
+{
+ background-color: #8e8e8e;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #8e8e8e;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #8e8e8e;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #8e8e8e;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #5f5f5f;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ border-color: #5f5f5f;
+ background: url('loading.gif') no-repeat;
+ background-color: #8e8e8e;
+ background-position: 5px;
+} \ No newline at end of file
diff --git a/lib/themes/lightcolor/gray/loading.gif b/lib/themes/lightcolor/gray/loading.gif
new file mode 100644
index 0000000..02cdd00
--- /dev/null
+++ b/lib/themes/lightcolor/gray/loading.gif
Binary files differ
diff --git a/lib/themes/lightcolor/gray/loading2.gif b/lib/themes/lightcolor/gray/loading2.gif
new file mode 100644
index 0000000..c838e6d
--- /dev/null
+++ b/lib/themes/lightcolor/gray/loading2.gif
Binary files differ
diff --git a/lib/themes/lightcolor/green/jtable.css b/lib/themes/lightcolor/green/jtable.css
new file mode 100644
index 0000000..f50295d
--- /dev/null
+++ b/lib/themes/lightcolor/green/jtable.css
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'Light color - Green' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'green' colors for jtable light color theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_lightcolor_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background: #42d033; /* Old browsers */
+ background: -moz-linear-gradient(top, rgba(114,235,101,1) 0%, rgba(30,157,13,1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(114,235,101,1)), color-stop(100%,rgba(30,157,13,1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(114,235,101,1) 0%,rgba(30,157,13,1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(114,235,101,1) 0%,rgba(30,157,13,1) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(114,235,101,1) 0%,rgba(30,157,13,1) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(114,235,101,1) 0%,rgba(30,157,13,1) 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72eb65', endColorstr='#1e9d0d',GradientType=0 ); /* IE6-9 */
+ border-color: #167509;
+}
+
+div.jtable-title-text
+{
+ color: #fff;
+ text-shadow: 0 1px 0 #666;
+ filter: progid:DXImageTransform.Microsoft.Shadow(direction=135,strength=2,color=666666);
+}
+
+/* PAGING ********************************************************************/
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #42d033;
+ border-color: #167509;
+}
+
+/* ROWS **********************************************************************/
+
+/* Selected row */
+table.jtable tr.jtable-row-selected,
+table.jtable tr.jtable-row-selected:hover
+{
+ background-color: #33b326;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #33b326;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #33b326;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #33b326;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #167509;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ border-color: #167509;
+ background: url('loading.gif') no-repeat;
+ background-color: #42d033;
+ background-position: 5px;
+} \ No newline at end of file
diff --git a/lib/themes/lightcolor/green/loading.gif b/lib/themes/lightcolor/green/loading.gif
new file mode 100644
index 0000000..d32f54f
--- /dev/null
+++ b/lib/themes/lightcolor/green/loading.gif
Binary files differ
diff --git a/lib/themes/lightcolor/jtable_lightcolor_base.css b/lib/themes/lightcolor/jtable_lightcolor_base.css
new file mode 100644
index 0000000..d89e91c
--- /dev/null
+++ b/lib/themes/lightcolor/jtable_lightcolor_base.css
@@ -0,0 +1,654 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'light color theme base''
+ * Author : Halil İbrahim KALKAN
+ * Description : This is the base file for light color themes, no color defines.
+ * Color files imports this and adds colors.
+ *****************************************************************************/
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ font-family: 'Verdana';
+ font-size: 11px;
+ color: #222;
+ position: relative;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+.jtable-title
+{
+ text-align: left;
+ position: relative;
+ height: 34px;
+ line-height: 34px;
+ -webkit-border-radius: 3px 3px 0 0;
+ -moz-border-radius: 3px 3px 0 0;
+ border-radius: 3px 3px 0 0;
+ box-shadow: inset 0 1px 0 0 rgba(255,255,255,0.5);
+ padding-left: 10px;
+ border: 1px solid;
+}
+
+/* A div that is in jtable-title and contains the title text */
+div.jtable-title div.jtable-title-text
+{
+ font-weight: bold;
+}
+
+/* Main table tag */
+table.jtable
+{
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+ border: 1px solid #C8C8C8;
+}
+
+/* BOTTOM PANEL */
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ padding: 1px;
+ background: #fff;
+ border: 1px solid #C8C8C8;
+ border-top: none;
+ border-radius: 0px 0px 3px 3px;
+ min-height: 26px;
+ line-height: 16px;
+ font-size: 0.9em;
+}
+
+/* Left area in the bottom panel */
+div.jtable-bottom-panel div.jtable-left-area
+{
+ display: inline-block;
+ float: left;
+}
+
+/* Right area in the bottom panel */
+div.jtable-bottom-panel div.jtable-right-area
+{
+ display: inline-block;
+ float: right;
+ padding: 2px;
+}
+
+/* HEADER ********************************************************************/
+
+table.jtable thead
+{
+ background: url('bg-thead.png') repeat-x scroll top left #dddddd;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #C8C8C8;
+}
+
+/* All header cells in the table */
+table.jtable thead th
+{
+ vertical-align: middle;
+ text-align: left;
+ padding: 4px 3px 4px 6px;
+ border-left: 1px solid #fff;
+ border-right: 1px solid #C8C8C8;
+}
+
+/* Disable left border for first columns */
+table.jtable thead th:first-child
+{
+ border-left: none;
+}
+
+table.jtable thead th:last-child
+{
+ border-right: none;
+}
+
+/* All header cells except command column header cell */
+table.jtable th.jtable-column-header
+{
+ /* no additional style */
+}
+
+/* Column header container in header cells */
+table.jtable th.jtable-column-header div.jtable-column-header-container
+{
+ height: 20px;
+ position: relative;
+}
+
+/* Header text in column header cell */
+table.jtable th.jtable-column-header span.jtable-column-header-text
+{
+ display: inline-block;
+ margin-top: 3px;
+}
+
+/* Command column header cell */
+table.jtable th.jtable-command-column-header
+{
+ text-align: center;
+}
+
+/* Selecting/deselecting all header cell */
+table.jtable th.jtable-column-header-selecting
+{
+ text-align: center;
+ width: 1%;
+}
+
+/* Checkbox in the selecting/deselecting all header cell */
+table.jtable th.jtable-column-header-selecting input
+{
+ margin-left: 1px;
+ cursor: pointer;
+}
+
+/* SORTING *******************************************************************/
+
+/* A sortable column header */
+table.jtable th.jtable-column-header-sortable
+{
+ cursor: pointer;
+}
+
+/* Sorting icon in the sortable table column header */
+table.jtable th.jtable-column-header-sortable div.jtable-column-header-container
+{
+ background: url('column-sortable.png') no-repeat right;
+}
+
+/* Ascending sorted icon in the table column header */
+table.jtable th.jtable-column-header-sorted-asc div.jtable-column-header-container
+{
+ background: url('column-asc.png') no-repeat right;
+}
+
+/* Descending sorted icon in the table column header */
+table.jtable th.jtable-column-header-sorted-desc div.jtable-column-header-container
+{
+ background: url('column-desc.png') no-repeat right;
+}
+
+/* PAGING ********************************************************************/
+
+/* A container for page list */
+.jtable-page-list
+{
+ display: inline-block;
+ margin: 2px;
+}
+
+/* Page numbers */
+.jtable-page-number, /* dots between numbers (...) */ .jtable-page-number-space, /* First page link */ .jtable-page-number-first, /* Last page link */ .jtable-page-number-last, /* Previous page link */ .jtable-page-number-previous, /* Next page link */ .jtable-page-number-next, /* Active page link */ .jtable-page-number-active
+{
+ display: inline-block;
+ background-color: #ebebeb;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #ffffff #b5b5b5 #b5b5b5 #ffffff;
+ margin: 0;
+ padding: 2px 5px;
+ cursor: pointer;
+ text-shadow: 0 1px 0 white;
+}
+
+/* Page numbers */
+.jtable-page-number, /* First page link */ .jtable-page-number-first, /* Last page link */ .jtable-page-number-last, /* Previous page link */ .jtable-page-number-previous, /* Next page link */ .jtable-page-number-next
+{
+ cursor: pointer;
+}
+
+/* ... between page numbers */
+.jtable-page-number-space, /* Active/current page link */ .jtable-page-number-active
+{
+ cursor: default;
+}
+
+/* Page numbers */
+.jtable-page-number:hover, /* First page link */ .jtable-page-number-first:hover, /* Last page link */ .jtable-page-number-last:hover, /* Previous page link */ .jtable-page-number-previous:hover, /* Next page link */ .jtable-page-number-next:hover
+{
+ background-color: #ddd;
+}
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ color: #FCFCFC;
+ text-shadow: 0 1px 0 #666;
+}
+
+/* Paging informations */
+.jtable-page-info
+{
+ display: inline-block;
+ margin-left: 5px;
+ padding: 2px;
+}
+
+/* RESIZING COLUMNS **********************************************************/
+
+/* A hidden div to resize colums */
+table.jtable div.jtable-column-resize-handler
+{
+ width: 8px;
+ height: 24px;
+ position: absolute;
+ right: -8px;
+ top: -2px;
+ z-index: 2;
+ cursor: col-resize;
+}
+
+/* A guide bar to show while resizing a column */
+.jtable-column-resize-bar
+{
+ width: 1px;
+ background-color: #000;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+/* COLUMN SELECTION ***********************************************************/
+
+/* This overlay is shown on page while column selection is open */
+div.jtable-contextmenu-overlay
+{
+ left: 0px;
+ top: 0px;
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ z-index: 100;
+}
+
+/* Container of column selection list */
+div.jtable-column-selection-container
+{
+ border: 1px solid #C8C8C8;
+ position: fixed;
+ background: #fff;
+ color: #000;
+ display: none;
+ padding: 5px;
+ z-index: 101;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ -webkit-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ -moz-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+}
+
+/* Column selection list */
+ul.jtable-column-select-list
+{
+ list-style: none;
+ margin: 0px;
+ padding: 0px;
+}
+
+/* An item in column selection list */
+ul.jtable-column-select-list li
+{
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+/* Label of an item in column selection list */
+ul.jtable-column-select-list li label
+{
+ /* No additional style */
+}
+
+/* A checkbox in column selection list */
+ul.jtable-column-select-list li input[type="checkbox"]
+{
+ /* No additional style */
+}
+
+/* A checkbox's text (column name) in column selection list */
+ul.jtable-column-select-list li label span
+{
+ position: relative;
+ top: -2px;
+ margin-left: 4px;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tbody > tr
+{
+ padding: 2px;
+ background: #f8f8f8;
+ height: 30px;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ background: #f0f0f0;
+}
+
+/* All rows in the table */
+table.jtable tbody tr:hover
+{
+ background: #e8eaef;
+}
+
+/* Command column in even rows */
+table.jtable tr.jtable-row-even td.jtable-command-column
+{
+ /* No additional style */
+}
+
+/* Style for 'no data available' row */
+table.jtable tr.jtable-no-data-row
+{
+ text-align: center;
+}
+
+/* Style for a selected row */
+table.jtable tr.jtable-row-selected
+{
+ color: #FCFCFC;
+ text-shadow: 0 1px 0 #333;
+}
+
+/* CHILD ROWS/TABLES ********************************************************/
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row > td
+{
+ background-color: #ababab;
+ padding: 1px 0px;
+}
+
+table.jtable tr.jtable-child-row .jtable-title, table.jtable tr.jtable-child-row .jtable-bottom-panel
+{
+ border: none;
+ -webkit-border-radius: 0px;
+ -moz-border-radius: 0px;
+ border-radius: 0px;
+}
+
+table.jtable tr.jtable-child-row .jtable
+{
+ border: none;
+ border-bottom: 1px solid #C8C8C8;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ /* No style yet */
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ /* No style yet */
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ /* No style yet */
+}
+
+/* CELLS *********************************************************************/
+
+/* All table cells in the table */
+table.jtable tbody td
+{
+ padding: 5px;
+ border-left: 1px dotted #bebebe;
+}
+
+/* Command column in all rows */
+table.jtable tr td.jtable-command-column
+{
+ text-align: center;
+ vertical-align: middle;
+}
+
+/* Disable left border for first columns */
+table.jtable tbody td:first-child
+{
+ border-left: none;
+}
+
+/* Select/deselect column for a row */
+table.jtable tbody td.jtable-selecting-column
+{
+ text-align: center;
+}
+
+/* Select/deselect checkbox for a row */
+table.jtable tbody td.jtable-selecting-column input
+{
+ cursor: pointer;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link container */
+span.jtable-add-record
+{
+ display: inline-block;
+ margin: 3px;
+}
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ font-weight: bold;
+ text-decoration: none;
+}
+
+/* 'add new record' link hover state */
+span.jtable-add-record a:hover
+{
+ text-decoration: underline;
+}
+
+/* All command buttons (delete/edit) */
+.jtable-command-button
+{
+ cursor: pointer;
+ border: none;
+ display: inline;
+ margin: 0px;
+ padding: 0px;
+}
+
+/* span tag (that contains the command text) in all command buttons (delete/edit) */
+.jtable-command-button span
+{
+ display: none;
+}
+
+/* Edit command button */
+.jtable-edit-command-button
+{
+ background: url('edit.png') no-repeat;
+ width: 16px;
+ height: 16px;
+}
+
+/* Delete command button */
+.jtable-delete-command-button
+{
+ background: url('delete.png') no-repeat;
+ width: 16px;
+ height: 16px;
+}
+
+/* Table Close command button */
+.jtable-close-button
+{
+ background: url('close.png') no-repeat;
+ width: 22px;
+ height: 22px;
+ position: absolute;
+ right: 6px;
+ top: 6px;
+ opacity: 0.8;
+ filter: alpha(opacity=80);
+}
+
+.jtable-close-button:hover
+{
+ opacity: 1.0;
+ filter: alpha(opacity=100);
+}
+
+/* FORMS *********************************************************************/
+
+/* A form to edit/create records */
+form.jtable-dialog-form
+{
+ font-family: 'Verdana';
+ font-size: 10px;
+}
+
+/* A form to create records */
+form.jtable-create-form
+{
+ /* No additional style */
+}
+
+/* A form to edit records */
+form.jtable-edit-form
+{
+ /* No additional style */
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ margin: 0px;
+ padding: 2px 0px 3px 0px;
+ border-bottom: 1px solid #ddd;
+}
+
+div.jtable-input-field-container:last-child
+{
+ border: none;
+}
+
+/* A div that contains title of input in create/edit forms */
+div.jtable-input-label
+{
+ padding: 2px;
+ font-weight: bold;
+}
+
+/* A div that contains an input element in create/edit forms */
+div.jtable-input
+{
+ padding: 2px;
+}
+
+/* A div that contains a date input element in create/edit forms */
+div.jtable-date-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a text input element in create/edit forms */
+div.jtable-text-input
+{
+ /* No additional style */
+}
+
+/* A container for radio button and checkbox textes */
+span.jtable-option-text-clickable
+{
+ position: relative;
+ top: -2px;
+}
+
+/* A div that contains a textarea input element in create/edit forms */
+div.jtable-textarea-input textarea
+{
+ width: 300px;
+ min-height: 60px;
+}
+
+/* A div that contains a password input element in create/edit forms */
+div.jtable-password-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a drop down list (combobox) element in create/edit forms */
+div.jtable-dropdown-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a radio button list in create/edit forms */
+div.jtable-radiobuttonlist-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a single radio button element */
+div.jtable-radio-input input, /* A div that contains a checkbox element */ div.jtable-checkbox-input input, /* A span that contains text that can be clicked to set radio button's or checkbox's state */ span.jtable-option-text-clickable
+{
+ cursor: pointer;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ z-index: 998;
+ position: absolute;
+ opacity: 0.1;
+ filter: alpha(opacity=10);
+ background-color: #000;
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ cursor: wait;
+ z-index: 999;
+ position: absolute;
+ margin: 5px;
+ font-size: 1.25em;
+ border: 1px solid;
+ color: #fff;
+ text-shadow: 0 1px 0 #333;
+ padding: 3px 5px 5px 27px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ -webkit-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ -moz-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+}
+
+/* MISC **********************************************************************/
+
+/* Style of the text that is shown in a delete confirmation dialog */
+.jtable-delete-confirm-message
+{
+ /* No additional style */
+}
+
+/* Style of a row that is ready to remove from table (Deleted from server, waiting for deletion from table) */
+.jtable-row-ready-to-remove
+{
+ /* No additional style */
+}
diff --git a/lib/themes/lightcolor/orange/jtable.css b/lib/themes/lightcolor/orange/jtable.css
new file mode 100644
index 0000000..009538d
--- /dev/null
+++ b/lib/themes/lightcolor/orange/jtable.css
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'Light color - Orange' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'orange' colors for jtable light color theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_lightcolor_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background: rgb(255,163,102); /* Old browsers */
+ background: -moz-linear-gradient(top, rgba(255,163,102,1) 0%, rgba(218,87,0,1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,163,102,1)), color-stop(100%,rgba(218,87,0,1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(255,163,102,1) 0%,rgba(218,87,0,1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(255,163,102,1) 0%,rgba(218,87,0,1) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(255,163,102,1) 0%,rgba(218,87,0,1) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(255,163,102,1) 0%,rgba(218,87,0,1) 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffa366', endColorstr='#da5700',GradientType=0 ); /* IE6-9 */
+ border-color: #804620;
+}
+
+div.jtable-title-text
+{
+ color: #fff;
+ text-shadow: 0 1px 0 #666;
+ filter: progid:DXImageTransform.Microsoft.Shadow(direction=135,strength=2,color=666666);
+}
+
+/* PAGING ********************************************************************/
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #f36301;
+ border-color: #a14100;
+}
+
+/* ROWS **********************************************************************/
+
+/* Selected row */
+table.jtable tr.jtable-row-selected,
+table.jtable tr.jtable-row-selected:hover
+{
+ background-color: #F36301;
+}
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #F36301;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #F36301;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #F36301;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #cc5200;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ border-color: #a14100;
+ background: url('loading.gif') no-repeat;
+ background-color: #f36301;
+ background-position: 5px;
+} \ No newline at end of file
diff --git a/lib/themes/lightcolor/orange/loading.gif b/lib/themes/lightcolor/orange/loading.gif
new file mode 100644
index 0000000..65aaae3
--- /dev/null
+++ b/lib/themes/lightcolor/orange/loading.gif
Binary files differ
diff --git a/lib/themes/lightcolor/red/jtable.css b/lib/themes/lightcolor/red/jtable.css
new file mode 100644
index 0000000..36b8d1e
--- /dev/null
+++ b/lib/themes/lightcolor/red/jtable.css
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'Light color - Red' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'red' colors for jtable light color theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_lightcolor_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background: #ea2a2a; /* Old browsers */
+ background: -moz-linear-gradient(top, rgba(235,101,101,1) 0%, rgba(157,13,13,1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(235,101,101,1)), color-stop(100%,rgba(157,13,13,1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(235,101,101,1) 0%,rgba(157,13,13,1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(235,101,101,1) 0%,rgba(157,13,13,1) 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, rgba(235,101,101,1) 0%,rgba(157,13,13,1) 100%); /* IE10+ */
+ background: linear-gradient(top, rgba(235,101,101,1) 0%,rgba(157,13,13,1) 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eb6565', endColorstr='#9d0d0d',GradientType=0 ); /* IE6-9 */
+ border-color: #772b2b;
+}
+
+div.jtable-title-text
+{
+ color: #fff;
+ text-shadow: 0 1px 0 #666;
+ filter: progid:DXImageTransform.Microsoft.Shadow(direction=135,strength=2,color=666666);
+}
+
+/* PAGING ********************************************************************/
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #b11515;
+ border-color: #7d1616;
+}
+
+/* ROWS **********************************************************************/
+
+/* Selected row */
+table.jtable tr.jtable-row-selected,
+table.jtable tr.jtable-row-selected:hover
+{
+ background-color: #ea2a2a;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #ea2a2a;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #ea2a2a;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #ea2a2a;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #772b2b;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ border-color: #772b2b;
+ background: url('loading.gif') no-repeat;
+ background-color: #ea2a2a;
+ background-position: 5px;
+} \ No newline at end of file
diff --git a/lib/themes/lightcolor/red/loading.gif b/lib/themes/lightcolor/red/loading.gif
new file mode 100644
index 0000000..c838e6d
--- /dev/null
+++ b/lib/themes/lightcolor/red/loading.gif
Binary files differ
diff --git a/lib/themes/standard/blue/header-bg.gif b/lib/themes/standard/blue/header-bg.gif
new file mode 100644
index 0000000..deb99ee
--- /dev/null
+++ b/lib/themes/standard/blue/header-bg.gif
Binary files differ
diff --git a/lib/themes/standard/blue/jtable_blue.css b/lib/themes/standard/blue/jtable_blue.css
new file mode 100644
index 0000000..d228d73
--- /dev/null
+++ b/lib/themes/standard/blue/jtable_blue.css
@@ -0,0 +1,176 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'standard blue' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'blue' colors for jtable standard theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_standard_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ color: #000000;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background:url('title-bg.png') left;
+ color: #FFFFFF;
+ border-color: #C6D5E1;
+}
+
+/* Main table tag */
+table.jtable
+{
+ background-color: #C6D5E1;
+}
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ background-color: #E0E8E7;
+ border-color: #C6D5E1;
+}
+
+/* HEADER ********************************************************************/
+
+/* All header cells in the table */
+table.jtable th
+{
+ background:url('header-bg.gif') left;
+ color:#CFDCE7;
+}
+
+/* PAGING ********************************************************************/
+
+/* Page numbers */
+.jtable-page-number,
+/* First page link */
+.jtable-page-number-first,
+/* Last page link */
+.jtable-page-number-last,
+/* Previous page link */
+.jtable-page-number-previous,
+/* Next page link */
+.jtable-page-number-next
+{
+ background-color: #CFDCE7;
+ border: 1px solid #a3bfd6;
+}
+
+/* Page numbers */
+.jtable-page-number:hover,
+/* First page link */
+.jtable-page-number-first:hover,
+/* Last page link */
+.jtable-page-number-last:hover,
+/* Previous page link */
+.jtable-page-number-previous:hover,
+/* Next page link */
+.jtable-page-number-next:hover
+{
+ background-color: #9ec7e9;
+}
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #4881b0;
+ border: 1px solid #a3bfd6;
+ color: #fff;
+ font-weight: bold;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tr
+{
+ background-color: #FFFFFF;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ color: #000055;
+ background-color: #ECF2F6;
+}
+
+/* Rows when mouse over */
+table.jtable tr:hover
+{
+ background-color: #d3e2ec;
+}
+
+/* Selected row */
+table.jtable tr.jtable-row-selected
+{
+ color: #ffffff;
+ background-color: #3e9cda;
+}
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row
+{
+ background-color: #b1f2ff;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #00FF89;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #00FFFF;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #FF0000;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #1E90FF;
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ background-color: #ECF2F6;
+ border-color: #C6D5E1;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ background-color: #000000;
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ color: #000000;
+ border-color: #000000;
+ background: url('loading.gif') no-repeat;
+ background-position: 5px;
+ background-color: #8AFFFF;
+} \ No newline at end of file
diff --git a/lib/themes/standard/blue/loading.gif b/lib/themes/standard/blue/loading.gif
new file mode 100644
index 0000000..dcc5113
--- /dev/null
+++ b/lib/themes/standard/blue/loading.gif
Binary files differ
diff --git a/lib/themes/standard/blue/title-bg.png b/lib/themes/standard/blue/title-bg.png
new file mode 100644
index 0000000..8c3a567
--- /dev/null
+++ b/lib/themes/standard/blue/title-bg.png
Binary files differ
diff --git a/lib/themes/standard/close.png b/lib/themes/standard/close.png
new file mode 100644
index 0000000..581fa74
--- /dev/null
+++ b/lib/themes/standard/close.png
Binary files differ
diff --git a/lib/themes/standard/column-asc.png b/lib/themes/standard/column-asc.png
new file mode 100644
index 0000000..fc6a982
--- /dev/null
+++ b/lib/themes/standard/column-asc.png
Binary files differ
diff --git a/lib/themes/standard/column-desc.png b/lib/themes/standard/column-desc.png
new file mode 100644
index 0000000..83776ba
--- /dev/null
+++ b/lib/themes/standard/column-desc.png
Binary files differ
diff --git a/lib/themes/standard/column-sortable.png b/lib/themes/standard/column-sortable.png
new file mode 100644
index 0000000..eb24b2c
--- /dev/null
+++ b/lib/themes/standard/column-sortable.png
Binary files differ
diff --git a/lib/themes/standard/delete.png b/lib/themes/standard/delete.png
new file mode 100644
index 0000000..55e388b
--- /dev/null
+++ b/lib/themes/standard/delete.png
Binary files differ
diff --git a/lib/themes/standard/edit.png b/lib/themes/standard/edit.png
new file mode 100644
index 0000000..b93e776
--- /dev/null
+++ b/lib/themes/standard/edit.png
Binary files differ
diff --git a/lib/themes/standard/green/header-bg.gif b/lib/themes/standard/green/header-bg.gif
new file mode 100644
index 0000000..d2d86b6
--- /dev/null
+++ b/lib/themes/standard/green/header-bg.gif
Binary files differ
diff --git a/lib/themes/standard/green/jtable_green.css b/lib/themes/standard/green/jtable_green.css
new file mode 100644
index 0000000..8160f58
--- /dev/null
+++ b/lib/themes/standard/green/jtable_green.css
@@ -0,0 +1,176 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'standard blue' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'blue' colors for jtable standard theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_standard_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ color: #000000;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ background:url('title-bg.png') left;
+ color: #FFFFFF;
+ border-color: #c6e1ce;
+}
+
+/* Main table tag */
+table.jtable
+{
+ background-color: #c6e1cf;
+}
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ background-color: #e0e8e3;
+ border-color: #c6e1ce;
+}
+
+/* HEADER ********************************************************************/
+
+/* All header cells in the table */
+table.jtable th
+{
+ background:url('header-bg.gif') left;
+ color:#cfe7d6;
+}
+
+/* PAGING ********************************************************************/
+
+/* Page numbers */
+.jtable-page-number,
+/* First page link */
+.jtable-page-number-first,
+/* Last page link */
+.jtable-page-number-last,
+/* Previous page link */
+.jtable-page-number-previous,
+/* Next page link */
+.jtable-page-number-next
+{
+ background-color: #cfe7d6;
+ border: 1px solid #a3d6b2;
+}
+
+/* Page numbers */
+.jtable-page-number:hover,
+/* First page link */
+.jtable-page-number-first:hover,
+/* Last page link */
+.jtable-page-number-last:hover,
+/* Previous page link */
+.jtable-page-number-previous:hover,
+/* Next page link */
+.jtable-page-number-next:hover
+{
+ background-color: #9ee9b5;
+}
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #48b068;
+ border: 1px solid #a3d6b2;
+ color: #fff;
+ font-weight: bold;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tr
+{
+ background-color: #FFFFFF;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ color: #00551a;
+ background-color: #ecf6ef;
+}
+
+/* Rows when mouse over */
+table.jtable tr:hover
+{
+ background-color: #d3ecda;
+}
+
+/* Selected row */
+table.jtable tr.jtable-row-selected
+{
+ color: #ffffff;
+ background-color: #3eda6e;
+}
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row
+{
+ background-color: #b1ffcb;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #00FF89;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #00FFFF;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #FF0000;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #18b749;
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ background-color: #ecf6ef;
+ border-color: #c6e1ce;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ background-color: #000000;
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ color: #000000;
+ border-color: #000000;
+ background: url('loading.gif') no-repeat;
+ background-position: 5px;
+ background-color: #8affab;
+} \ No newline at end of file
diff --git a/lib/themes/standard/green/loading.gif b/lib/themes/standard/green/loading.gif
new file mode 100644
index 0000000..25457a2
--- /dev/null
+++ b/lib/themes/standard/green/loading.gif
Binary files differ
diff --git a/lib/themes/standard/green/title-bg.png b/lib/themes/standard/green/title-bg.png
new file mode 100644
index 0000000..2cad9bc
--- /dev/null
+++ b/lib/themes/standard/green/title-bg.png
Binary files differ
diff --git a/lib/themes/standard/jtable_standard_base.css b/lib/themes/standard/jtable_standard_base.css
new file mode 100644
index 0000000..6a5344b
--- /dev/null
+++ b/lib/themes/standard/jtable_standard_base.css
@@ -0,0 +1,535 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'standard' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This is the base file for standart themes, no color defines.
+ * Color files imports this and adds colors.
+ *****************************************************************************/
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ font-family: 'Verdana';
+ font-size: 10px;
+ position: relative;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+.jtable-title
+{
+ text-align: center;
+ border: 1px solid transparent;
+ border-bottom: none;
+ padding: 1px;
+ height: 24px;
+ position: relative;
+}
+
+/* A div that is in jtable-title and contains the title text */
+div.jtable-title div.jtable-title-text
+{
+ font-weight: bold;
+ font-size: 14px;
+ margin: 3px;
+}
+
+/* Main table tag */
+table.jtable
+{
+ width: 100%;
+ border-spacing: 1px;
+}
+
+/* BOTTOM PANEL */
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ border: 1px solid transparent;
+ border-top: none;
+ min-height: 22px;
+}
+
+/* Left area in the bottom panel */
+div.jtable-bottom-panel div.jtable-left-area
+{
+ display: inline-block;
+ float: left;
+}
+
+/* Right area in the bottom panel */
+div.jtable-bottom-panel div.jtable-right-area
+{
+ display: inline-block;
+ float: right;
+ padding: 2px;
+}
+
+/* HEADER ********************************************************************/
+
+/* All header cells in the table */
+table.jtable th
+{
+ text-align: left;
+ font-size: 11px;
+ padding: 2px;
+ height: 22px;
+ position: relative;
+}
+
+/* All header cells except command column header cell */
+table.jtable th.jtable-column-header
+{
+ /* no additional style */
+}
+
+/* Column header container in header cells */
+table.jtable th.jtable-column-header div.jtable-column-header-container
+{
+ height: 20px;
+ position: relative;
+}
+
+/* Header text in column header cell */
+table.jtable th.jtable-column-header span.jtable-column-header-text
+{
+ display: inline-block;
+ margin-top: 3px;
+}
+
+/* Command column header cell */
+table.jtable th.jtable-command-column-header,
+table.jtable th.jtable-column-header-selecting
+{
+ text-align: center;
+ width: 1%
+}
+
+/* Checkbox in the selecting/deselecting all header cell */
+table.jtable th.jtable-column-header-selecting input
+{
+ margin-left: 4px;
+ cursor: pointer;
+}
+
+/* SORTING *******************************************************************/
+
+/* A sortable column header */
+table.jtable th.jtable-column-header-sortable
+{
+ cursor: pointer;
+}
+
+/* Sorting icon in the sortable table column header */
+table.jtable th.jtable-column-header-sortable div.jtable-column-header-container
+{
+ background: url('column-sortable.png') no-repeat right;
+}
+
+/* Ascending sorted icon in the table column header */
+table.jtable th.jtable-column-header-sorted-asc div.jtable-column-header-container
+{
+ background: url('column-asc.png') no-repeat right;
+}
+
+/* Descending sorted icon in the table column header */
+table.jtable th.jtable-column-header-sorted-desc div.jtable-column-header-container
+{
+ background: url('column-desc.png') no-repeat right;
+}
+
+/* PAGING ********************************************************************/
+
+/* A container for page list */
+.jtable-page-list
+{
+ display: inline-block;
+ margin: 2px;
+}
+
+/* Page numbers */
+.jtable-page-number, /* dots between numbers (...) */ .jtable-page-number-space, /* First page link */ .jtable-page-number-first, /* Last page link */ .jtable-page-number-last, /* Previous page link */ .jtable-page-number-previous, /* Next page link */ .jtable-page-number-next, /* Active page link */ .jtable-page-number-active
+{
+ display: inline-block;
+ margin-right: 1px;
+ padding: 2px;
+}
+
+/* Page numbers */
+.jtable-page-number, /* First page link */ .jtable-page-number-first, /* Last page link */ .jtable-page-number-last, /* Previous page link */ .jtable-page-number-previous, /* Next page link */ .jtable-page-number-next
+{
+ cursor: pointer;
+}
+
+/* Paging informations */
+.jtable-page-info
+{
+ display: inline-block;
+ margin-left: 5px;
+ padding: 2px;
+}
+
+/* RESIZING COLUMNS **********************************************************/
+
+/* A hidden div to resize colums */
+table.jtable div.jtable-column-resize-handler
+{
+ width: 8px;
+ height: 24px;
+ position: absolute;
+ right: -6px;
+ top: -2px;
+ z-index: 2;
+ cursor: col-resize;
+}
+
+/* A guide bar to show while resizing a column */
+.jtable-column-resize-bar
+{
+ width: 1px;
+ background-color: #000;
+ opacity: 0.5;
+}
+
+/* COLUMN SELECTION **************************************************************/
+
+/* This overlay is shown on page while column selection is open */
+div.jtable-contextmenu-overlay
+{
+ left: 0px;
+ top: 0px;
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ z-index: 100;
+}
+
+/* Container of column selection list */
+div.jtable-column-selection-container
+{
+ border: 1px solid #aaa;
+ position: fixed;
+ background: #fff;
+ color: #000;
+ display: none;
+ padding: 5px;
+ z-index: 101;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ -webkit-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ -moz-box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+ box-shadow: 2px 2px 4px rgba(50, 51, 50, 0.75);
+}
+
+/* Column selection list */
+ul.jtable-column-select-list
+{
+ list-style: none;
+ margin: 0px;
+ padding: 0px;
+}
+
+/* An item in column selection list */
+ul.jtable-column-select-list li
+{
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+/* Label of an item in column selection list */
+ul.jtable-column-select-list li label
+{
+ /* No additional style */
+}
+
+/* A checkbox in column selection list */
+ul.jtable-column-select-list li input[type="checkbox"]
+{
+ /* No additional style */
+}
+
+/* A checkbox's text (column name) in column selection list */
+ul.jtable-column-select-list li label span
+{
+ position: relative;
+ top: -2px;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tr
+{
+ padding: 2px;
+}
+
+/* Command column in all rows */
+table.jtable tr td.jtable-command-column
+{
+ text-align: center;
+ vertical-align: middle;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ /* no additional style */
+}
+
+/* Command column in even rows */
+table.jtable tr.jtable-row-even td.jtable-command-column
+{
+ /* No additional style */
+}
+
+/* Style for 'no data available' row */
+table.jtable tr.jtable-no-data-row
+{
+ text-align: center;
+}
+
+/* Style for a selected row */
+table.jtable tr.jtable-row-selected
+{
+ /* No additional style */
+}
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row
+{
+ /* No additional style */
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ /* No additional style */
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ /* No additional style */
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ /* No additional style */
+}
+
+/* CELLS *********************************************************************/
+
+/* All table cells in the table */
+table.jtable td
+{
+ padding: 2px 3px 3px;
+}
+
+/* Select/deselect column for a row */
+table.jtable tbody td.jtable-selecting-column
+{
+ text-align: center;
+}
+
+/* Select/deselect checkbox for a row */
+table.jtable td.jtable-selecting-column input
+{
+ cursor: pointer;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link container */
+span.jtable-add-record
+{
+ display: inline-block;
+ margin: 2px;
+}
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ display: inline-block;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+/* 'add new record' link hover state */
+span.jtable-add-record a:hover
+{
+ text-decoration: underline;
+}
+
+/* All command buttons (delete/edit) */
+.jtable-command-button
+{
+ cursor: pointer;
+ border: none;
+ display: inline;
+ margin: 0px;
+ padding: 0px;
+}
+
+/* span tag (that contains the command text) in all command buttons (delete/edit) */
+.jtable-command-button span
+{
+ display: none;
+}
+
+/* Edit command button */
+.jtable-edit-command-button
+{
+ background: url('edit.png') no-repeat;
+ width: 16px;
+ height: 16px;
+}
+
+/* Delete command button */
+.jtable-delete-command-button
+{
+ background: url('delete.png') no-repeat;
+ width: 16px;
+ height: 16px;
+}
+
+/* Table Close command button */
+.jtable-close-button
+{
+ background: url('close.png') no-repeat;
+ width: 16px;
+ height: 16px;
+ position: absolute;
+ right: 4px;
+ top: 6px;
+}
+
+/* FORMS *********************************************************************/
+
+/* A form to edit/create records */
+form.jtable-dialog-form
+{
+ font-family: 'Verdana';
+ font-size: 10px;
+}
+
+/* A form to create records */
+form.jtable-create-form
+{
+ /* No additional style */
+}
+
+/* A form to edit records */
+form.jtable-edit-form
+{
+ /* No additional style */
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ margin: 3px;
+ padding: 2px;
+ border: 1px solid transparent;
+ border-top: none;
+ border-left: none;
+}
+
+/* A div that contains title of input in create/edit forms */
+div.jtable-input-label
+{
+ padding: 2px;
+ font-weight: bold;
+}
+
+/* A div that contains an input element in create/edit forms */
+div.jtable-input
+{
+ padding: 2px;
+}
+
+/* A div that contains a date input element in create/edit forms */
+div.jtable-date-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a text input element in create/edit forms */
+div.jtable-text-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a textarea input element in create/edit forms */
+div.jtable-textarea-input textarea
+{
+ width: 300px;
+ min-height: 60px;
+}
+
+/* A div that contains a password input element in create/edit forms */
+div.jtable-password-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a drop down list (combobox) element in create/edit forms */
+div.jtable-dropdown-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a radio button list in create/edit forms */
+div.jtable-radiobuttonlist-input
+{
+ /* No additional style */
+}
+
+/* A div that contains a single radio button element */
+div.jtable-radio-input input, /* A div that contains a checkbox element */ div.jtable-checkbox-input input, /* A span that contains text that can be clicked to set radio button's or checkbox's state */ span.jtable-option-text-clickable
+{
+ cursor: pointer;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ z-index: 998;
+ position: absolute;
+ opacity: 0.2;
+ filter: alpha(opacity=20); /* For IE8 and earlier */
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ z-index: 999;
+ position: absolute;
+ margin: 5px;
+ padding: 5px;
+ padding-left: 26px;
+ font-size: larger;
+ border: 1px solid;
+}
+
+/* MISC **********************************************************************/
+
+/* Style of the text that is shown in a delete confirmation dialog */
+.jtable-delete-confirm-message
+{
+ /* No additional style */
+}
+
+/* Style of a row that is ready to remove from table (Deleted from server, waiting for deletion from table) */
+.jtable-row-ready-to-remove
+{
+ /* No additional style */
+}
diff --git a/lib/themes/standard/purple/jtable_purple.css b/lib/themes/standard/purple/jtable_purple.css
new file mode 100644
index 0000000..f6fc78d
--- /dev/null
+++ b/lib/themes/standard/purple/jtable_purple.css
@@ -0,0 +1,199 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'standard purple' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'purple' colors for jtable standard theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_standard_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ color: #F6ECF0;
+ font-size: 11px;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ color: #FFFFFF;
+ background: #51152A;
+ border-color: #38160C;
+}
+
+/* Main table tag */
+table.jtable
+{
+ background: #641B35;
+ border-collapse: collapse;
+ border: 1px solid #38160C;
+}
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ background-color: #853653;
+ border-color: #38160C;
+}
+
+/* LINKS *********************************************************************/
+
+div.jtable-main-container a
+{
+ color: #F6ECF0;
+}
+
+/* HEADER ********************************************************************/
+
+/* All header cells in the table */
+table.jtable th
+{
+ background: #38160C;
+ border: 1px solid #A85070;
+ padding-left: 6px;
+}
+
+table.jtable th.jtable-column-header-selecting input
+{
+ margin-left: 0px;
+}
+
+/* PAGING ********************************************************************/
+
+/* Page numbers */
+.jtable-page-number,
+/* First page link */
+.jtable-page-number-first,
+/* Last page link */
+.jtable-page-number-last,
+/* Previous page link */
+.jtable-page-number-previous,
+/* Next page link */
+.jtable-page-number-next
+{
+ background-color: #8d415d;
+ border: 1px solid #ae6982;
+}
+
+/* Page numbers */
+.jtable-page-number:hover,
+/* First page link */
+.jtable-page-number-first:hover,
+/* Last page link */
+.jtable-page-number-last:hover,
+/* Previous page link */
+.jtable-page-number-previous:hover,
+/* Next page link */
+.jtable-page-number-next:hover
+{
+ background-color: #571930;
+}
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #b04865;
+ border: 1px solid #c1849a;
+ color: #fff;
+ font-weight: bold;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tr
+{
+ background: #7B2342;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ background: #641b35;
+}
+
+/* Mouse over rows */
+table.jtable tr:hover
+{
+ background: #51152A;
+}
+
+/* Selected row */
+table.jtable tr.jtable-row-selected
+{
+ color: #ffffff;
+ background-color: #000000;
+}
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row
+{
+ padding: 0px;
+ background-color: #ab284d;
+}
+
+/* CELLS ********************************************************************/
+
+table.jtable td
+{
+ padding: 6px;
+ border: 1px dashed #B85A7C;
+}
+
+/* Style for a child row cell */
+table.jtable tr.jtable-child-row td
+{
+ padding: 3px;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #c000ff;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #ff00eb;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #FF0000;
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ color: #F6ECF0;
+ background-color: #641b35;
+ border-color: #000000;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ background-color: #000000;
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ color: #000000;
+ border-color: #000000;
+ background: url('loading.gif') no-repeat;
+ background-position: 5px;
+ background-color: #ff00eb;
+}
diff --git a/lib/themes/standard/purple/loading.gif b/lib/themes/standard/purple/loading.gif
new file mode 100644
index 0000000..b871f80
--- /dev/null
+++ b/lib/themes/standard/purple/loading.gif
Binary files differ
diff --git a/lib/themes/standard/red/header-bg.gif b/lib/themes/standard/red/header-bg.gif
new file mode 100644
index 0000000..9187645
--- /dev/null
+++ b/lib/themes/standard/red/header-bg.gif
Binary files differ
diff --git a/lib/themes/standard/red/jtable_red.css b/lib/themes/standard/red/jtable_red.css
new file mode 100644
index 0000000..f2f20bf
--- /dev/null
+++ b/lib/themes/standard/red/jtable_red.css
@@ -0,0 +1,185 @@
+/******************************************************************************
+ * Name : jtable jQuery plug-in 'standard red' theme
+ * Author : Halil İbrahim KALKAN
+ * Description : This file defines 'red' colors for jtable standart theme.
+ *****************************************************************************/
+
+/* IMPORTS *******************************************************************/
+
+@import '../jtable_standard_base.css';
+
+/* MAIN ELEMENTS *************************************************************/
+
+/* Main container of all elements those are created by jtable plugin */
+div.jtable-main-container
+{
+ color: #000000;
+}
+
+/* A div that contains title of the table (if any title supplied in options) */
+div.jtable-title
+{
+ color: #FFFFFF;
+ background:url('title-bg.png') left;
+ border-color: #e1c6c6;
+}
+
+/* Main table tag */
+table.jtable
+{
+ background-color: #e1c6c6;
+}
+
+/* A panel below the table that contains some commands */
+div.jtable-bottom-panel
+{
+ background-color: #e8e0e0;
+ border-color:#e1c6c6;
+}
+
+/* HEADER ********************************************************************/
+
+/* All header cells in the table */
+table.jtable th
+{
+ background:url('header-bg.gif') left;
+ color:#e7cfcf;
+}
+
+/* PAGING ********************************************************************/
+
+/* Page numbers */
+.jtable-page-number,
+/* First page link */
+.jtable-page-number-first,
+/* Last page link */
+.jtable-page-number-last,
+/* Previous page link */
+.jtable-page-number-previous,
+/* Next page link */
+.jtable-page-number-next
+{
+ background-color: #e7cfcf;
+ border: 1px solid #d6a3a3;
+}
+
+/* Page numbers */
+.jtable-page-number:hover,
+/* First page link */
+.jtable-page-number-first:hover,
+/* Last page link */
+.jtable-page-number-last:hover,
+/* Previous page link */
+.jtable-page-number-previous:hover,
+/* Next page link */
+.jtable-page-number-next:hover
+{
+ background-color: #e99e9e;
+}
+
+/* Active/current page link */
+.jtable-page-number-active
+{
+ background-color: #b04848;
+ border: 1px solid #d6a3a3;
+ color: #fff;
+ font-weight: bold;
+}
+
+/* ROWS **********************************************************************/
+
+/* All rows in the table */
+table.jtable tr
+{
+ background-color: #FFFFFF;
+}
+
+/* Even rows */
+table.jtable tr.jtable-row-even
+{
+ color: #550000;
+ background-color: #F6ECEC;
+}
+
+/* Rows when mouse over */
+table.jtable tr:hover
+{
+ background-color: #edcece;
+}
+
+/* Selected row */
+table.jtable tr.jtable-row-selected
+{
+ color: #ffffff;
+ background-color: #da3e3e;
+}
+
+/* Style for a child row */
+table.jtable tr.jtable-child-row
+{
+ background-color: #ffb1b1;
+}
+
+/* ROW ANIMATIONS ***********************************************************/
+
+/* A 'new created row' style for animation */
+table.jtable tr.jtable-row-created
+{
+ background-color: #00FF89;
+}
+
+/* An 'updated row style' for animation */
+table.jtable tr.jtable-row-updated
+{
+ background-color: #00FFFF;
+}
+
+/* A 'deleting row style' for animation */
+table.jtable tr.jtable-row-deleting
+{
+ background-color: #FF0000;
+}
+
+/* COMMAND BUTTONS ***********************************************************/
+
+/* 'add new record' link */
+span.jtable-add-record a
+{
+ color: #ff1e20;
+}
+
+/* FORMS *********************************************************************/
+
+/* A form to edit/create records */
+form.jtable-dialog-form
+{
+ font-family: 'Verdana';
+ font-size: 10px;
+}
+
+/* FORM INPUT ELEMENTS *******************************************************/
+
+/* A div that contains a label (title) and input field */
+div.jtable-input-field-container
+{
+ background-color: #F6ECEC;
+ border-color: #e1c6c6;
+}
+
+/* BUSY MESSAGE AND PANEL ****************************************************/
+
+/* A panel to block table UI while is busy */
+div.jtable-busy-panel-background
+{
+ background-color: #000000;
+}
+
+/* A div that contains a message while table UI is busy */
+div.jtable-busy-message
+{
+ color: #000000;
+ border-color: #000000;
+ background: url('loading.gif') no-repeat;
+ background-position: 5px;
+ background-color: #ff8a8a;
+}
diff --git a/lib/themes/standard/red/loading.gif b/lib/themes/standard/red/loading.gif
new file mode 100644
index 0000000..2f7eef3
--- /dev/null
+++ b/lib/themes/standard/red/loading.gif
Binary files differ
diff --git a/lib/themes/standard/red/title-bg.png b/lib/themes/standard/red/title-bg.png
new file mode 100644
index 0000000..4126e93
--- /dev/null
+++ b/lib/themes/standard/red/title-bg.png
Binary files differ