summaryrefslogtreecommitdiff
path: root/build/resources/main/static/plugins/jsgrid
diff options
context:
space:
mode:
Diffstat (limited to 'build/resources/main/static/plugins/jsgrid')
-rw-r--r--build/resources/main/static/plugins/jsgrid/demos/db.js884
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-de.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-es.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-fr.js47
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-he.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ja.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ka.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pl.js62
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt-br.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ru.js47
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-tr.js47
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-cn.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-tw.js46
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid-theme.css258
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid-theme.min.css7
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid.css126
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid.js2516
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid.min.css7
-rw-r--r--build/resources/main/static/plugins/jsgrid/jsgrid.min.js8
20 files changed, 4423 insertions, 0 deletions
diff --git a/build/resources/main/static/plugins/jsgrid/demos/db.js b/build/resources/main/static/plugins/jsgrid/demos/db.js
new file mode 100644
index 0000000..07ef1ee
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/demos/db.js
@@ -0,0 +1,884 @@
+(function() {
+
+ var db = {
+
+ loadData: function(filter) {
+ return $.grep(this.clients, function(client) {
+ return (!filter.Name || client.Name.indexOf(filter.Name) > -1)
+ && (filter.Age === undefined || client.Age === filter.Age)
+ && (!filter.Address || client.Address.indexOf(filter.Address) > -1)
+ && (!filter.Country || client.Country === filter.Country)
+ && (filter.Married === undefined || client.Married === filter.Married);
+ });
+ },
+
+ insertItem: function(insertingClient) {
+ this.clients.push(insertingClient);
+ },
+
+ updateItem: function(updatingClient) { },
+
+ deleteItem: function(deletingClient) {
+ var clientIndex = $.inArray(deletingClient, this.clients);
+ this.clients.splice(clientIndex, 1);
+ }
+
+ };
+
+ window.db = db;
+
+
+ db.countries = [
+ { Name: "", Id: 0 },
+ { Name: "United States", Id: 1 },
+ { Name: "Canada", Id: 2 },
+ { Name: "United Kingdom", Id: 3 },
+ { Name: "France", Id: 4 },
+ { Name: "Brazil", Id: 5 },
+ { Name: "China", Id: 6 },
+ { Name: "Russia", Id: 7 }
+ ];
+
+ db.clients = [
+ {
+ "Name": "Otto Clay",
+ "Age": 61,
+ "Country": 6,
+ "Address": "Ap #897-1459 Quam Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Connor Johnston",
+ "Age": 73,
+ "Country": 7,
+ "Address": "Ap #370-4647 Dis Av.",
+ "Married": false
+ },
+ {
+ "Name": "Lacey Hess",
+ "Age": 29,
+ "Country": 7,
+ "Address": "Ap #365-8835 Integer St.",
+ "Married": false
+ },
+ {
+ "Name": "Timothy Henson",
+ "Age": 78,
+ "Country": 1,
+ "Address": "911-5143 Luctus Ave",
+ "Married": false
+ },
+ {
+ "Name": "Ramona Benton",
+ "Age": 43,
+ "Country": 5,
+ "Address": "Ap #614-689 Vehicula Street",
+ "Married": true
+ },
+ {
+ "Name": "Ezra Tillman",
+ "Age": 51,
+ "Country": 1,
+ "Address": "P.O. Box 738, 7583 Quisque St.",
+ "Married": true
+ },
+ {
+ "Name": "Dante Carter",
+ "Age": 59,
+ "Country": 1,
+ "Address": "P.O. Box 976, 6316 Lorem, St.",
+ "Married": false
+ },
+ {
+ "Name": "Christopher Mcclure",
+ "Age": 58,
+ "Country": 1,
+ "Address": "847-4303 Dictum Av.",
+ "Married": true
+ },
+ {
+ "Name": "Ruby Rocha",
+ "Age": 62,
+ "Country": 2,
+ "Address": "5212 Sagittis Ave",
+ "Married": false
+ },
+ {
+ "Name": "Imelda Hardin",
+ "Age": 39,
+ "Country": 5,
+ "Address": "719-7009 Auctor Av.",
+ "Married": false
+ },
+ {
+ "Name": "Jonah Johns",
+ "Age": 28,
+ "Country": 5,
+ "Address": "P.O. Box 939, 9310 A Ave",
+ "Married": false
+ },
+ {
+ "Name": "Herman Rosa",
+ "Age": 49,
+ "Country": 7,
+ "Address": "718-7162 Molestie Av.",
+ "Married": true
+ },
+ {
+ "Name": "Arthur Gay",
+ "Age": 20,
+ "Country": 7,
+ "Address": "5497 Neque Street",
+ "Married": false
+ },
+ {
+ "Name": "Xena Wilkerson",
+ "Age": 63,
+ "Country": 1,
+ "Address": "Ap #303-6974 Proin Street",
+ "Married": true
+ },
+ {
+ "Name": "Lilah Atkins",
+ "Age": 33,
+ "Country": 5,
+ "Address": "622-8602 Gravida Ave",
+ "Married": true
+ },
+ {
+ "Name": "Malik Shepard",
+ "Age": 59,
+ "Country": 1,
+ "Address": "967-5176 Tincidunt Av.",
+ "Married": false
+ },
+ {
+ "Name": "Keely Silva",
+ "Age": 24,
+ "Country": 1,
+ "Address": "P.O. Box 153, 8995 Praesent Ave",
+ "Married": false
+ },
+ {
+ "Name": "Hunter Pate",
+ "Age": 73,
+ "Country": 7,
+ "Address": "P.O. Box 771, 7599 Ante, Road",
+ "Married": false
+ },
+ {
+ "Name": "Mikayla Roach",
+ "Age": 55,
+ "Country": 5,
+ "Address": "Ap #438-9886 Donec Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Upton Joseph",
+ "Age": 48,
+ "Country": 4,
+ "Address": "Ap #896-7592 Habitant St.",
+ "Married": true
+ },
+ {
+ "Name": "Jeanette Pate",
+ "Age": 59,
+ "Country": 2,
+ "Address": "P.O. Box 177, 7584 Amet, St.",
+ "Married": false
+ },
+ {
+ "Name": "Kaden Hernandez",
+ "Age": 79,
+ "Country": 3,
+ "Address": "366 Ut St.",
+ "Married": true
+ },
+ {
+ "Name": "Kenyon Stevens",
+ "Age": 20,
+ "Country": 3,
+ "Address": "P.O. Box 704, 4580 Gravida Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Jerome Harper",
+ "Age": 31,
+ "Country": 5,
+ "Address": "2464 Porttitor Road",
+ "Married": false
+ },
+ {
+ "Name": "Jelani Patel",
+ "Age": 36,
+ "Country": 2,
+ "Address": "P.O. Box 541, 5805 Nec Av.",
+ "Married": true
+ },
+ {
+ "Name": "Keaton Oconnor",
+ "Age": 21,
+ "Country": 1,
+ "Address": "Ap #657-1093 Nec, Street",
+ "Married": false
+ },
+ {
+ "Name": "Bree Johnston",
+ "Age": 31,
+ "Country": 2,
+ "Address": "372-5942 Vulputate Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Maisie Hodges",
+ "Age": 70,
+ "Country": 7,
+ "Address": "P.O. Box 445, 3880 Odio, Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Kuame Calhoun",
+ "Age": 39,
+ "Country": 2,
+ "Address": "P.O. Box 609, 4105 Rutrum St.",
+ "Married": true
+ },
+ {
+ "Name": "Carlos Cameron",
+ "Age": 38,
+ "Country": 5,
+ "Address": "Ap #215-5386 A, Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Fulton Parsons",
+ "Age": 25,
+ "Country": 7,
+ "Address": "P.O. Box 523, 3705 Sed Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Wallace Christian",
+ "Age": 43,
+ "Country": 3,
+ "Address": "416-8816 Mauris Avenue",
+ "Married": true
+ },
+ {
+ "Name": "Caryn Maldonado",
+ "Age": 40,
+ "Country": 1,
+ "Address": "108-282 Nonummy Ave",
+ "Married": false
+ },
+ {
+ "Name": "Whilemina Frank",
+ "Age": 20,
+ "Country": 7,
+ "Address": "P.O. Box 681, 3938 Egestas. Av.",
+ "Married": true
+ },
+ {
+ "Name": "Emery Moon",
+ "Age": 41,
+ "Country": 4,
+ "Address": "Ap #717-8556 Non Road",
+ "Married": true
+ },
+ {
+ "Name": "Price Watkins",
+ "Age": 35,
+ "Country": 4,
+ "Address": "832-7810 Nunc Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Lydia Castillo",
+ "Age": 59,
+ "Country": 7,
+ "Address": "5280 Placerat, Ave",
+ "Married": true
+ },
+ {
+ "Name": "Lawrence Conway",
+ "Age": 53,
+ "Country": 1,
+ "Address": "Ap #452-2808 Imperdiet St.",
+ "Married": false
+ },
+ {
+ "Name": "Kalia Nicholson",
+ "Age": 67,
+ "Country": 5,
+ "Address": "P.O. Box 871, 3023 Tellus Road",
+ "Married": true
+ },
+ {
+ "Name": "Brielle Baxter",
+ "Age": 45,
+ "Country": 3,
+ "Address": "Ap #822-9526 Ut, Road",
+ "Married": true
+ },
+ {
+ "Name": "Valentine Brady",
+ "Age": 72,
+ "Country": 7,
+ "Address": "8014 Enim. Road",
+ "Married": true
+ },
+ {
+ "Name": "Rebecca Gardner",
+ "Age": 57,
+ "Country": 4,
+ "Address": "8655 Arcu. Road",
+ "Married": true
+ },
+ {
+ "Name": "Vladimir Tate",
+ "Age": 26,
+ "Country": 1,
+ "Address": "130-1291 Non, Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Vernon Hays",
+ "Age": 56,
+ "Country": 4,
+ "Address": "964-5552 In Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Allegra Hull",
+ "Age": 22,
+ "Country": 4,
+ "Address": "245-8891 Donec St.",
+ "Married": true
+ },
+ {
+ "Name": "Hu Hendrix",
+ "Age": 65,
+ "Country": 7,
+ "Address": "428-5404 Tempus Ave",
+ "Married": true
+ },
+ {
+ "Name": "Kenyon Battle",
+ "Age": 32,
+ "Country": 2,
+ "Address": "921-6804 Lectus St.",
+ "Married": false
+ },
+ {
+ "Name": "Gloria Nielsen",
+ "Age": 24,
+ "Country": 4,
+ "Address": "Ap #275-4345 Lorem, Street",
+ "Married": true
+ },
+ {
+ "Name": "Illiana Kidd",
+ "Age": 59,
+ "Country": 2,
+ "Address": "7618 Lacus. Av.",
+ "Married": false
+ },
+ {
+ "Name": "Adria Todd",
+ "Age": 68,
+ "Country": 6,
+ "Address": "1889 Tincidunt Road",
+ "Married": false
+ },
+ {
+ "Name": "Kirsten Mayo",
+ "Age": 71,
+ "Country": 1,
+ "Address": "100-8640 Orci, Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Willa Hobbs",
+ "Age": 60,
+ "Country": 6,
+ "Address": "P.O. Box 323, 158 Tristique St.",
+ "Married": false
+ },
+ {
+ "Name": "Alexis Clements",
+ "Age": 69,
+ "Country": 5,
+ "Address": "P.O. Box 176, 5107 Proin Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Akeem Conrad",
+ "Age": 60,
+ "Country": 2,
+ "Address": "282-495 Sed Ave",
+ "Married": true
+ },
+ {
+ "Name": "Montana Silva",
+ "Age": 79,
+ "Country": 6,
+ "Address": "P.O. Box 120, 9766 Consectetuer St.",
+ "Married": false
+ },
+ {
+ "Name": "Kaseem Hensley",
+ "Age": 77,
+ "Country": 6,
+ "Address": "Ap #510-8903 Mauris. Av.",
+ "Married": true
+ },
+ {
+ "Name": "Christopher Morton",
+ "Age": 35,
+ "Country": 5,
+ "Address": "P.O. Box 234, 3651 Sodales Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Wade Fernandez",
+ "Age": 49,
+ "Country": 6,
+ "Address": "740-5059 Dolor. Road",
+ "Married": true
+ },
+ {
+ "Name": "Illiana Kirby",
+ "Age": 31,
+ "Country": 2,
+ "Address": "527-3553 Mi Ave",
+ "Married": false
+ },
+ {
+ "Name": "Kimberley Hurley",
+ "Age": 65,
+ "Country": 5,
+ "Address": "P.O. Box 637, 9915 Dictum St.",
+ "Married": false
+ },
+ {
+ "Name": "Arthur Olsen",
+ "Age": 74,
+ "Country": 5,
+ "Address": "887-5080 Eget St.",
+ "Married": false
+ },
+ {
+ "Name": "Brody Potts",
+ "Age": 59,
+ "Country": 2,
+ "Address": "Ap #577-7690 Sem Road",
+ "Married": false
+ },
+ {
+ "Name": "Dillon Ford",
+ "Age": 60,
+ "Country": 1,
+ "Address": "Ap #885-9289 A, Av.",
+ "Married": true
+ },
+ {
+ "Name": "Hannah Juarez",
+ "Age": 61,
+ "Country": 2,
+ "Address": "4744 Sapien, Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Vincent Shaffer",
+ "Age": 25,
+ "Country": 2,
+ "Address": "9203 Nunc St.",
+ "Married": true
+ },
+ {
+ "Name": "George Holt",
+ "Age": 27,
+ "Country": 6,
+ "Address": "4162 Cras Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Tobias Bartlett",
+ "Age": 74,
+ "Country": 4,
+ "Address": "792-6145 Mauris St.",
+ "Married": true
+ },
+ {
+ "Name": "Xavier Hooper",
+ "Age": 35,
+ "Country": 1,
+ "Address": "879-5026 Interdum. Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Declan Dorsey",
+ "Age": 31,
+ "Country": 2,
+ "Address": "Ap #926-4171 Aenean Road",
+ "Married": true
+ },
+ {
+ "Name": "Clementine Tran",
+ "Age": 43,
+ "Country": 4,
+ "Address": "P.O. Box 176, 9865 Eu Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Pamela Moody",
+ "Age": 55,
+ "Country": 6,
+ "Address": "622-6233 Luctus Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Julie Leon",
+ "Age": 43,
+ "Country": 6,
+ "Address": "Ap #915-6782 Sem Av.",
+ "Married": true
+ },
+ {
+ "Name": "Shana Nolan",
+ "Age": 79,
+ "Country": 5,
+ "Address": "P.O. Box 603, 899 Eu St.",
+ "Married": false
+ },
+ {
+ "Name": "Vaughan Moody",
+ "Age": 37,
+ "Country": 5,
+ "Address": "880 Erat Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Randall Reeves",
+ "Age": 44,
+ "Country": 3,
+ "Address": "1819 Non Street",
+ "Married": false
+ },
+ {
+ "Name": "Dominic Raymond",
+ "Age": 68,
+ "Country": 1,
+ "Address": "Ap #689-4874 Nisi Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Lev Pugh",
+ "Age": 69,
+ "Country": 5,
+ "Address": "Ap #433-6844 Auctor Avenue",
+ "Married": true
+ },
+ {
+ "Name": "Desiree Hughes",
+ "Age": 80,
+ "Country": 4,
+ "Address": "605-6645 Fermentum Avenue",
+ "Married": true
+ },
+ {
+ "Name": "Idona Oneill",
+ "Age": 23,
+ "Country": 7,
+ "Address": "751-8148 Aliquam Avenue",
+ "Married": true
+ },
+ {
+ "Name": "Lani Mayo",
+ "Age": 76,
+ "Country": 1,
+ "Address": "635-2704 Tristique St.",
+ "Married": true
+ },
+ {
+ "Name": "Cathleen Bonner",
+ "Age": 40,
+ "Country": 1,
+ "Address": "916-2910 Dolor Av.",
+ "Married": false
+ },
+ {
+ "Name": "Sydney Murray",
+ "Age": 44,
+ "Country": 5,
+ "Address": "835-2330 Fringilla St.",
+ "Married": false
+ },
+ {
+ "Name": "Brenna Rodriguez",
+ "Age": 77,
+ "Country": 6,
+ "Address": "3687 Imperdiet Av.",
+ "Married": true
+ },
+ {
+ "Name": "Alfreda Mcdaniel",
+ "Age": 38,
+ "Country": 7,
+ "Address": "745-8221 Aliquet Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Zachery Atkins",
+ "Age": 30,
+ "Country": 1,
+ "Address": "549-2208 Auctor. Road",
+ "Married": true
+ },
+ {
+ "Name": "Amelia Rich",
+ "Age": 56,
+ "Country": 4,
+ "Address": "P.O. Box 734, 4717 Nunc Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Kiayada Witt",
+ "Age": 62,
+ "Country": 3,
+ "Address": "Ap #735-3421 Malesuada Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Lysandra Pierce",
+ "Age": 36,
+ "Country": 1,
+ "Address": "Ap #146-2835 Curabitur St.",
+ "Married": true
+ },
+ {
+ "Name": "Cara Rios",
+ "Age": 58,
+ "Country": 4,
+ "Address": "Ap #562-7811 Quam. Ave",
+ "Married": true
+ },
+ {
+ "Name": "Austin Andrews",
+ "Age": 55,
+ "Country": 7,
+ "Address": "P.O. Box 274, 5505 Sociis Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Lillian Peterson",
+ "Age": 39,
+ "Country": 2,
+ "Address": "6212 A Avenue",
+ "Married": false
+ },
+ {
+ "Name": "Adria Beach",
+ "Age": 29,
+ "Country": 2,
+ "Address": "P.O. Box 183, 2717 Nunc Avenue",
+ "Married": true
+ },
+ {
+ "Name": "Oleg Durham",
+ "Age": 80,
+ "Country": 4,
+ "Address": "931-3208 Nunc Rd.",
+ "Married": false
+ },
+ {
+ "Name": "Casey Reese",
+ "Age": 60,
+ "Country": 4,
+ "Address": "383-3675 Ultrices, St.",
+ "Married": false
+ },
+ {
+ "Name": "Kane Burnett",
+ "Age": 80,
+ "Country": 1,
+ "Address": "759-8212 Dolor. Ave",
+ "Married": false
+ },
+ {
+ "Name": "Stewart Wilson",
+ "Age": 46,
+ "Country": 7,
+ "Address": "718-7845 Sagittis. Av.",
+ "Married": false
+ },
+ {
+ "Name": "Charity Holcomb",
+ "Age": 31,
+ "Country": 6,
+ "Address": "641-7892 Enim. Ave",
+ "Married": false
+ },
+ {
+ "Name": "Kyra Cummings",
+ "Age": 43,
+ "Country": 4,
+ "Address": "P.O. Box 702, 6621 Mus. Av.",
+ "Married": false
+ },
+ {
+ "Name": "Stuart Wallace",
+ "Age": 25,
+ "Country": 7,
+ "Address": "648-4990 Sed Rd.",
+ "Married": true
+ },
+ {
+ "Name": "Carter Clarke",
+ "Age": 59,
+ "Country": 6,
+ "Address": "Ap #547-2921 A Street",
+ "Married": false
+ }
+ ];
+
+ db.users = [
+ {
+ "ID": "x",
+ "Account": "A758A693-0302-03D1-AE53-EEFE22855556",
+ "Name": "Carson Kelley",
+ "RegisterDate": "2002-04-20T22:55:52-07:00"
+ },
+ {
+ "Account": "D89FF524-1233-0CE7-C9E1-56EFF017A321",
+ "Name": "Prescott Griffin",
+ "RegisterDate": "2011-02-22T05:59:55-08:00"
+ },
+ {
+ "Account": "06FAAD9A-5114-08F6-D60C-961B2528B4F0",
+ "Name": "Amir Saunders",
+ "RegisterDate": "2014-08-13T09:17:49-07:00"
+ },
+ {
+ "Account": "EED7653D-7DD9-A722-64A8-36A55ECDBE77",
+ "Name": "Derek Thornton",
+ "RegisterDate": "2012-02-27T01:31:07-08:00"
+ },
+ {
+ "Account": "2A2E6D40-FEBD-C643-A751-9AB4CAF1E2F6",
+ "Name": "Fletcher Romero",
+ "RegisterDate": "2010-06-25T15:49:54-07:00"
+ },
+ {
+ "Account": "3978F8FA-DFF0-DA0E-0A5D-EB9D281A3286",
+ "Name": "Thaddeus Stein",
+ "RegisterDate": "2013-11-10T07:29:41-08:00"
+ },
+ {
+ "Account": "658DBF5A-176E-569A-9273-74FB5F69FA42",
+ "Name": "Nash Knapp",
+ "RegisterDate": "2005-06-24T09:11:19-07:00"
+ },
+ {
+ "Account": "76D2EE4B-7A73-1212-F6F2-957EF8C1F907",
+ "Name": "Quamar Vega",
+ "RegisterDate": "2011-04-13T20:06:29-07:00"
+ },
+ {
+ "Account": "00E46809-A595-CE82-C5B4-D1CAEB7E3E58",
+ "Name": "Philip Galloway",
+ "RegisterDate": "2008-08-21T18:59:38-07:00"
+ },
+ {
+ "Account": "C196781C-DDCC-AF83-DDC2-CA3E851A47A0",
+ "Name": "Mason French",
+ "RegisterDate": "2000-11-15T00:38:37-08:00"
+ },
+ {
+ "Account": "5911F201-818A-B393-5888-13157CE0D63F",
+ "Name": "Ross Cortez",
+ "RegisterDate": "2010-05-27T17:35:32-07:00"
+ },
+ {
+ "Account": "B8BB78F9-E1A1-A956-086F-E12B6FE168B6",
+ "Name": "Logan King",
+ "RegisterDate": "2003-07-08T16:58:06-07:00"
+ },
+ {
+ "Account": "06F636C3-9599-1A2D-5FD5-86B24ADDE626",
+ "Name": "Cedric Leblanc",
+ "RegisterDate": "2011-06-30T14:30:10-07:00"
+ },
+ {
+ "Account": "FE880CDD-F6E7-75CB-743C-64C6DE192412",
+ "Name": "Simon Sullivan",
+ "RegisterDate": "2013-06-11T16:35:07-07:00"
+ },
+ {
+ "Account": "BBEDD673-E2C1-4872-A5D3-C4EBD4BE0A12",
+ "Name": "Jamal West",
+ "RegisterDate": "2001-03-16T20:18:29-08:00"
+ },
+ {
+ "Account": "19BC22FA-C52E-0CC6-9552-10365C755FAC",
+ "Name": "Hector Morales",
+ "RegisterDate": "2012-11-01T01:56:34-07:00"
+ },
+ {
+ "Account": "A8292214-2C13-5989-3419-6B83DD637D6C",
+ "Name": "Herrod Hart",
+ "RegisterDate": "2008-03-13T19:21:04-07:00"
+ },
+ {
+ "Account": "0285564B-F447-0E7F-EAA1-7FB8F9C453C8",
+ "Name": "Clark Maxwell",
+ "RegisterDate": "2004-08-05T08:22:24-07:00"
+ },
+ {
+ "Account": "EA78F076-4F6E-4228-268C-1F51272498AE",
+ "Name": "Reuben Walter",
+ "RegisterDate": "2011-01-23T01:55:59-08:00"
+ },
+ {
+ "Account": "6A88C194-EA21-426F-4FE2-F2AE33F51793",
+ "Name": "Ira Ingram",
+ "RegisterDate": "2008-08-15T05:57:46-07:00"
+ },
+ {
+ "Account": "4275E873-439C-AD26-56B3-8715E336508E",
+ "Name": "Damian Morrow",
+ "RegisterDate": "2015-09-13T01:50:55-07:00"
+ },
+ {
+ "Account": "A0D733C4-9070-B8D6-4387-D44F0BA515BE",
+ "Name": "Macon Farrell",
+ "RegisterDate": "2011-03-14T05:41:40-07:00"
+ },
+ {
+ "Account": "B3683DE8-C2FA-7CA0-A8A6-8FA7E954F90A",
+ "Name": "Joel Galloway",
+ "RegisterDate": "2003-02-03T04:19:01-08:00"
+ },
+ {
+ "Account": "01D95A8E-91BC-2050-F5D0-4437AAFFD11F",
+ "Name": "Rigel Horton",
+ "RegisterDate": "2015-06-20T11:53:11-07:00"
+ },
+ {
+ "Account": "F0D12CC0-31AC-A82E-FD73-EEEFDBD21A36",
+ "Name": "Sylvester Gaines",
+ "RegisterDate": "2004-03-12T09:57:13-08:00"
+ },
+ {
+ "Account": "874FCC49-9A61-71BC-2F4E-2CE88348AD7B",
+ "Name": "Abbot Mckay",
+ "RegisterDate": "2008-12-26T20:42:57-08:00"
+ },
+ {
+ "Account": "B8DA1912-20A0-FB6E-0031-5F88FD63EF90",
+ "Name": "Solomon Green",
+ "RegisterDate": "2013-09-04T01:44:47-07:00"
+ }
+ ];
+
+}()); \ No newline at end of file
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-de.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-de.js
new file mode 100644
index 0000000..4bad06d
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-de.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.de = {
+ grid: {
+ noDataContent: "Die Daten konnten nicht gefunden werden",
+ deleteConfirm: "Möchten Sie die Daten unwiederruflich löschen?",
+ pagerFormat: "Seiten: {first} {prev} {pages} {next} {last}    {pageIndex} von {pageCount}",
+ pagePrevText: "<",
+ pageNextText: ">",
+ pageFirstText: "<<",
+ pageLastText: ">>",
+ loadMessage: "Bitte warten...",
+ invalidMessage: "Ihre Eingabe ist nicht zulässig!"
+ },
+
+ loadIndicator: {
+ message: "Lädt..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Suche",
+ insertModeButtonTooltip: "Eintrag hinzufügen",
+ editButtonTooltip: "Bearbeiten",
+ deleteButtonTooltip: "Löschen",
+ searchButtonTooltip: "Eintrag finden",
+ clearFilterButtonTooltip: "Filter zurücksetzen",
+ insertButtonTooltip: "Hinzufügen",
+ updateButtonTooltip: "Speichern",
+ cancelEditButtonTooltip: "Abbrechen"
+ }
+ },
+
+ validators: {
+ required: { message: "Dies ist ein Pflichtfeld" },
+ rangeLength: { message: "Die Länge der Eingabe liegt außerhalb des zulässigen Bereichs" },
+ minLength: { message: "Die Eingabe ist zu kurz" },
+ maxLength: { message: "Die Eingabe ist zu lang" },
+ pattern: { message: "Die Eingabe entspricht nicht dem gewünschten Muster" },
+ range: { message: "Der eingegebene Wert liegt außerhalb des zulässigen Bereichs" },
+ min: { message: "Der eingegebene Wert ist zu niedrig" },
+ max: { message: "Der eingegebene Wert ist zu hoch" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-es.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-es.js
new file mode 100644
index 0000000..e8fd7fe
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-es.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.es = {
+ grid: {
+ noDataContent: "No encontrado",
+ deleteConfirm: "¿Está seguro?",
+ pagerFormat: "Paginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
+ pagePrevText: "Anterior",
+ pageNextText: "Siguiente",
+ pageFirstText: "Primero",
+ pageLastText: "Ultimo",
+ loadMessage: "Por favor, espere...",
+ invalidMessage: "¡Datos no válidos!"
+ },
+
+ loadIndicator: {
+ message: "Cargando..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Cambiar a búsqueda",
+ insertModeButtonTooltip: "Cambiar a inserción",
+ editButtonTooltip: "Editar",
+ deleteButtonTooltip: "Suprimir",
+ searchButtonTooltip: "Buscar",
+ clearFilterButtonTooltip: "Borrar filtro",
+ insertButtonTooltip: "Insertar",
+ updateButtonTooltip: "Actualizar",
+ cancelEditButtonTooltip: "Cancelar edición"
+ }
+ },
+
+ validators: {
+ required: { message: "Campo requerido" },
+ rangeLength: { message: "La longitud del valor está fuera del intervalo definido" },
+ minLength: { message: "La longitud del valor es demasiado corta" },
+ maxLength: { message: "La longitud del valor es demasiado larga" },
+ pattern: { message: "El valor no se ajusta al patrón definido" },
+ range: { message: "Valor fuera del rango definido" },
+ min: { message: "Valor demasiado bajo" },
+ max: { message: "Valor demasiado alto" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-fr.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-fr.js
new file mode 100644
index 0000000..c0f6f71
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-fr.js
@@ -0,0 +1,47 @@
+(function(jsGrid) {
+
+ jsGrid.locales.fr = {
+ grid: {
+ noDataContent: "Pas de données",
+ deleteConfirm: "Êtes-vous sûr ?",
+ pagerFormat: "Pages: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
+ pagePrevText: "<",
+ pageNextText: ">",
+ pageFirstText: "<<",
+ pageLastText: ">>",
+ loadMessage: "Chargement en cours...",
+ invalidMessage: "Des données incorrectes sont entrés !"
+ },
+
+ loadIndicator: {
+ message: "Chargement en cours..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Recherche",
+ insertModeButtonTooltip: "Ajouter une entrée",
+ editButtonTooltip: "Changer",
+ deleteButtonTooltip: "Effacer",
+ searchButtonTooltip: "Trouve",
+ clearFilterButtonTooltip: "Effacer",
+ insertButtonTooltip: "Ajouter",
+ updateButtonTooltip: "Sauvegarder",
+ cancelEditButtonTooltip: "Annuler"
+ }
+ },
+
+ validators: {
+ required: { message: "Champ requis" },
+ rangeLength: { message: "Longueur de la valeur du champ est hors de la plage définie" },
+ minLength: { message: "La valeur du champ est trop court" },
+ maxLength: { message: "La valeur du champ est trop long" },
+ pattern: { message: "La valeur du champ ne correspond pas à la configuration définie" },
+ range: { message: "La valeur du champ est hors de la plage définie" },
+ min: { message: "La valeur du champ est trop petit" },
+ max: { message: "La valeur du champ est trop grande" }
+ }
+ };
+
+}(jsGrid, jQuery));
+
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-he.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-he.js
new file mode 100644
index 0000000..42c294c
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-he.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.he = {
+ grid: {
+ noDataContent: "לא נמצא",
+ deleteConfirm: "האם אתה בטוח?",
+ pagerFormat: "עמודים: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} מתוך {pageCount}",
+ pagePrevText: "הקודם",
+ pageNextText: "הבא",
+ pageFirstText: "ראשון",
+ pageLastText: "אחרון",
+ loadMessage: "אנא המתן ...",
+ invalidMessage: "נתונים לא חוקיים!"
+ },
+
+ loadIndicator: {
+ message: "טוען..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "ביצוע חיפוש",
+ insertModeButtonTooltip: "ביצוע עריכת שורה",
+ editButtonTooltip: "עריכה",
+ deleteButtonTooltip: "מחיקה",
+ searchButtonTooltip: "חיפוש",
+ clearFilterButtonTooltip: "ניקוי מסנן",
+ insertButtonTooltip: "הכנסה",
+ updateButtonTooltip: "עדכון",
+ cancelEditButtonTooltip: "ביטול עריכה"
+ }
+ },
+
+ validators: {
+ required: { message: "שדה נדרש" },
+ rangeLength: { message: "אורכו של הערך הוא מחוץ לטווח המוגדר" },
+ minLength: { message: "אורכו של הערך קצר מדי" },
+ maxLength: { message: "אורכו של הערך ארוך מדי" },
+ pattern: { message: "אורכו של הערך ארוך מדי" },
+ range: { message: "ערך מחוץ לטווח" },
+ min: { message: "ערך נמוך מדי" },
+ max: { message: "גבוה מדי" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ja.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ja.js
new file mode 100644
index 0000000..acc506f
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ja.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.ja = {
+ grid: {
+ noDataContent: "データが見つかりません。",
+ deleteConfirm: "削除しますよろしですか。",
+ pagerFormat: "頁: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; 【{pageIndex}/{pageCount}】",
+ pagePrevText: "前",
+ pageNextText: "次",
+ pageFirstText: "最初",
+ pageLastText: "最後",
+ loadMessage: "しばらくお待ちください…",
+ invalidMessage: "入力されたデータが不正です。"
+ },
+
+ loadIndicator: {
+ message: "処理中…"
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "検索モードへ",
+ insertModeButtonTooltip: "登録モードへ",
+ editButtonTooltip: "編集",
+ deleteButtonTooltip: "削除",
+ searchButtonTooltip: "フィルター",
+ clearFilterButtonTooltip: "クリア",
+ insertButtonTooltip: "登録",
+ updateButtonTooltip: "更新",
+ cancelEditButtonTooltip: "編集戻す"
+ }
+ },
+
+ validators: {
+ required: { message: "項目が必要です。" },
+ rangeLength: { message: "項目の桁数が範囲外です。" },
+ minLength: { message: "項目の桁数が超過しています。" },
+ maxLength: { message: "項目の桁数が不足しています。" },
+ pattern: { message: "項目の値がパターンに一致しません。" },
+ range: { message: "項目の値が範囲外です。" },
+ min: { message: "項目の値が超過しています。" },
+ max: { message: "項目の値が不足しています。" }
+ }
+ };
+
+}(jsGrid, jQuery)); \ No newline at end of file
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ka.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ka.js
new file mode 100644
index 0000000..281a230
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ka.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.ka = {
+ grid: {
+ noDataContent: "მონაცემები ცარიელია.",
+ deleteConfirm: "ნამდვილად გსურთ ჩანაწერის წაშლა?",
+ pagerFormat: "გვერდები: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} - {pageCount} დან.",
+ pagePrevText: "<",
+ pageNextText: ">",
+ pageFirstText: "<<",
+ pageLastText: ">>",
+ loadMessage: "გთხოვთ დაიცადოთ...",
+ invalidMessage: "შეყვანილია არასწორი მონაცემები!"
+ },
+
+ loadIndicator: {
+ message: "მიმდინარეობს ჩატვირთვა..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "ძებნა",
+ insertModeButtonTooltip: "ჩანაწერის დამატება",
+ editButtonTooltip: "შესწორება",
+ deleteButtonTooltip: "წაშლა",
+ searchButtonTooltip: "ძებნა",
+ clearFilterButtonTooltip: "ფილტრის გასუფთავება",
+ insertButtonTooltip: "დამატება",
+ updateButtonTooltip: "შენახვა",
+ cancelEditButtonTooltip: "გაუქმება"
+ }
+ },
+
+ validators: {
+ required: { message: "ველი აუცილებელია შესავსებად." },
+ rangeLength: { message: "შეყვანილი ჩანაწერის ზომა არ ექვემდებარება დიაპაზონს." },
+ minLength: { message: "შეყვანილი ჩანაწერის ზომა საკმაოდ პატარა არის." },
+ maxLength: { message: "შეყვანილი ჩანაწერის ზომა საკმაოდ დიდი არის." },
+ pattern: { message: "შეყვანილი მნიშვნელობა არ ემთხვევა მითითებულ შაბლონს." },
+ range: { message: "შეყვანილი ინფორმაცია არ ჯდება დიაპაზონში." },
+ min: { message: "შეყვანილი ინფორმაციის ზომა საკმაოდ პატარა არის." },
+ max: { message: "შეყვანილი ინფორმაციის ზომა საკმაოდ დიდი არის." }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pl.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pl.js
new file mode 100644
index 0000000..e5fbf41
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pl.js
@@ -0,0 +1,62 @@
+(function(jsGrid) {
+
+ jsGrid.locales.pl = {
+ grid: {
+ noDataContent: "Nie znaleziono",
+ deleteConfirm: "Czy jesteś pewien?",
+ pagerFormat: "Strony: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} z {pageCount}",
+ pagePrevText: "Poprzednia",
+ pageNextText: "Następna",
+ pageFirstText: "Pierwsza",
+ pageLastText: "Ostatnia",
+ loadMessage: "Proszę czekać...",
+ invalidMessage: "Wprowadzono nieprawidłowe dane!"
+ },
+
+ loadIndicator: {
+ message: "Ładowanie..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Wyszukiwanie",
+ insertModeButtonTooltip: "Dodawanie",
+ editButtonTooltip: "Edytuj",
+ deleteButtonTooltip: "Usuń",
+ searchButtonTooltip: "Szukaj",
+ clearFilterButtonTooltip: "Wyczyść filtr",
+ insertButtonTooltip: "Dodaj",
+ updateButtonTooltip: "Aktualizuj",
+ cancelEditButtonTooltip: "Anuluj edytowanie"
+ }
+ },
+
+ validators: {
+ required: {
+ message: "Pole jest wymagane"
+ },
+ rangeLength: {
+ message: "Długość wartości pola znajduje się poza zdefiniowanym zakresem"
+ },
+ minLength: {
+ message: "Wartość pola jest zbyt krótka"
+ },
+ maxLength: {
+ message: "Wartość pola jest zbyt długa"
+ },
+ pattern: {
+ message: "Wartość pola nie zgadza się ze zdefiniowanym wzorem"
+ },
+ range: {
+ message: "Wartość pola znajduje się poza zdefiniowanym zakresem"
+ },
+ min: {
+ message: "Wartość pola jest zbyt mała"
+ },
+ max: {
+ message: "Wartość pola jest zbyt duża"
+ }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt-br.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt-br.js
new file mode 100644
index 0000000..d9df06c
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt-br.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales["pt-br"] = {
+ grid: {
+ noDataContent: "Não encontrado",
+ deleteConfirm: "Você tem certeza que deseja remover este item?",
+ pagerFormat: "Páginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
+ pagePrevText: "Anterior",
+ pageNextText: "Seguinte",
+ pageFirstText: "Primeira",
+ pageLastText: "Última",
+ loadMessage: "Por favor, espere...",
+ invalidMessage: "Dados inválidos!"
+ },
+
+ loadIndicator: {
+ message: "Carregando..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Mudar para busca",
+ insertModeButtonTooltip: "Mudar para inserção",
+ editButtonTooltip: "Editar",
+ deleteButtonTooltip: "Remover",
+ searchButtonTooltip: "Buscar",
+ clearFilterButtonTooltip: "Remover filtro",
+ insertButtonTooltip: "Adicionar",
+ updateButtonTooltip: "Atualizar",
+ cancelEditButtonTooltip: "Cancelar Edição"
+ }
+ },
+
+ validators: {
+ required: { message: "Campo obrigatório" },
+ rangeLength: { message: "O valor esta fora do intervaldo definido" },
+ minLength: { message: "O comprimento do valor é muito curto" },
+ maxLength: { message: "O comprimento valor é muito longo" },
+ pattern: { message: "O valor informado não é compatível com o padrão" },
+ range: { message: "O valor informado esta fora do limite definido" },
+ min: { message: "O valor é muito curto" },
+ max: { message: "O valor é muito longo" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt.js
new file mode 100644
index 0000000..25e3e1a
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-pt.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales.pt = {
+ grid: {
+ noDataContent: "Não encontrado",
+ deleteConfirm: "Você tem certeza que deseja remover este item?",
+ pagerFormat: "Páginas: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} de {pageCount}",
+ pagePrevText: "Anterior",
+ pageNextText: "Seguinte",
+ pageFirstText: "Primeira",
+ pageLastText: "Última",
+ loadMessage: "Por favor, espere...",
+ invalidMessage: "Dados inválidos!"
+ },
+
+ loadIndicator: {
+ message: "Carregando..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Mudar para busca",
+ insertModeButtonTooltip: "Mudar para inserção",
+ editButtonTooltip: "Editar",
+ deleteButtonTooltip: "Remover",
+ searchButtonTooltip: "Buscar",
+ clearFilterButtonTooltip: "Remover filtro",
+ insertButtonTooltip: "Adicionar",
+ updateButtonTooltip: "Atualizar",
+ cancelEditButtonTooltip: "Cancelar Edição"
+ }
+ },
+
+ validators: {
+ required: { message: "Campo obrigatório" },
+ rangeLength: { message: "O valor esta fora do intervaldo definido" },
+ minLength: { message: "O comprimento do valor é muito curto" },
+ maxLength: { message: "O comprimento valor é muito longo" },
+ pattern: { message: "O valor informado não é compatível com o padrão" },
+ range: { message: "O valor informado esta fora do limite definido" },
+ min: { message: "O valor é muito curto" },
+ max: { message: "O valor é muito longo" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ru.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ru.js
new file mode 100644
index 0000000..7fa469f
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-ru.js
@@ -0,0 +1,47 @@
+(function(jsGrid) {
+
+ jsGrid.locales.ru = {
+ grid: {
+ noDataContent: "Данных не найдено",
+ deleteConfirm: "Вы действительно хотите удалить запись?",
+ pagerFormat: "Страницы: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} из {pageCount}",
+ pagePrevText: "<",
+ pageNextText: ">",
+ pageFirstText: "<<",
+ pageLastText: ">>",
+ loadMessage: "Пожалуйста, подождите...",
+ invalidMessage: "Введены неверные данные!"
+ },
+
+ loadIndicator: {
+ message: "Загрузка..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Поиск",
+ insertModeButtonTooltip: "Добавить запись",
+ editButtonTooltip: "Изменить",
+ deleteButtonTooltip: "Удалить",
+ searchButtonTooltip: "Найти",
+ clearFilterButtonTooltip: "Очистить фильтр",
+ insertButtonTooltip: "Добавить",
+ updateButtonTooltip: "Сохранить",
+ cancelEditButtonTooltip: "Отменить"
+ }
+ },
+
+ validators: {
+ required: { message: "Поле обязательно для заполения" },
+ rangeLength: { message: "Длинна введенного значения вне допустимого диапазона" },
+ minLength: { message: "Введенное значение слишком короткое" },
+ maxLength: { message: "Введенное значение слишком длинное" },
+ pattern: { message: "Введенное значение не соответствует заданному шаблону" },
+ range: { message: "Введенное значение вне допустимого диапазона" },
+ min: { message: "Введенное значение слишком маленькое" },
+ max: { message: "Введенное значение слишком большое" }
+ }
+ };
+
+}(jsGrid, jQuery));
+
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-tr.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-tr.js
new file mode 100644
index 0000000..bbb7c5c
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-tr.js
@@ -0,0 +1,47 @@
+(function(jsGrid) {
+
+ jsGrid.locales.tr = {
+ grid: {
+ noDataContent: "Kayıt Bulunamadı",
+ deleteConfirm: "Emin misiniz ?",
+ pagerFormat: "Sayfalar: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
+ pagePrevText: "<",
+ pageNextText: ">",
+ pageFirstText: "<<",
+ pageLastText: ">>",
+ loadMessage: "Lütfen bekleyiniz...",
+ invalidMessage: "Geçersiz veri girişi !"
+ },
+
+ loadIndicator: {
+ message: "Yükleniyor..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "Arama moduna geç",
+ insertModeButtonTooltip: "Yeni kayıt moduna geç",
+ editButtonTooltip: "Değiştir",
+ deleteButtonTooltip: "Sil",
+ searchButtonTooltip: "Bul",
+ clearFilterButtonTooltip: "Filtreyi temizle",
+ insertButtonTooltip: "Ekle",
+ updateButtonTooltip: "Güncelle",
+ cancelEditButtonTooltip: "Güncelleme iptali"
+ }
+ },
+
+ validators: {
+ required: { message: "Gerekli alandır" },
+ rangeLength: { message: "Alan değerinin uzunluğu tanımlanan aralık dışındadır" },
+ minLength: { message: "Alan değeri çok kısadır" },
+ maxLength: { message: "Alan değeri çok uzundur" },
+ pattern: { message: "Alan değeri tanımlanan şablon ile eşleşmiyor" },
+ range: { message: "Alan değeri tanımlı aralığın dışındadır" },
+ min: { message: "Alan değeri çok küçüktür" },
+ max: { message: "Alan değeri çok büyüktür" }
+ }
+ };
+
+}(jsGrid, jQuery));
+
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-cn.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-cn.js
new file mode 100644
index 0000000..87c0055
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-cn.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales["zh-cn"] = {
+ grid: {
+ noDataContent: "暂无数据",
+ deleteConfirm: "确认删除?",
+ pagerFormat: "页码: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
+ pagePrevText: "上一页",
+ pageNextText: "下一页",
+ pageFirstText: "第一页",
+ pageLastText: "最后页",
+ loadMessage: "请稍后...",
+ invalidMessage: "数据有误!"
+ },
+
+ loadIndicator: {
+ message: "载入中..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "切换为搜索",
+ insertModeButtonTooltip: "切换为新增",
+ editButtonTooltip: "编辑",
+ deleteButtonTooltip: "删除",
+ searchButtonTooltip: "搜索",
+ clearFilterButtonTooltip: "清空过滤",
+ insertButtonTooltip: "插入",
+ updateButtonTooltip: "更新",
+ cancelEditButtonTooltip: "取消编辑"
+ }
+ },
+
+ validators: {
+ required: { message: "字段必填" },
+ rangeLength: { message: "字段值长度超过定义范围" },
+ minLength: { message: "字段长度过短" },
+ maxLength: { message: "字段长度过长" },
+ pattern: { message: "字段值不符合定义规则" },
+ range: { message: "字段值超过定义范围" },
+ min: { message: "字段值太小" },
+ max: { message: "字段值太大" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-tw.js b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-tw.js
new file mode 100644
index 0000000..2a22845
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/i18n/jsgrid-zh-tw.js
@@ -0,0 +1,46 @@
+(function(jsGrid) {
+
+ jsGrid.locales["zh-tw"] = {
+ grid: {
+ noDataContent: "暫無資料",
+ deleteConfirm: "確認刪除?",
+ pagerFormat: "頁碼: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} / {pageCount}",
+ pagePrevText: "上一頁",
+ pageNextText: "下一頁",
+ pageFirstText: "第一頁",
+ pageLastText: "最後一頁",
+ loadMessage: "請稍候...",
+ invalidMessage: "輸入資料不正確"
+ },
+
+ loadIndicator: {
+ message: "載入中..."
+ },
+
+ fields: {
+ control: {
+ searchModeButtonTooltip: "切換為搜尋",
+ insertModeButtonTooltip: "切換為新增",
+ editButtonTooltip: "編輯",
+ deleteButtonTooltip: "刪除",
+ searchButtonTooltip: "搜尋",
+ clearFilterButtonTooltip: "清除搜尋條件",
+ insertButtonTooltip: "新增",
+ updateButtonTooltip: "修改",
+ cancelEditButtonTooltip: "取消編輯"
+ }
+ },
+
+ validators: {
+ required: { message: "欄位必填" },
+ rangeLength: { message: "欄位字串長度超出範圍" },
+ minLength: { message: "欄位字串長度太短" },
+ maxLength: { message: "欄位字串長度太長" },
+ pattern: { message: "欄位字串不符合規則" },
+ range: { message: "欄位數值超出範圍" },
+ min: { message: "欄位數值太小" },
+ max: { message: "欄位數值太大" }
+ }
+ };
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid-theme.css b/build/resources/main/static/plugins/jsgrid/jsgrid-theme.css
new file mode 100644
index 0000000..ebc7855
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid-theme.css
@@ -0,0 +1,258 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+.jsgrid-grid-header,
+.jsgrid-grid-body,
+.jsgrid-header-row > .jsgrid-header-cell,
+.jsgrid-filter-row > .jsgrid-cell,
+.jsgrid-insert-row > .jsgrid-cell,
+.jsgrid-edit-row > .jsgrid-cell {
+ border: 1px solid #e9e9e9;
+}
+
+.jsgrid-header-row > .jsgrid-header-cell {
+ border-top: 0;
+}
+
+.jsgrid-header-row > .jsgrid-header-cell,
+.jsgrid-filter-row > .jsgrid-cell,
+.jsgrid-insert-row > .jsgrid-cell {
+ border-bottom: 0;
+}
+
+.jsgrid-header-row > .jsgrid-header-cell:first-child,
+.jsgrid-filter-row > .jsgrid-cell:first-child,
+.jsgrid-insert-row > .jsgrid-cell:first-child {
+ border-left: none;
+}
+
+.jsgrid-header-row > .jsgrid-header-cell:last-child,
+.jsgrid-filter-row > .jsgrid-cell:last-child,
+.jsgrid-insert-row > .jsgrid-cell:last-child {
+ border-right: none;
+}
+
+.jsgrid-header-row .jsgrid-align-right,
+.jsgrid-header-row .jsgrid-align-left {
+ text-align: center;
+}
+
+.jsgrid-grid-header {
+ background: #f9f9f9;
+}
+
+.jsgrid-header-scrollbar {
+ scrollbar-arrow-color: #f1f1f1;
+ scrollbar-base-color: #f1f1f1;
+ scrollbar-3dlight-color: #f1f1f1;
+ scrollbar-highlight-color: #f1f1f1;
+ scrollbar-track-color: #f1f1f1;
+ scrollbar-shadow-color: #f1f1f1;
+ scrollbar-dark-shadow-color: #f1f1f1;
+}
+
+.jsgrid-header-scrollbar::-webkit-scrollbar {
+ visibility: hidden;
+}
+
+.jsgrid-header-scrollbar::-webkit-scrollbar-track {
+ background: #f1f1f1;
+}
+
+.jsgrid-header-sortable:hover {
+ cursor: pointer;
+ background: #fcfcfc;
+}
+
+.jsgrid-header-row .jsgrid-header-sort {
+ background: #c4e2ff;
+}
+
+.jsgrid-header-sort:before {
+ content: " ";
+ display: block;
+ float: left;
+ width: 0;
+ height: 0;
+ border-style: solid;
+}
+
+.jsgrid-header-sort-asc:before {
+ border-width: 0 5px 5px 5px;
+ border-color: transparent transparent #009a67 transparent;
+}
+
+.jsgrid-header-sort-desc:before {
+ border-width: 5px 5px 0 5px;
+ border-color: #009a67 transparent transparent transparent;
+}
+
+.jsgrid-grid-body {
+ border-top: none;
+}
+
+.jsgrid-cell {
+ border: #f3f3f3 1px solid;
+}
+
+.jsgrid-grid-body .jsgrid-row:first-child .jsgrid-cell,
+.jsgrid-grid-body .jsgrid-alt-row:first-child .jsgrid-cell {
+ border-top: none;
+}
+
+.jsgrid-grid-body .jsgrid-cell:first-child {
+ border-left: none;
+}
+
+.jsgrid-grid-body .jsgrid-cell:last-child {
+ border-right: none;
+}
+
+.jsgrid-row > .jsgrid-cell {
+ background: #fff;
+}
+
+.jsgrid-alt-row > .jsgrid-cell {
+ background: #fcfcfc;
+}
+
+.jsgrid-header-row > .jsgrid-header-cell {
+ background: #f9f9f9;
+}
+
+.jsgrid-filter-row > .jsgrid-cell {
+ background: #fcfcfc;
+}
+
+.jsgrid-insert-row > .jsgrid-cell {
+ background: #e3ffe5;
+}
+
+.jsgrid-edit-row > .jsgrid-cell {
+ background: #fdffe3;
+}
+
+.jsgrid-selected-row > .jsgrid-cell {
+ background: #c4e2ff;
+ border-color: #c4e2ff;
+}
+
+.jsgrid-nodata-row > .jsgrid-cell {
+ background: #fff;
+}
+
+.jsgrid-invalid input,
+.jsgrid-invalid select,
+.jsgrid-invalid textarea {
+ background: #ffe3e5;
+ border: 1px solid #ff808a;
+}
+
+.jsgrid-pager-current-page {
+ font-weight: bold;
+}
+
+.jsgrid-pager-nav-inactive-button a {
+ color: #d3d3d3;
+}
+
+.jsgrid-button + .jsgrid-button {
+ margin-left: 5px;
+}
+
+.jsgrid-button:hover {
+ opacity: .5;
+ transition: opacity 200ms linear;
+}
+
+.jsgrid .jsgrid-button {
+ width: 16px;
+ height: 16px;
+ border: none;
+ cursor: pointer;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAFgEAYAAADx4WWjAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAZjElEQVR42u2deVyU1f7HzzyzDzCA7MgihCsY7uYOiZIamebVFl/Wy8zSxLTQuld/lmIuCGIu9cruLa9lXlNTUQsVUgQRNBbZF5F9lWEbZpj9/P74doQZ87LMDHjvPe9/vj7MPOf5fp6zjc/3e86D0H8rNTVRUd988/rrxpZTV3f48PHjixb1m+N5eVOmvP76hQtXryKEEMYVFWFhERG7dvW2nIKC4OBVq/71L1JOWdk774SHb9tmcoc1mpaWtjYLi6Ki+fPff/+f/7x2DS6YlobQpEkYJyQgxOViXFGxYUNExN693ZVXWDh//urV339/8yZCQiGUM3EixqTcqqq//e3gwQ8+MJkAnU6tVqvZbKk0KSkj47nnfv/d2nrcOInk1i2EHBw6HSBCyss3btyz53Eh4PiJEwkJCAkEGKenIzRlCsaJiQhZW2OcmentHRhYUCCX5+Tcv+/nZ/KaIKjVlZUSibPz3bu2tv7+jY1JSQjZ22P8++8ITZiA8c2bCIlEGNfU7Njx9dcbN5aXv/fe55/v2kXueFfHrawwzsjw8po1Kz9fp5PJVCoOx9T+sp4spLq6qcnJKTPTzy8wMDtbpWpurqlxcBAIEPL2RkihQKi8HCEWCyEOByGBACEPD4RkMoSysxGyshoxYtKkvLxnn83IiI3192cYoZDL1WjMduefhEbT2Njebm2dnT1x4sKFt26lpCDk7Q01Mm5cp719GyEPD4zz8+fNe/PNixcx1moxZhhz+9ftBTgce3tLy9ZWodDT08enqEirRUguh89YrE6r1SLU3o6QWDx27HPP3bjBYrHZLJZO1+933JDCwnnzVq8+eZJ0xvR0hKZNwzg5GSF3d4xJjXRt+2IxxpWVYWFRUX/964A5npc3e/aKFT/+aNg5k5IQsrPDOC9v/PjXX09Nzcpyc3vhhbKy5GSEXFygSY0fD6MWj4dxRcWmTZGRW7b0m+P5+dOnr1jx00+Gw+HNmwhZWmKcmTliRFBQdjb5vlrd1NTSYm2dmsrnDx0qlycnI+TsrC9EIMC4ouKDDyIitm41ucNqtUTS3GxlVVQ0f/66dZ0TWUYGQjNmQJPo6rhOp1RqtWy2YTkKRUFBVdXQoampPN7QoR0dt26BkPR0hCZPxpjMyDCRbdxoMgE6nUqlVnO5UmlSUmbmtGl374rFY8c2NcXFwQXv3RsxIigoKwtjpVKr7X5UUSgKCiorfXxSU0Wi4cOl0vh4KCcz08srMPD+fbk8O7u4+NlnTV4ThI6OrKzS0qFDc3JCQpYuPX1ap+vo0Ggev+PdIZPduVNY6O+flRUUFBLyyy9arVSqUAiFZnPcEI2mrq611cbG2HJUqrKyhgZX135znEKhUCgUCoVCoVAoFAqFQvlP4FGIyd//wIGYGPL0eOFCsOSRooWF/jHG3RT7R7kkwNHeDpY8W7106d69DRteesn4p9UGQbdZs8BOmAD26FGwajVYS8veFd/RAZbExtatA6tUgjW5gFdfBXv4MFhnZ7hTpEZ6D9TsiRNwFBsL9u23jXWc8FiUEi5IwqFlZWBLSkAIqaGeOn7uHBzNnAl2yBAoRyo1lYDHnvfDBUiV+/qCfeYZcOjs2Z45/s03cBQQAHbUKFM7TmB19wVwyNMTjlJSwCYlgW1tBUtqjM8HGxwMdsYMcDw319SOE7qNuIAD5eVwtGwZ2CVLwFpbgyU1RvrQypXmdrzHAvQhTaCoCOzy5eDoqlVwnJEBtqnJ3I73UQAJEQkEYG1t9T8nf++/UJKRqQBsNvSR3sfQBkiASPTHaX+cV1sLTUirhWNWt4PCAAuorQU7aBDYpUv1P5fJwJo+rcZoAfqjyvvvgz18GJpQXh4cjxkD1vTjvdEC9IUcOwZHZDglwyyEtREqLu4vARQKhUKhUCgUCoVCoVAoFMp/JL1+GAuLe0isbM8esCScum/fhAkIpaWdP9/vAsCxyEg4mjsX7MOHYA2XEE6ZAtbKSv/vJBx786b+eVwuWEdHsHFxINT4xUAGT5G9vMA6O4NtbgZrbw+WPJVOTARLHrMTS+LC48aBbWsD29gI1sFB/zrGYyCAhIpIXJgE927fBktCSCtXgv31V/07v3gx2DVrwA4dCjYwEOzp02DPnDGTAJJSQCLq48eDhdVlCB05Apa0fdKESFxg506wOTlgSVDwtdfAkiaZkAC2vt5YAQaP10kA4949/b8/KcWARGQMAxrk76TJEFJTwVZWGuv4YwKgU5FQEYn/EkjwjrRxQwyTP8ioRM4j1NTAdQzLN4EAfVpa9I9JDSgUYEmb77ogtyvkcxL4Jpg+cvMEASTiQiBtndQQEWIogNQE+Zz0KYLp48dPEFBSon9MhlUS/yXDIhk+iQDSxFQqsGKxfjkkQG52AWT8N1yRTZYmks8N5wHSREjc2MlJ/3zTdd5uBJBF54Zt1s4OLJmgyJ0nAkjNkBwKMgOTpkfOM7sAMkoYdmYyqvzZqvquDhKhBJJy9qRRzIQCYJgjna2qSv9TMk+QpkCakkSi/33iMIFMWGQiMx3dRNQNL0gi825uYEeNAks6rYsL2Dfe0D+PjP9kxu43Afn5YOfNAxsSApYMk6SzkiZE/u7tDZb8GjWc2SkUCoVCoVAoFAqFQqFQKBTjMNuiHViaMmQIHJFNgqOjYQVIRcVTKwAcJ2swydJFEuEhi0sDAvRXCPYdk20pC46TQAiJIxgG/0iN/PILfN/DY8AF6C8WTU8Hu3YtWPIQ2HBNJXko/MMPxl6/z+u9wHGSOhATA5Y8nSZbnhcWgiXLch88AEtibl9/bayAXvcBcHzwYDgiKQfdpQ6Q9cW//AKWy4U+QCL3/SAAHCc5EyRyTxa+9RQfH3DcMIjYd7ptQvqdjaQIkM7YHSQ2tmSJqR3vVgA4TqKMpI331HHCokXg+MWLpnb8iQL0R5UbN/rm+MKF5nacYLAxBgkVVVeDJaNKT1m8GBwnuxmYH7b+cEi21ScB7qlT//3ppI2TO06aWv/xx0Tm7g72wgWwZCOLjz7689NITgS545cu9bfjBI6+Q6TTkt8wpEZIqtknn4B95ZWBuuOG/FEDZC8VAo8HliRnkJ8IU6eC46SmBp4/aoC0ebKnyq1bYElKQWEhOE5+GlAoFAqFQqFQKBQKhUKhUCgDi8nCrKdOFRffuTN+/LJlMTEREdevIyQUkuAqPPPu6JBKEbp6ddmy7dtDQubOdXPz9SUBk75jsk0dWSwWi8Xi8xFiGDbbygpsVwFwzGIhxGIZLpB7CgQAGg1CGMOjYmIJXY/JmhvjMfu7U80NFTDQUAEEnc6w0/6HCfDyEovt7auru442+oJ0Oq0WITc3CwtbW7Kk0Xg4P/10//6dO7D4n8Uiq097/mJkPp/N5nC02t9+q6rKzx89GiGBgIzyMP6zWGB5PKEQoZMni4tTUwMCLl4sLc3MFAg6OrRatbrn2z5DTTMMl8swDKNUshCKilqyBOPOiae3TYE4yGZDdpBAALkoGOvfBhYLFu12dMCaV6iR3l+PnMflCgQdHRyY8lUqEMDj9b5A8m0ixNDxzu/B36EmOq/T272qQQCbzeUKhUolB4oATX3b9rr3Z5Gm1Sm99+fDOVotB35kCYXGNyFyvlBImhD5BrnT0IRUKlhtbFwT0mi0Wo1m0CDWtWuVlbm5s2aBI2TRf8/fJ8/lMgybrVbn5zc319b6+a1Zc/36t98ePtzZJ4jjSqVcjlBExKxZK1Zs3jxpkqOjl9edO2q1TqfVksGjezDGGGMOh81msRhGJuPMmePuboqftZmZjY3l5QUFCKlUCsXhw11HI7jDarVKhVBIiKenv39MzMiRtrYuLsbHnU02D+TmNjXV1np6du2c+m2bYRgGoaoqmay5meRmGI/JBEBT+jPHzQv9LTTQUAEDjcn+Tww/srjczgmKWDJrwjHGCGFM8pGeIgHw61Au5/G4XIGgoYFhuFyBoPPXjk6n0ajVLBZMQP33hggKhUKhUCgUCoVCoVAoFAoFIYTQhx8mJHz//dq1CO3b9/LLLS0IRUQsXNjSsm3b7ds//fThh/3tT6+fzEFekK0t/Ivsbkw+M9ws2Pz04eEuxhgrlX+eF0S2rH2qBTxd9FrAk5I6GKZ/Q0uEXvcBFxdLSxuburquj9ExRsjBgc+3sGho6HcBH32UkHD8eGgoxHOFQmjThlkOGNvYCARCYXt7XFx1dUHBCy8gJBTC1vBQH2fPlpZmZISE7NiRknLmDIvV2qpSKRQWFlBeZ91AnJdhWCyGYRiZLCpq5szly8mbJXoPC6F9+xYuxBghFotE6v8810Gng78LBJBOKRLpj0FyOWx4rlBAJB7Cqo9DymcYCG+HhZ092/fGx3k8v+dJof/HR50/vyxxsOt9//flGANn27bp05cv37wZxnUSWyepBp0vRrCzEwgsLEgTCgq6eLGkJC1twQIiPDjY03PMmCtX5s718Bg16sqVtjalsqNDJAInSV3AkU7H4bBYLBab3d6+fTtCP/9svJAeExWVlnbx4vLlCO3Z8+KLGCO0e/eCBRgfOZKRERv77rv96ArUQG9PKC9va5NInJ07kzmgKdTXKxRSKdmfov/o9TzA4zFM/72F3gwCIEw60G530ut7CeO4QNB1tOkcVQzfO/MUCmCzGYbNbmyEcby1lQhgGIZhsfp/JqZQKBQKhUKhUCgUCoVCofxv0uPAQmNjW1tbm5NTfX1ra3Pzyy9LJFKpVDp9Oiy/cnXV6XQ6na69ncfj8bjcjAw7O0tLK6vz5729nZ1dXDIzzSWg2ydzKSlFRfn5lpbNzTKZVLpwYUtLe3t7+xtvqFQajUYzdqxWi5BOZ2mJMUTN1GqdTqcjb0cXiUpL6+vr6trbvbycnJyd79/vtxqorJRIHj4cOTI7u7y8rOz0aY1Gq9VqfX0h0I0Ql8tmczgPH8Kz0oICCIU4OkIUc/hwEIgQj8fhcDgajY+Pi4uLyzvvDBvm6urmduyYqQQ89nS6rq6lpalpzJi8vMrKioq4OHDI11ck4vEEghs3LCz4fIFgzhxwzNNz3rxx4yZMmDmTx+NyudyRIwUCHo/HGz5cLBaJRKIjR0AuhwM34rvvSkrq6mprN240Ww1cuZKenpaWmalUajQajb+/lZVQKBB8+WVg4OjR/v7vv9/bC1y/np19797LL0ON/PxzR4darVKxWFOnDh8+cuS0aY6O1tY2NsnJfa4BuVyhUCjc3cvLGxrq69evl8tVKqXS318k4vN5vOvX++o4Ac4/fx5q7IMPSHShpKS2trZ23z5ja4ApL29sbGgIDq6qamqSSF56ic2G8CjYnTuNvYC+kEOHBAIul8stK2tr6+iQy6dOLStraKir6+17DLoIaG6WyWSyoCCFQq1Wq6dO5XI5HA6npgbu0+3bphLw6IIMwzDMtWtk1WtDQ0tLS8vEiX0uD9anOzoyDEKdK7rJjt+mzz6BUaywkAReVSqtVqcj7+TogwCtVqfT6eRyksQBw6GDA3xsrnCevb3+XghqdZ8FQGdNT+dwGIZh8vNBkK8vCOnt+we6B2bsqVPBImRjIxKJRH2f4BgvLwcHJ6cLF5ydbW1tbGJjVSqtVqMhaTVhYaZyPD4+MzM9fc4cjQZjjGfOtLQUi8XikhJfXw+PIUN+/bXPAmxtraysrNLS7O3FYmvrL7+EO9/erlSq1Wp1aOj16zk5WVmQUtA3x+/dy8iwsdHptFqtNjqax3N0dHREaNiwIUO8vDZvNvbGPJqJ7eysrMTi+/dHjHBzc3ffvFmhUKlUKoRUKrVarT53Diakdevi47OyMjO73wsF7viMGRhrtVptQoKFxZgxY8b4+ra0XLp0+TJCpaV790ZEGN/Hnvhb6MGDurra2vXrc3MrKysqoqNJ0gaPx2az2ZWVMBxevgyjSlkZhFutraHpzZ4N6SKTJgkEDg4ODghJJBcvXryIUEXFRx9t2oSQTCaXy+UIBQVFRkZGrls3bVpYWFhY7/OGuv05XVvb1NTUNHFicXFtbU3NoUMKhVqtUk2eDD/iyLDY+X2MoXNaWg4aZGf34IG7u6urq2tYWE7O6tXvvhsQcPfusWPHjq1fb23t7e3tjZBUWl1dXY3QvHmHDh06tGHDhAmrV69e/cUXJhNgSFWVRNLY6OtbXS2RSCQTJqjVsEUI5GApldbWIpFIVFDg6enu7uGRlGRpyWKxWJ27msXFbdmyZcvBgykpUVFRUaGhYrG7u7s7Qm1tICQ4ODIyMnLTpokT165duzYyss9ty9xcv/7ZZ599duDAzp1CoVCIcVSUm5ubG8bkOCkpIiIiYseOgfazWxISwsPDw6Ojw8N5PB4P46iowYMHD8Z4506RSCTCODFx9+7du033m8xsgKO7du3cKRAIBBgfPOjj4+PTKeTKlbCwsLC9ewfaz25JSTl06NCh8PDwcD6fz8d49247Ozs7jD/5hM1mszHOyzt79uzZ0FC5vKGhoWHIkKcuc/e550JDQ0P/7/+Cg/fv379/yxadDuYjS0sLCwsLhLhcoVAolEoRYrPZbKVyoP19IgpFa2trq739jz+GhISEnDhx8uTixYsXHz/e0dHc3NxsazvQ/lEoFAqFQqFQKBQKhUKhUChG0U2ERiBob1cqFYp9+ySStjapdP58iGa2tdnbW1uLxTt3jhzp5ubhcfbsUyMgL6+qqqIiKKisrKGhvv7YMUg5GDwY4jFlZbDlu7W1VouxTicUWltbWFhYXL7s7m5nZ2+/dKmHh4ODo2PP319gLI8e7hYV1dRUVQUGlpc3NDQ0XLum1ep0GJeWwtLDCRMglDRsGJvNZjPM4MEcDofD4Xz4YX19S0tz8yuv1NQ0NUkksbH9XgUymULR0WFvD2k29fUxMXfupKQkJvb0/Bs3cnKysvz8zp9PTU1OxhjygvovIMEUF9fV1dZu3QrRRUdHCws+n8/v+crsgAA/v2efzcnhcjkcLvf0aYlEKm1tXbPm/v3a2urqnu9q32cBLS3t7TLZsmWwGrW8fPZsf/+xY/PyelsQZLlcuaLVarUYI1Rd3dTU3Gz+Fd4MQgixWCT3zdLyt9+yszMze79NAkTibW2hHB5PKOTxeDzymngzCvDxcXZ2cgoP1+lg7wKVSqPRalev7m1BGHO5XO6qVba2Hh7u7ikpkyYNHTpsWHOzuQU84s6d4uKCgpiY06eTkxMTMYbOOWpUd+fFxxcW5udv356QUF9fW4txeXlZWWlp3zOwesujplJd3dTU2CgQlJXV1zc0nD/f1NTeLpUGB8OmL6dPw7B57RpE4p2ctFoej8t99VWRaNAgOztf39zc5ctXrECIzy8vLy8/dWrSpC1btmxZvtzff+XKlSt7/kqM3vJoHhg8eNAge3uFYtq0kSNHjXrhBVdXW1s7ux07RCI+n8+fOBEmtM8/hy3KQ0OHDHnmGR+fqioXl4cPJZIXX9Tp0tLS0lJSiopKSkpKli0rKrp69erVc+dyck6dOnWq/9faP0ZiYl5ebq6bW2pqQUF+/uM7OV27tm5daKit7YkTISEhIUlJkEiD8fHjwcHBwcnJKSkHDx482PfUsn7jzp2vvvrqKzu7b78NCAgIyMjYtIkImT179uz4+Nu3o6Ojo21sBtrPbklOjoyMjLS0PH48KCgoKC5u/XoQcvTojBkzZmRkyGR1dXV1gwcbex2z7dExdWpYWFhYe3tVVWpqaurChTKZVCqVPniAsUaj0bi58flisVjc92Q/swsguLlNnjx5skx26dKqVatW/eMfarVGo9HodAzD5/P5Eom5r0+hUCgUCoVCoVAoFAqFQqH8b3PsWHFxauqLLx49mp+fmLho0UD702Nyc1ta6urc3RHas2fBAowR2rkzOBjjTz+9e/fCBeO3ZzDbKiaZTKNRqRgmIOD06e3bb95EiMuFMIdGo1Ih9N13hYXJyatWPbUCnn/+3Lndu2NjHz5sbKyoGDKEOO7q6uHh51dRkZPzl7989tnkyU+dgDfeiI//+9+/+CI1tbDw1q05cxDi80UihBiGz7ew0Gji4195ZevW558Xi/l8oRD2yX8q2LUrMzM29r33EAoPDwrCGKEvvnjtNYwR2rVrwQKMY2OrqwsKnn/ebA6MHn3y5JYtiYlTppw6tW1bz9e4x8RUVOTkzJpFNpFH6MABcBw6a3R0Ts5vv61dazbH58y5dGn//h9+QGjr1mnTOi88evQPP3z88Y0bdXUKhUz2eJQxL6+lpa7OzQ2h6OhXX1WpEIqOXroUY4R27JgzB+OVKxMSjh//6iuzOf4HzPTpzs5Dh2ZmImRt7eSEEEIikViMUHZ2dXVBwaxZfn7ffbd+fV7egwetrQ0NnUsAAwLOnAkPv3ULIY1GqeRyEZLL29oQmjnTzy8wMD7+229nzVqxYs0acwt4FOi+cqWqKi8vIGDRonPndu+OiZHLOzqkUisr8ioKe3t7e0/PsjIPDyurQYNKS9PTy8uzsgIDEVKrlUqEXF3t7T08KisfPHjrrQMHvLwEAjabwyFv6e4HAYQHD6RSicTNbc6cM2d27IiLKympqSksHD4cISsre3uEEMIY3IL9JxBiGDZbpyspefvtI0e8vJ55xsrKzq6iwtyOEx4bRr29razs7KqqcnLefHP//tGj584dOXLmzMuXEWptra8HAbDDgVqtUCD0669Llnz66dy5/e14r3nrrbi4o0ePHkXo44/HjcN4796srGvXNmwYaL96TVxcZWVu7owZA+3Hfw3/D73/bnBl1mLvAAAAAElFTkSuQmCC);
+ background-repeat: no-repeat;
+ background-color: transparent;
+}
+
+@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
+ .jsgrid .jsgrid-button {
+ background-image: url(data:image/png;base64,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);
+ background-size: 24px 352px;
+ }
+}
+
+.jsgrid .jsgrid-mode-button {
+ width: 24px;
+ height: 24px;
+}
+
+.jsgrid-mode-on-button {
+ opacity: .5;
+}
+
+.jsgrid-cancel-edit-button { background-position: 0 0; width: 16px; height: 16px; }
+.jsgrid-clear-filter-button { background-position: 0 -40px; width: 16px; height: 16px; }
+.jsgrid-delete-button { background-position: 0 -80px; width: 16px; height: 16px; }
+.jsgrid-edit-button { background-position: 0 -120px; width: 16px; height: 16px; }
+.jsgrid-insert-mode-button { background-position: 0 -160px; width: 24px; height: 24px; }
+.jsgrid-insert-button { background-position: 0 -208px; width: 16px; height: 16px; }
+.jsgrid-search-mode-button { background-position: 0 -248px; width: 24px; height: 24px; }
+.jsgrid-search-button { background-position: 0 -296px; width: 16px; height: 16px; }
+.jsgrid-update-button { background-position: 0 -336px; width: 16px; height: 16px; }
+
+
+.jsgrid-load-shader {
+ background: #ddd;
+ opacity: .5;
+ filter: alpha(opacity=50);
+}
+
+.jsgrid-load-panel {
+ width: 15em;
+ height: 5em;
+ background: #fff;
+ border: 1px solid #e9e9e9;
+ padding-top: 3em;
+ text-align: center;
+}
+
+.jsgrid-load-panel:before {
+ content: ' ';
+ position: absolute;
+ top: .5em;
+ left: 50%;
+ margin-left: -1em;
+ width: 2em;
+ height: 2em;
+ border: 2px solid #009a67;
+ border-right-color: transparent;
+ border-radius: 50%;
+ -webkit-animation: indicator 1s linear infinite;
+ animation: indicator 1s linear infinite;
+}
+
+@-webkit-keyframes indicator
+{
+ from { -webkit-transform: rotate(0deg); }
+ 50% { -webkit-transform: rotate(180deg); }
+ to { -webkit-transform: rotate(360deg); }
+}
+
+@keyframes indicator
+{
+ from { transform: rotate(0deg); }
+ 50% { transform: rotate(180deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* old IE */
+.jsgrid-load-panel {
+ padding-top: 1.5em\9;
+}
+.jsgrid-load-panel:before {
+ display: none\9;
+}
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid-theme.min.css b/build/resources/main/static/plugins/jsgrid/jsgrid-theme.min.css
new file mode 100644
index 0000000..f369d7e
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid-theme.min.css
@@ -0,0 +1,7 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+.jsgrid-edit-row>.jsgrid-cell,.jsgrid-filter-row>.jsgrid-cell,.jsgrid-grid-body,.jsgrid-grid-header,.jsgrid-header-row>.jsgrid-header-cell,.jsgrid-insert-row>.jsgrid-cell{border:1px solid #e9e9e9}.jsgrid-header-row>.jsgrid-header-cell{border-top:0}.jsgrid-filter-row>.jsgrid-cell,.jsgrid-header-row>.jsgrid-header-cell,.jsgrid-insert-row>.jsgrid-cell{border-bottom:0}.jsgrid-filter-row>.jsgrid-cell:first-child,.jsgrid-header-row>.jsgrid-header-cell:first-child,.jsgrid-insert-row>.jsgrid-cell:first-child{border-left:none}.jsgrid-filter-row>.jsgrid-cell:last-child,.jsgrid-header-row>.jsgrid-header-cell:last-child,.jsgrid-insert-row>.jsgrid-cell:last-child{border-right:none}.jsgrid-header-row .jsgrid-align-left,.jsgrid-header-row .jsgrid-align-right{text-align:center}.jsgrid-grid-header{background:#f9f9f9}.jsgrid-header-scrollbar{scrollbar-arrow-color:#f1f1f1;scrollbar-base-color:#f1f1f1;scrollbar-3dlight-color:#f1f1f1;scrollbar-highlight-color:#f1f1f1;scrollbar-track-color:#f1f1f1;scrollbar-shadow-color:#f1f1f1;scrollbar-dark-shadow-color:#f1f1f1}.jsgrid-header-scrollbar::-webkit-scrollbar{visibility:hidden}.jsgrid-header-scrollbar::-webkit-scrollbar-track{background:#f1f1f1}.jsgrid-header-sortable:hover{cursor:pointer;background:#fcfcfc}.jsgrid-header-row .jsgrid-header-sort{background:#c4e2ff}.jsgrid-header-sort:before{content:" ";display:block;float:left;width:0;height:0;border-style:solid}.jsgrid-header-sort-asc:before{border-width:0 5px 5px;border-color:transparent transparent #009a67}.jsgrid-header-sort-desc:before{border-width:5px 5px 0;border-color:#009a67 transparent transparent}.jsgrid-grid-body{border-top:none}.jsgrid-cell{border:1px solid #f3f3f3}.jsgrid-grid-body .jsgrid-alt-row:first-child .jsgrid-cell,.jsgrid-grid-body .jsgrid-row:first-child .jsgrid-cell{border-top:none}.jsgrid-grid-body .jsgrid-cell:first-child{border-left:none}.jsgrid-grid-body .jsgrid-cell:last-child{border-right:none}.jsgrid-row>.jsgrid-cell{background:#fff}.jsgrid-alt-row>.jsgrid-cell{background:#fcfcfc}.jsgrid-header-row>.jsgrid-header-cell{background:#f9f9f9}.jsgrid-filter-row>.jsgrid-cell{background:#fcfcfc}.jsgrid-insert-row>.jsgrid-cell{background:#e3ffe5}.jsgrid-edit-row>.jsgrid-cell{background:#fdffe3}.jsgrid-selected-row>.jsgrid-cell{background:#c4e2ff;border-color:#c4e2ff}.jsgrid-nodata-row>.jsgrid-cell{background:#fff}.jsgrid-invalid input,.jsgrid-invalid select,.jsgrid-invalid textarea{background:#ffe3e5;border:1px solid #ff808a}.jsgrid-pager-current-page{font-weight:700}.jsgrid-pager-nav-inactive-button a{color:#d3d3d3}.jsgrid-button+.jsgrid-button{margin-left:5px}.jsgrid-button:hover{opacity:.5;transition:opacity 200ms linear}.jsgrid .jsgrid-button{width:16px;height:16px;border:none;cursor:pointer;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAFgEAYAAADx4WWjAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAZjElEQVR42u2deVyU1f7HzzyzDzCA7MgihCsY7uYOiZIamebVFl/Wy8zSxLTQuld/lmIuCGIu9cruLa9lXlNTUQsVUgQRNBbZF5F9lWEbZpj9/P74doQZ87LMDHjvPe9/vj7MPOf5fp6zjc/3e86D0H8rNTVRUd988/rrxpZTV3f48PHjixb1m+N5eVOmvP76hQtXryKEEMYVFWFhERG7dvW2nIKC4OBVq/71L1JOWdk774SHb9tmcoc1mpaWtjYLi6Ki+fPff/+f/7x2DS6YlobQpEkYJyQgxOViXFGxYUNExN693ZVXWDh//urV339/8yZCQiGUM3EixqTcqqq//e3gwQ8+MJkAnU6tVqvZbKk0KSkj47nnfv/d2nrcOInk1i2EHBw6HSBCyss3btyz53Eh4PiJEwkJCAkEGKenIzRlCsaJiQhZW2OcmentHRhYUCCX5+Tcv+/nZ/KaIKjVlZUSibPz3bu2tv7+jY1JSQjZ22P8++8ITZiA8c2bCIlEGNfU7Njx9dcbN5aXv/fe55/v2kXueFfHrawwzsjw8po1Kz9fp5PJVCoOx9T+sp4spLq6qcnJKTPTzy8wMDtbpWpurqlxcBAIEPL2RkihQKi8HCEWCyEOByGBACEPD4RkMoSysxGyshoxYtKkvLxnn83IiI3192cYoZDL1WjMduefhEbT2Njebm2dnT1x4sKFt26lpCDk7Q01Mm5cp719GyEPD4zz8+fNe/PNixcx1moxZhhz+9ftBTgce3tLy9ZWodDT08enqEirRUguh89YrE6r1SLU3o6QWDx27HPP3bjBYrHZLJZO1+933JDCwnnzVq8+eZJ0xvR0hKZNwzg5GSF3d4xJjXRt+2IxxpWVYWFRUX/964A5npc3e/aKFT/+aNg5k5IQsrPDOC9v/PjXX09Nzcpyc3vhhbKy5GSEXFygSY0fD6MWj4dxRcWmTZGRW7b0m+P5+dOnr1jx00+Gw+HNmwhZWmKcmTliRFBQdjb5vlrd1NTSYm2dmsrnDx0qlycnI+TsrC9EIMC4ouKDDyIitm41ucNqtUTS3GxlVVQ0f/66dZ0TWUYGQjNmQJPo6rhOp1RqtWy2YTkKRUFBVdXQoampPN7QoR0dt26BkPR0hCZPxpjMyDCRbdxoMgE6nUqlVnO5UmlSUmbmtGl374rFY8c2NcXFwQXv3RsxIigoKwtjpVKr7X5UUSgKCiorfXxSU0Wi4cOl0vh4KCcz08srMPD+fbk8O7u4+NlnTV4ThI6OrKzS0qFDc3JCQpYuPX1ap+vo0Ggev+PdIZPduVNY6O+flRUUFBLyyy9arVSqUAiFZnPcEI2mrq611cbG2HJUqrKyhgZX135znEKhUCgUCoVCoVAoFAqFQvlP4FGIyd//wIGYGPL0eOFCsOSRooWF/jHG3RT7R7kkwNHeDpY8W7106d69DRteesn4p9UGQbdZs8BOmAD26FGwajVYS8veFd/RAZbExtatA6tUgjW5gFdfBXv4MFhnZ7hTpEZ6D9TsiRNwFBsL9u23jXWc8FiUEi5IwqFlZWBLSkAIqaGeOn7uHBzNnAl2yBAoRyo1lYDHnvfDBUiV+/qCfeYZcOjs2Z45/s03cBQQAHbUKFM7TmB19wVwyNMTjlJSwCYlgW1tBUtqjM8HGxwMdsYMcDw319SOE7qNuIAD5eVwtGwZ2CVLwFpbgyU1RvrQypXmdrzHAvQhTaCoCOzy5eDoqlVwnJEBtqnJ3I73UQAJEQkEYG1t9T8nf++/UJKRqQBsNvSR3sfQBkiASPTHaX+cV1sLTUirhWNWt4PCAAuorQU7aBDYpUv1P5fJwJo+rcZoAfqjyvvvgz18GJpQXh4cjxkD1vTjvdEC9IUcOwZHZDglwyyEtREqLu4vARQKhUKhUCgUCoVCoVAoFMp/JL1+GAuLe0isbM8esCScum/fhAkIpaWdP9/vAsCxyEg4mjsX7MOHYA2XEE6ZAtbKSv/vJBx786b+eVwuWEdHsHFxINT4xUAGT5G9vMA6O4NtbgZrbw+WPJVOTARLHrMTS+LC48aBbWsD29gI1sFB/zrGYyCAhIpIXJgE927fBktCSCtXgv31V/07v3gx2DVrwA4dCjYwEOzp02DPnDGTAJJSQCLq48eDhdVlCB05Apa0fdKESFxg506wOTlgSVDwtdfAkiaZkAC2vt5YAQaP10kA4949/b8/KcWARGQMAxrk76TJEFJTwVZWGuv4YwKgU5FQEYn/EkjwjrRxQwyTP8ioRM4j1NTAdQzLN4EAfVpa9I9JDSgUYEmb77ogtyvkcxL4Jpg+cvMEASTiQiBtndQQEWIogNQE+Zz0KYLp48dPEFBSon9MhlUS/yXDIhk+iQDSxFQqsGKxfjkkQG52AWT8N1yRTZYmks8N5wHSREjc2MlJ/3zTdd5uBJBF54Zt1s4OLJmgyJ0nAkjNkBwKMgOTpkfOM7sAMkoYdmYyqvzZqvquDhKhBJJy9qRRzIQCYJgjna2qSv9TMk+QpkCakkSi/33iMIFMWGQiMx3dRNQNL0gi825uYEeNAks6rYsL2Dfe0D+PjP9kxu43Afn5YOfNAxsSApYMk6SzkiZE/u7tDZb8GjWc2SkUCoVCoVAoFAqFQqFQKBTjMNuiHViaMmQIHJFNgqOjYQVIRcVTKwAcJ2swydJFEuEhi0sDAvRXCPYdk20pC46TQAiJIxgG/0iN/PILfN/DY8AF6C8WTU8Hu3YtWPIQ2HBNJXko/MMPxl6/z+u9wHGSOhATA5Y8nSZbnhcWgiXLch88AEtibl9/bayAXvcBcHzwYDgiKQfdpQ6Q9cW//AKWy4U+QCL3/SAAHCc5EyRyTxa+9RQfH3DcMIjYd7ptQvqdjaQIkM7YHSQ2tmSJqR3vVgA4TqKMpI331HHCokXg+MWLpnb8iQL0R5UbN/rm+MKF5nacYLAxBgkVVVeDJaNKT1m8GBwnuxmYH7b+cEi21ScB7qlT//3ppI2TO06aWv/xx0Tm7g72wgWwZCOLjz7689NITgS545cu9bfjBI6+Q6TTkt8wpEZIqtknn4B95ZWBuuOG/FEDZC8VAo8HliRnkJ8IU6eC46SmBp4/aoC0ebKnyq1bYElKQWEhOE5+GlAoFAqFQqFQKBQKhUKhUCgDi8nCrKdOFRffuTN+/LJlMTEREdevIyQUkuAqPPPu6JBKEbp6ddmy7dtDQubOdXPz9SUBk75jsk0dWSwWi8Xi8xFiGDbbygpsVwFwzGIhxGIZLpB7CgQAGg1CGMOjYmIJXY/JmhvjMfu7U80NFTDQUAEEnc6w0/6HCfDyEovt7auru442+oJ0Oq0WITc3CwtbW7Kk0Xg4P/10//6dO7D4n8Uiq097/mJkPp/N5nC02t9+q6rKzx89GiGBgIzyMP6zWGB5PKEQoZMni4tTUwMCLl4sLc3MFAg6OrRatbrn2z5DTTMMl8swDKNUshCKilqyBOPOiae3TYE4yGZDdpBAALkoGOvfBhYLFu12dMCaV6iR3l+PnMflCgQdHRyY8lUqEMDj9b5A8m0ixNDxzu/B36EmOq/T272qQQCbzeUKhUolB4oATX3b9rr3Z5Gm1Sm99+fDOVotB35kCYXGNyFyvlBImhD5BrnT0IRUKlhtbFwT0mi0Wo1m0CDWtWuVlbm5s2aBI2TRf8/fJ8/lMgybrVbn5zc319b6+a1Zc/36t98ePtzZJ4jjSqVcjlBExKxZK1Zs3jxpkqOjl9edO2q1TqfVksGjezDGGGMOh81msRhGJuPMmePuboqftZmZjY3l5QUFCKlUCsXhw11HI7jDarVKhVBIiKenv39MzMiRtrYuLsbHnU02D+TmNjXV1np6du2c+m2bYRgGoaoqmay5meRmGI/JBEBT+jPHzQv9LTTQUAEDjcn+Tww/srjczgmKWDJrwjHGCGFM8pGeIgHw61Au5/G4XIGgoYFhuFyBoPPXjk6n0ajVLBZMQP33hggKhUKhUCgUCoVCoVAoFAoFIYTQhx8mJHz//dq1CO3b9/LLLS0IRUQsXNjSsm3b7ds//fThh/3tT6+fzEFekK0t/Ivsbkw+M9ws2Pz04eEuxhgrlX+eF0S2rH2qBTxd9FrAk5I6GKZ/Q0uEXvcBFxdLSxuburquj9ExRsjBgc+3sGho6HcBH32UkHD8eGgoxHOFQmjThlkOGNvYCARCYXt7XFx1dUHBCy8gJBTC1vBQH2fPlpZmZISE7NiRknLmDIvV2qpSKRQWFlBeZ91AnJdhWCyGYRiZLCpq5szly8mbJXoPC6F9+xYuxBghFotE6v8810Gng78LBJBOKRLpj0FyOWx4rlBAJB7Cqo9DymcYCG+HhZ092/fGx3k8v+dJof/HR50/vyxxsOt9//flGANn27bp05cv37wZxnUSWyepBp0vRrCzEwgsLEgTCgq6eLGkJC1twQIiPDjY03PMmCtX5s718Bg16sqVtjalsqNDJAInSV3AkU7H4bBYLBab3d6+fTtCP/9svJAeExWVlnbx4vLlCO3Z8+KLGCO0e/eCBRgfOZKRERv77rv96ArUQG9PKC9va5NInJ07kzmgKdTXKxRSKdmfov/o9TzA4zFM/72F3gwCIEw60G530ut7CeO4QNB1tOkcVQzfO/MUCmCzGYbNbmyEcby1lQhgGIZhsfp/JqZQKBQKhUKhUCgUCoVCofxv0uPAQmNjW1tbm5NTfX1ra3Pzyy9LJFKpVDp9Oiy/cnXV6XQ6na69ncfj8bjcjAw7O0tLK6vz5729nZ1dXDIzzSWg2ydzKSlFRfn5lpbNzTKZVLpwYUtLe3t7+xtvqFQajUYzdqxWi5BOZ2mJMUTN1GqdTqcjb0cXiUpL6+vr6trbvbycnJyd79/vtxqorJRIHj4cOTI7u7y8rOz0aY1Gq9VqfX0h0I0Ql8tmczgPH8Kz0oICCIU4OkIUc/hwEIgQj8fhcDgajY+Pi4uLyzvvDBvm6urmduyYqQQ89nS6rq6lpalpzJi8vMrKioq4OHDI11ck4vEEghs3LCz4fIFgzhxwzNNz3rxx4yZMmDmTx+NyudyRIwUCHo/HGz5cLBaJRKIjR0AuhwM34rvvSkrq6mprN240Ww1cuZKenpaWmalUajQajb+/lZVQKBB8+WVg4OjR/v7vv9/bC1y/np19797LL0ON/PxzR4darVKxWFOnDh8+cuS0aY6O1tY2NsnJfa4BuVyhUCjc3cvLGxrq69evl8tVKqXS318k4vN5vOvX++o4Ac4/fx5q7IMPSHShpKS2trZ23z5ja4ApL29sbGgIDq6qamqSSF56ic2G8CjYnTuNvYC+kEOHBAIul8stK2tr6+iQy6dOLStraKir6+17DLoIaG6WyWSyoCCFQq1Wq6dO5XI5HA6npgbu0+3bphLw6IIMwzDMtWtk1WtDQ0tLS8vEiX0uD9anOzoyDEKdK7rJjt+mzz6BUaywkAReVSqtVqcj7+TogwCtVqfT6eRyksQBw6GDA3xsrnCevb3+XghqdZ8FQGdNT+dwGIZh8vNBkK8vCOnt+we6B2bsqVPBImRjIxKJRH2f4BgvLwcHJ6cLF5ydbW1tbGJjVSqtVqMhaTVhYaZyPD4+MzM9fc4cjQZjjGfOtLQUi8XikhJfXw+PIUN+/bXPAmxtraysrNLS7O3FYmvrL7+EO9/erlSq1Wp1aOj16zk5WVmQUtA3x+/dy8iwsdHptFqtNjqax3N0dHREaNiwIUO8vDZvNvbGPJqJ7eysrMTi+/dHjHBzc3ffvFmhUKlUKoRUKrVarT53Diakdevi47OyMjO73wsF7viMGRhrtVptQoKFxZgxY8b4+ra0XLp0+TJCpaV790ZEGN/Hnvhb6MGDurra2vXrc3MrKysqoqNJ0gaPx2az2ZWVMBxevgyjSlkZhFutraHpzZ4N6SKTJgkEDg4ODghJJBcvXryIUEXFRx9t2oSQTCaXy+UIBQVFRkZGrls3bVpYWFhY7/OGuv05XVvb1NTUNHFicXFtbU3NoUMKhVqtUk2eDD/iyLDY+X2MoXNaWg4aZGf34IG7u6urq2tYWE7O6tXvvhsQcPfusWPHjq1fb23t7e3tjZBUWl1dXY3QvHmHDh06tGHDhAmrV69e/cUXJhNgSFWVRNLY6OtbXS2RSCQTJqjVsEUI5GApldbWIpFIVFDg6enu7uGRlGRpyWKxWJ27msXFbdmyZcvBgykpUVFRUaGhYrG7u7s7Qm1tICQ4ODIyMnLTpokT165duzYyss9ty9xcv/7ZZ599duDAzp1CoVCIcVSUm5ubG8bkOCkpIiIiYseOgfazWxISwsPDw6Ojw8N5PB4P46iowYMHD8Z4506RSCTCODFx9+7du033m8xsgKO7du3cKRAIBBgfPOjj4+PTKeTKlbCwsLC9ewfaz25JSTl06NCh8PDwcD6fz8d49247Ozs7jD/5hM1mszHOyzt79uzZ0FC5vKGhoWHIkKcuc/e550JDQ0P/7/+Cg/fv379/yxadDuYjS0sLCwsLhLhcoVAolEoRYrPZbKVyoP19IgpFa2trq739jz+GhISEnDhx8uTixYsXHz/e0dHc3NxsazvQ/lEoFAqFQqFQKBQKhUKhUChG0U2ERiBob1cqFYp9+ySStjapdP58iGa2tdnbW1uLxTt3jhzp5ubhcfbsUyMgL6+qqqIiKKisrKGhvv7YMUg5GDwY4jFlZbDlu7W1VouxTicUWltbWFhYXL7s7m5nZ2+/dKmHh4ODo2PP319gLI8e7hYV1dRUVQUGlpc3NDQ0XLum1ep0GJeWwtLDCRMglDRsGJvNZjPM4MEcDofD4Xz4YX19S0tz8yuv1NQ0NUkksbH9XgUymULR0WFvD2k29fUxMXfupKQkJvb0/Bs3cnKysvz8zp9PTU1OxhjygvovIMEUF9fV1dZu3QrRRUdHCws+n8/v+crsgAA/v2efzcnhcjkcLvf0aYlEKm1tXbPm/v3a2urqnu9q32cBLS3t7TLZsmWwGrW8fPZsf/+xY/PyelsQZLlcuaLVarUYI1Rd3dTU3Gz+Fd4MQgixWCT3zdLyt9+yszMze79NAkTibW2hHB5PKOTxeDzymngzCvDxcXZ2cgoP1+lg7wKVSqPRalev7m1BGHO5XO6qVba2Hh7u7ikpkyYNHTpsWHOzuQU84s6d4uKCgpiY06eTkxMTMYbOOWpUd+fFxxcW5udv356QUF9fW4txeXlZWWlp3zOwesujplJd3dTU2CgQlJXV1zc0nD/f1NTeLpUGB8OmL6dPw7B57RpE4p2ctFoej8t99VWRaNAgOztf39zc5ctXrECIzy8vLy8/dWrSpC1btmxZvtzff+XKlSt7/kqM3vJoHhg8eNAge3uFYtq0kSNHjXrhBVdXW1s7ux07RCI+n8+fOBEmtM8/hy3KQ0OHDHnmGR+fqioXl4cPJZIXX9Tp0tLS0lJSiopKSkpKli0rKrp69erVc+dyck6dOnWq/9faP0ZiYl5ebq6bW2pqQUF+/uM7OV27tm5daKit7YkTISEhIUlJkEiD8fHjwcHBwcnJKSkHDx482PfUsn7jzp2vvvrqKzu7b78NCAgIyMjYtIkImT179uz4+Nu3o6Ojo21sBtrPbklOjoyMjLS0PH48KCgoKC5u/XoQcvTojBkzZmRkyGR1dXV1gwcbex2z7dExdWpYWFhYe3tVVWpqaurChTKZVCqVPniAsUaj0bi58flisVjc92Q/swsguLlNnjx5skx26dKqVatW/eMfarVGo9HodAzD5/P5Eom5r0+hUCgUCoVCoVAoFAqFQqH8b3PsWHFxauqLLx49mp+fmLho0UD702Nyc1ta6urc3RHas2fBAowR2rkzOBjjTz+9e/fCBeO3ZzDbKiaZTKNRqRgmIOD06e3bb95EiMuFMIdGo1Ih9N13hYXJyatWPbUCnn/+3Lndu2NjHz5sbKyoGDKEOO7q6uHh51dRkZPzl7989tnkyU+dgDfeiI//+9+/+CI1tbDw1q05cxDi80UihBiGz7ew0Gji4195ZevW558Xi/l8oRD2yX8q2LUrMzM29r33EAoPDwrCGKEvvnjtNYwR2rVrwQKMY2OrqwsKnn/ebA6MHn3y5JYtiYlTppw6tW1bz9e4x8RUVOTkzJpFNpFH6MABcBw6a3R0Ts5vv61dazbH58y5dGn//h9+QGjr1mnTOi88evQPP3z88Y0bdXUKhUz2eJQxL6+lpa7OzQ2h6OhXX1WpEIqOXroUY4R27JgzB+OVKxMSjh//6iuzOf4HzPTpzs5Dh2ZmImRt7eSEEEIikViMUHZ2dXVBwaxZfn7ffbd+fV7egwetrQ0NnUsAAwLOnAkPv3ULIY1GqeRyEZLL29oQmjnTzy8wMD7+229nzVqxYs0acwt4FOi+cqWqKi8vIGDRonPndu+OiZHLOzqkUisr8ioKe3t7e0/PsjIPDyurQYNKS9PTy8uzsgIDEVKrlUqEXF3t7T08KisfPHjrrQMHvLwEAjabwyFv6e4HAYQHD6RSicTNbc6cM2d27IiLKympqSksHD4cISsre3uEEMIY3IL9JxBiGDZbpyspefvtI0e8vJ55xsrKzq6iwtyOEx4bRr29razs7KqqcnLefHP//tGj584dOXLmzMuXEWptra8HAbDDgVqtUCD0669Llnz66dy5/e14r3nrrbi4o0ePHkXo44/HjcN4796srGvXNmwYaL96TVxcZWVu7owZA+3Hfw3/D73/bnBl1mLvAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-color:transparent}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){.jsgrid .jsgrid-button{background-image:url(data:image/png;base64,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);background-size:24px 352px}}.jsgrid .jsgrid-mode-button{width:24px;height:24px}.jsgrid-mode-on-button{opacity:.5}.jsgrid-cancel-edit-button{background-position:0 0;width:16px;height:16px}.jsgrid-clear-filter-button{background-position:0 -40px;width:16px;height:16px}.jsgrid-delete-button{background-position:0 -80px;width:16px;height:16px}.jsgrid-edit-button{background-position:0 -120px;width:16px;height:16px}.jsgrid-insert-mode-button{background-position:0 -160px;width:24px;height:24px}.jsgrid-insert-button{background-position:0 -208px;width:16px;height:16px}.jsgrid-search-mode-button{background-position:0 -248px;width:24px;height:24px}.jsgrid-search-button{background-position:0 -296px;width:16px;height:16px}.jsgrid-update-button{background-position:0 -336px;width:16px;height:16px}.jsgrid-load-shader{background:#ddd;opacity:.5;filter:alpha(opacity=50)}.jsgrid-load-panel{width:15em;height:5em;background:#fff;border:1px solid #e9e9e9;padding-top:3em;text-align:center}.jsgrid-load-panel:before{content:' ';position:absolute;top:.5em;left:50%;margin-left:-1em;width:2em;height:2em;border:2px solid #009a67;border-right-color:transparent;border-radius:50%;-webkit-animation:indicator 1s linear infinite;animation:indicator 1s linear infinite}@-webkit-keyframes indicator{from{-webkit-transform:rotate(0deg)}50%{-webkit-transform:rotate(180deg)}to{-webkit-transform:rotate(360deg)}}@keyframes indicator{from{transform:rotate(0deg)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}} \ No newline at end of file
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid.css b/build/resources/main/static/plugins/jsgrid/jsgrid.css
new file mode 100644
index 0000000..a59154f
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid.css
@@ -0,0 +1,126 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+.jsgrid {
+ position: relative;
+ overflow: hidden;
+ font-size: 1em;
+}
+
+.jsgrid, .jsgrid *, .jsgrid *:before, .jsgrid *:after {
+ box-sizing: border-box;
+}
+
+.jsgrid input,
+.jsgrid textarea,
+.jsgrid select {
+ font-size: 1em;
+}
+
+.jsgrid-grid-header {
+ overflow-x: hidden;
+ overflow-y: scroll;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+
+.jsgrid-grid-body {
+ overflow-x: auto;
+ overflow-y: scroll;
+ -webkit-overflow-scrolling: touch;
+}
+
+.jsgrid-table {
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.jsgrid-cell {
+ padding: 0.5em 0.5em;
+}
+
+.jsgrid-сell,
+.jsgrid-header-cell {
+ box-sizing: border-box;
+}
+
+.jsgrid-align-left {
+ text-align: left;
+}
+
+.jsgrid-align-center,
+.jsgrid-align-center input,
+.jsgrid-align-center textarea,
+.jsgrid-align-center select {
+ text-align: center;
+}
+
+.jsgrid-align-right,
+.jsgrid-align-right input,
+.jsgrid-align-right textarea,
+.jsgrid-align-right select {
+ text-align: right;
+}
+
+.jsgrid-header-cell {
+ padding: .5em .5em;
+}
+
+.jsgrid-filter-row input,
+.jsgrid-filter-row textarea,
+.jsgrid-filter-row select,
+.jsgrid-edit-row input,
+.jsgrid-edit-row textarea,
+.jsgrid-edit-row select,
+.jsgrid-insert-row input,
+.jsgrid-insert-row textarea,
+.jsgrid-insert-row select {
+ width: 100%;
+ padding: .3em .5em;
+}
+
+.jsgrid-filter-row input[type='checkbox'],
+.jsgrid-edit-row input[type='checkbox'],
+.jsgrid-insert-row input[type='checkbox'] {
+ width: auto;
+}
+
+
+.jsgrid-selected-row .jsgrid-cell {
+ cursor: pointer;
+}
+
+.jsgrid-nodata-row .jsgrid-cell {
+ padding: .5em 0;
+ text-align: center;
+}
+
+.jsgrid-header-sort {
+ cursor: pointer;
+}
+
+.jsgrid-pager {
+ padding: .5em 0;
+}
+
+.jsgrid-pager-nav-button {
+ padding: .2em .6em;
+}
+
+.jsgrid-pager-nav-inactive-button {
+ display: none;
+ pointer-events: none;
+}
+
+.jsgrid-pager-page {
+ padding: .2em .6em;
+}
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid.js b/build/resources/main/static/plugins/jsgrid/jsgrid.js
new file mode 100644
index 0000000..922bcdf
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid.js
@@ -0,0 +1,2516 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+(function(window, $, undefined) {
+
+ var JSGRID = "JSGrid",
+ JSGRID_DATA_KEY = JSGRID,
+ JSGRID_ROW_DATA_KEY = "JSGridItem",
+ JSGRID_EDIT_ROW_DATA_KEY = "JSGridEditRow",
+
+ SORT_ORDER_ASC = "asc",
+ SORT_ORDER_DESC = "desc",
+
+ FIRST_PAGE_PLACEHOLDER = "{first}",
+ PAGES_PLACEHOLDER = "{pages}",
+ PREV_PAGE_PLACEHOLDER = "{prev}",
+ NEXT_PAGE_PLACEHOLDER = "{next}",
+ LAST_PAGE_PLACEHOLDER = "{last}",
+ PAGE_INDEX_PLACEHOLDER = "{pageIndex}",
+ PAGE_COUNT_PLACEHOLDER = "{pageCount}",
+ ITEM_COUNT_PLACEHOLDER = "{itemCount}",
+
+ EMPTY_HREF = "javascript:void(0);";
+
+ var getOrApply = function(value, context) {
+ if($.isFunction(value)) {
+ return value.apply(context, $.makeArray(arguments).slice(2));
+ }
+ return value;
+ };
+
+ var normalizePromise = function(promise) {
+ var d = $.Deferred();
+
+ if(promise && promise.then) {
+ promise.then(function() {
+ d.resolve.apply(d, arguments);
+ }, function() {
+ d.reject.apply(d, arguments);
+ });
+ } else {
+ d.resolve(promise);
+ }
+
+ return d.promise();
+ };
+
+ var defaultController = {
+ loadData: $.noop,
+ insertItem: $.noop,
+ updateItem: $.noop,
+ deleteItem: $.noop
+ };
+
+
+ function Grid(element, config) {
+ var $element = $(element);
+
+ $element.data(JSGRID_DATA_KEY, this);
+
+ this._container = $element;
+
+ this.data = [];
+ this.fields = [];
+
+ this._editingRow = null;
+ this._sortField = null;
+ this._sortOrder = SORT_ORDER_ASC;
+ this._firstDisplayingPage = 1;
+
+ this._init(config);
+ this.render();
+ }
+
+ Grid.prototype = {
+ width: "auto",
+ height: "auto",
+ updateOnResize: true,
+
+ rowClass: $.noop,
+ rowRenderer: null,
+
+ rowClick: function(args) {
+ if(this.editing) {
+ this.editItem($(args.event.target).closest("tr"));
+ }
+ },
+ rowDoubleClick: $.noop,
+
+ noDataContent: "Not found",
+ noDataRowClass: "jsgrid-nodata-row",
+
+ heading: true,
+ headerRowRenderer: null,
+ headerRowClass: "jsgrid-header-row",
+ headerCellClass: "jsgrid-header-cell",
+
+ filtering: false,
+ filterRowRenderer: null,
+ filterRowClass: "jsgrid-filter-row",
+
+ inserting: false,
+ insertRowRenderer: null,
+ insertRowClass: "jsgrid-insert-row",
+
+ editing: false,
+ editRowRenderer: null,
+ editRowClass: "jsgrid-edit-row",
+
+ confirmDeleting: true,
+ deleteConfirm: "Are you sure?",
+
+ selecting: true,
+ selectedRowClass: "jsgrid-selected-row",
+ oddRowClass: "jsgrid-row",
+ evenRowClass: "jsgrid-alt-row",
+ cellClass: "jsgrid-cell",
+
+ sorting: false,
+ sortableClass: "jsgrid-header-sortable",
+ sortAscClass: "jsgrid-header-sort jsgrid-header-sort-asc",
+ sortDescClass: "jsgrid-header-sort jsgrid-header-sort-desc",
+
+ paging: false,
+ pagerContainer: null,
+ pageIndex: 1,
+ pageSize: 20,
+ pageButtonCount: 15,
+ pagerFormat: "Pages: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} of {pageCount}",
+ pagePrevText: "Prev",
+ pageNextText: "Next",
+ pageFirstText: "First",
+ pageLastText: "Last",
+ pageNavigatorNextText: "...",
+ pageNavigatorPrevText: "...",
+ pagerContainerClass: "jsgrid-pager-container",
+ pagerClass: "jsgrid-pager",
+ pagerNavButtonClass: "jsgrid-pager-nav-button",
+ pagerNavButtonInactiveClass: "jsgrid-pager-nav-inactive-button",
+ pageClass: "jsgrid-pager-page",
+ currentPageClass: "jsgrid-pager-current-page",
+
+ customLoading: false,
+ pageLoading: false,
+
+ autoload: false,
+ controller: defaultController,
+
+ loadIndication: true,
+ loadIndicationDelay: 500,
+ loadMessage: "Please, wait...",
+ loadShading: true,
+
+ invalidMessage: "Invalid data entered!",
+
+ invalidNotify: function(args) {
+ var messages = $.map(args.errors, function(error) {
+ return error.message || null;
+ });
+
+ window.alert([this.invalidMessage].concat(messages).join("\n"));
+ },
+
+ onInit: $.noop,
+ onRefreshing: $.noop,
+ onRefreshed: $.noop,
+ onPageChanged: $.noop,
+ onItemDeleting: $.noop,
+ onItemDeleted: $.noop,
+ onItemInserting: $.noop,
+ onItemInserted: $.noop,
+ onItemEditing: $.noop,
+ onItemUpdating: $.noop,
+ onItemUpdated: $.noop,
+ onItemInvalid: $.noop,
+ onDataLoading: $.noop,
+ onDataLoaded: $.noop,
+ onOptionChanging: $.noop,
+ onOptionChanged: $.noop,
+ onError: $.noop,
+
+ invalidClass: "jsgrid-invalid",
+
+ containerClass: "jsgrid",
+ tableClass: "jsgrid-table",
+ gridHeaderClass: "jsgrid-grid-header",
+ gridBodyClass: "jsgrid-grid-body",
+
+ _init: function(config) {
+ $.extend(this, config);
+ this._initLoadStrategy();
+ this._initController();
+ this._initFields();
+ this._attachWindowLoadResize();
+ this._attachWindowResizeCallback();
+ this._callEventHandler(this.onInit)
+ },
+
+ loadStrategy: function() {
+ return this.pageLoading
+ ? new jsGrid.loadStrategies.PageLoadingStrategy(this)
+ : new jsGrid.loadStrategies.DirectLoadingStrategy(this);
+ },
+
+ _initLoadStrategy: function() {
+ this._loadStrategy = getOrApply(this.loadStrategy, this);
+ },
+
+ _initController: function() {
+ this._controller = $.extend({}, defaultController, getOrApply(this.controller, this));
+ },
+
+ renderTemplate: function(source, context, config) {
+ args = [];
+ for(var key in config) {
+ args.push(config[key]);
+ }
+
+ args.unshift(source, context);
+
+ source = getOrApply.apply(null, args);
+ return (source === undefined || source === null) ? "" : source;
+ },
+
+ loadIndicator: function(config) {
+ return new jsGrid.LoadIndicator(config);
+ },
+
+ validation: function(config) {
+ return jsGrid.Validation && new jsGrid.Validation(config);
+ },
+
+ _initFields: function() {
+ var self = this;
+ self.fields = $.map(self.fields, function(field) {
+ if($.isPlainObject(field)) {
+ var fieldConstructor = (field.type && jsGrid.fields[field.type]) || jsGrid.Field;
+ field = new fieldConstructor(field);
+ }
+ field._grid = self;
+ return field;
+ });
+ },
+
+ _attachWindowLoadResize: function() {
+ $(window).on("load", $.proxy(this._refreshSize, this));
+ },
+
+ _attachWindowResizeCallback: function() {
+ if(this.updateOnResize) {
+ $(window).on("resize", $.proxy(this._refreshSize, this));
+ }
+ },
+
+ _detachWindowResizeCallback: function() {
+ $(window).off("resize", this._refreshSize);
+ },
+
+ option: function(key, value) {
+ var optionChangingEventArgs,
+ optionChangedEventArgs;
+
+ if(arguments.length === 1)
+ return this[key];
+
+ optionChangingEventArgs = {
+ option: key,
+ oldValue: this[key],
+ newValue: value
+ };
+ this._callEventHandler(this.onOptionChanging, optionChangingEventArgs);
+
+ this._handleOptionChange(optionChangingEventArgs.option, optionChangingEventArgs.newValue);
+
+ optionChangedEventArgs = {
+ option: optionChangingEventArgs.option,
+ value: optionChangingEventArgs.newValue
+ };
+ this._callEventHandler(this.onOptionChanged, optionChangedEventArgs);
+ },
+
+ fieldOption: function(field, key, value) {
+ field = this._normalizeField(field);
+
+ if(arguments.length === 2)
+ return field[key];
+
+ field[key] = value;
+ this._renderGrid();
+ },
+
+ _handleOptionChange: function(name, value) {
+ this[name] = value;
+
+ switch(name) {
+ case "width":
+ case "height":
+ this._refreshSize();
+ break;
+ case "rowClass":
+ case "rowRenderer":
+ case "rowClick":
+ case "rowDoubleClick":
+ case "noDataRowClass":
+ case "noDataContent":
+ case "selecting":
+ case "selectedRowClass":
+ case "oddRowClass":
+ case "evenRowClass":
+ this._refreshContent();
+ break;
+ case "pageButtonCount":
+ case "pagerFormat":
+ case "pagePrevText":
+ case "pageNextText":
+ case "pageFirstText":
+ case "pageLastText":
+ case "pageNavigatorNextText":
+ case "pageNavigatorPrevText":
+ case "pagerClass":
+ case "pagerNavButtonClass":
+ case "pageClass":
+ case "currentPageClass":
+ case "pagerRenderer":
+ this._refreshPager();
+ break;
+ case "fields":
+ this._initFields();
+ this.render();
+ break;
+ case "data":
+ case "editing":
+ case "heading":
+ case "filtering":
+ case "inserting":
+ case "paging":
+ this.refresh();
+ break;
+ case "loadStrategy":
+ case "pageLoading":
+ this._initLoadStrategy();
+ this.search();
+ break;
+ case "pageIndex":
+ this.openPage(value);
+ break;
+ case "pageSize":
+ this.refresh();
+ this.search();
+ break;
+ case "editRowRenderer":
+ case "editRowClass":
+ this.cancelEdit();
+ break;
+ case "updateOnResize":
+ this._detachWindowResizeCallback();
+ this._attachWindowResizeCallback();
+ break;
+ case "invalidNotify":
+ case "invalidMessage":
+ break;
+ default:
+ this.render();
+ break;
+ }
+ },
+
+ destroy: function() {
+ this._detachWindowResizeCallback();
+ this._clear();
+ this._container.removeData(JSGRID_DATA_KEY);
+ },
+
+ render: function() {
+ this._renderGrid();
+ return this.autoload ? this.loadData() : $.Deferred().resolve().promise();
+ },
+
+ _renderGrid: function() {
+ this._clear();
+
+ this._container.addClass(this.containerClass)
+ .css("position", "relative")
+ .append(this._createHeader())
+ .append(this._createBody());
+
+ this._pagerContainer = this._createPagerContainer();
+ this._loadIndicator = this._createLoadIndicator();
+ this._validation = this._createValidation();
+
+ this.refresh();
+ },
+
+ _createLoadIndicator: function() {
+ return getOrApply(this.loadIndicator, this, {
+ message: this.loadMessage,
+ shading: this.loadShading,
+ container: this._container
+ });
+ },
+
+ _createValidation: function() {
+ return getOrApply(this.validation, this);
+ },
+
+ _clear: function() {
+ this.cancelEdit();
+
+ clearTimeout(this._loadingTimer);
+
+ this._pagerContainer && this._pagerContainer.empty();
+
+ this._container.empty()
+ .css({ position: "", width: "", height: "" });
+ },
+
+ _createHeader: function() {
+ var $headerRow = this._headerRow = this._createHeaderRow(),
+ $filterRow = this._filterRow = this._createFilterRow(),
+ $insertRow = this._insertRow = this._createInsertRow();
+
+ var $headerGrid = this._headerGrid = $("<table>").addClass(this.tableClass)
+ .append($headerRow)
+ .append($filterRow)
+ .append($insertRow);
+
+ var $header = this._header = $("<div>").addClass(this.gridHeaderClass)
+ .addClass(this._scrollBarWidth() ? "jsgrid-header-scrollbar" : "")
+ .append($headerGrid);
+
+ return $header;
+ },
+
+ _createBody: function() {
+ var $content = this._content = $("<tbody>");
+
+ var $bodyGrid = this._bodyGrid = $("<table>").addClass(this.tableClass)
+ .append($content);
+
+ var $body = this._body = $("<div>").addClass(this.gridBodyClass)
+ .append($bodyGrid)
+ .on("scroll", $.proxy(function(e) {
+ this._header.scrollLeft(e.target.scrollLeft);
+ }, this));
+
+ return $body;
+ },
+
+ _createPagerContainer: function() {
+ var pagerContainer = this.pagerContainer || $("<div>").appendTo(this._container);
+ return $(pagerContainer).addClass(this.pagerContainerClass);
+ },
+
+ _eachField: function(callBack) {
+ var self = this;
+ $.each(this.fields, function(index, field) {
+ if(field.visible) {
+ callBack.call(self, field, index);
+ }
+ });
+ },
+
+ _createHeaderRow: function() {
+ if($.isFunction(this.headerRowRenderer))
+ return $(this.renderTemplate(this.headerRowRenderer, this));
+
+ var $result = $("<tr>").addClass(this.headerRowClass);
+
+ this._eachField(function(field, index) {
+ var $th = this._prepareCell("<th>", field, "headercss", this.headerCellClass)
+ .append(this.renderTemplate(field.headerTemplate, field))
+ .appendTo($result);
+
+ if(this.sorting && field.sorting) {
+ $th.addClass(this.sortableClass)
+ .on("click", $.proxy(function() {
+ this.sort(index);
+ }, this));
+ }
+ });
+
+ return $result;
+ },
+
+ _prepareCell: function(cell, field, cssprop, cellClass) {
+ return $(cell).css("width", field.width)
+ .addClass(cellClass || this.cellClass)
+ .addClass((cssprop && field[cssprop]) || field.css)
+ .addClass(field.align ? ("jsgrid-align-" + field.align) : "");
+ },
+
+ _createFilterRow: function() {
+ if($.isFunction(this.filterRowRenderer))
+ return $(this.renderTemplate(this.filterRowRenderer, this));
+
+ var $result = $("<tr>").addClass(this.filterRowClass);
+
+ this._eachField(function(field) {
+ this._prepareCell("<td>", field, "filtercss")
+ .append(this.renderTemplate(field.filterTemplate, field))
+ .appendTo($result);
+ });
+
+ return $result;
+ },
+
+ _createInsertRow: function() {
+ if($.isFunction(this.insertRowRenderer))
+ return $(this.renderTemplate(this.insertRowRenderer, this));
+
+ var $result = $("<tr>").addClass(this.insertRowClass);
+
+ this._eachField(function(field) {
+ this._prepareCell("<td>", field, "insertcss")
+ .append(this.renderTemplate(field.insertTemplate, field))
+ .appendTo($result);
+ });
+
+ return $result;
+ },
+
+ _callEventHandler: function(handler, eventParams) {
+ handler.call(this, $.extend(eventParams, {
+ grid: this
+ }));
+
+ return eventParams;
+ },
+
+ reset: function() {
+ this._resetSorting();
+ this._resetPager();
+ return this._loadStrategy.reset();
+ },
+
+ _resetPager: function() {
+ this._firstDisplayingPage = 1;
+ this._setPage(1);
+ },
+
+ _resetSorting: function() {
+ this._sortField = null;
+ this._sortOrder = SORT_ORDER_ASC;
+ this._clearSortingCss();
+ },
+
+ refresh: function() {
+ this._callEventHandler(this.onRefreshing);
+
+ this.cancelEdit();
+
+ this._refreshHeading();
+ this._refreshFiltering();
+ this._refreshInserting();
+ this._refreshContent();
+ this._refreshPager();
+ this._refreshSize();
+
+ this._callEventHandler(this.onRefreshed);
+ },
+
+ _refreshHeading: function() {
+ this._headerRow.toggle(this.heading);
+ },
+
+ _refreshFiltering: function() {
+ this._filterRow.toggle(this.filtering);
+ },
+
+ _refreshInserting: function() {
+ this._insertRow.toggle(this.inserting);
+ },
+
+ _refreshContent: function() {
+ var $content = this._content;
+ $content.empty();
+
+ if(!this.data.length) {
+ $content.append(this._createNoDataRow());
+ return this;
+ }
+
+ var indexFrom = this._loadStrategy.firstDisplayIndex();
+ var indexTo = this._loadStrategy.lastDisplayIndex();
+
+ for(var itemIndex = indexFrom; itemIndex < indexTo; itemIndex++) {
+ var item = this.data[itemIndex];
+ $content.append(this._createRow(item, itemIndex));
+ }
+ },
+
+ _createNoDataRow: function() {
+ var amountOfFields = 0;
+ this._eachField(function() {
+ amountOfFields++;
+ });
+
+ return $("<tr>").addClass(this.noDataRowClass)
+ .append($("<td>").addClass(this.cellClass).attr("colspan", amountOfFields)
+ .append(this.renderTemplate(this.noDataContent, this)));
+ },
+
+ _createRow: function(item, itemIndex) {
+ var $result;
+
+ if($.isFunction(this.rowRenderer)) {
+ $result = this.renderTemplate(this.rowRenderer, this, { item: item, itemIndex: itemIndex });
+ } else {
+ $result = $("<tr>");
+ this._renderCells($result, item);
+ }
+
+ $result.addClass(this._getRowClasses(item, itemIndex))
+ .data(JSGRID_ROW_DATA_KEY, item)
+ .on("click", $.proxy(function(e) {
+ this.rowClick({
+ item: item,
+ itemIndex: itemIndex,
+ event: e
+ });
+ }, this))
+ .on("dblclick", $.proxy(function(e) {
+ this.rowDoubleClick({
+ item: item,
+ itemIndex: itemIndex,
+ event: e
+ });
+ }, this));
+
+ if(this.selecting) {
+ this._attachRowHover($result);
+ }
+
+ return $result;
+ },
+
+ _getRowClasses: function(item, itemIndex) {
+ var classes = [];
+ classes.push(((itemIndex + 1) % 2) ? this.oddRowClass : this.evenRowClass);
+ classes.push(getOrApply(this.rowClass, this, item, itemIndex));
+ return classes.join(" ");
+ },
+
+ _attachRowHover: function($row) {
+ var selectedRowClass = this.selectedRowClass;
+ $row.hover(function() {
+ $(this).addClass(selectedRowClass);
+ },
+ function() {
+ $(this).removeClass(selectedRowClass);
+ }
+ );
+ },
+
+ _renderCells: function($row, item) {
+ this._eachField(function(field) {
+ $row.append(this._createCell(item, field));
+ });
+ return this;
+ },
+
+ _createCell: function(item, field) {
+ var $result;
+ var fieldValue = this._getItemFieldValue(item, field);
+
+ var args = { value: fieldValue, item : item };
+ if($.isFunction(field.cellRenderer)) {
+ $result = this.renderTemplate(field.cellRenderer, field, args);
+ } else {
+ $result = $("<td>").append(this.renderTemplate(field.itemTemplate || fieldValue, field, args));
+ }
+
+ return this._prepareCell($result, field);
+ },
+
+ _getItemFieldValue: function(item, field) {
+ var props = field.name.split('.');
+ var result = item[props.shift()];
+
+ while(result && props.length) {
+ result = result[props.shift()];
+ }
+
+ return result;
+ },
+
+ _setItemFieldValue: function(item, field, value) {
+ var props = field.name.split('.');
+ var current = item;
+ var prop = props[0];
+
+ while(current && props.length) {
+ item = current;
+ prop = props.shift();
+ current = item[prop];
+ }
+
+ if(!current) {
+ while(props.length) {
+ item = item[prop] = {};
+ prop = props.shift();
+ }
+ }
+
+ item[prop] = value;
+ },
+
+ sort: function(field, order) {
+ if($.isPlainObject(field)) {
+ order = field.order;
+ field = field.field;
+ }
+
+ this._clearSortingCss();
+ this._setSortingParams(field, order);
+ this._setSortingCss();
+ return this._loadStrategy.sort();
+ },
+
+ _clearSortingCss: function() {
+ this._headerRow.find("th")
+ .removeClass(this.sortAscClass)
+ .removeClass(this.sortDescClass);
+ },
+
+ _setSortingParams: function(field, order) {
+ field = this._normalizeField(field);
+ order = order || ((this._sortField === field) ? this._reversedSortOrder(this._sortOrder) : SORT_ORDER_ASC);
+
+ this._sortField = field;
+ this._sortOrder = order;
+ },
+
+ _normalizeField: function(field) {
+ if($.isNumeric(field)) {
+ return this.fields[field];
+ }
+
+ if(typeof field === "string") {
+ return $.grep(this.fields, function(f) {
+ return f.name === field;
+ })[0];
+ }
+
+ return field;
+ },
+
+ _reversedSortOrder: function(order) {
+ return (order === SORT_ORDER_ASC ? SORT_ORDER_DESC : SORT_ORDER_ASC);
+ },
+
+ _setSortingCss: function() {
+ var fieldIndex = this._visibleFieldIndex(this._sortField);
+
+ this._headerRow.find("th").eq(fieldIndex)
+ .addClass(this._sortOrder === SORT_ORDER_ASC ? this.sortAscClass : this.sortDescClass);
+ },
+
+ _visibleFieldIndex: function(field) {
+ return $.inArray(field, $.grep(this.fields, function(f) { return f.visible; }));
+ },
+
+ _sortData: function() {
+ var sortFactor = this._sortFactor(),
+ sortField = this._sortField;
+
+ if(sortField) {
+ this.data.sort(function(item1, item2) {
+ return sortFactor * sortField.sortingFunc(item1[sortField.name], item2[sortField.name]);
+ });
+ }
+ },
+
+ _sortFactor: function() {
+ return this._sortOrder === SORT_ORDER_ASC ? 1 : -1;
+ },
+
+ _itemsCount: function() {
+ return this._loadStrategy.itemsCount();
+ },
+
+ _pagesCount: function() {
+ var itemsCount = this._itemsCount(),
+ pageSize = this.pageSize;
+ return Math.floor(itemsCount / pageSize) + (itemsCount % pageSize ? 1 : 0);
+ },
+
+ _refreshPager: function() {
+ var $pagerContainer = this._pagerContainer;
+ $pagerContainer.empty();
+
+ if(this.paging) {
+ $pagerContainer.append(this._createPager());
+ }
+
+ var showPager = this.paging && this._pagesCount() > 1;
+ $pagerContainer.toggle(showPager);
+ },
+
+ _createPager: function() {
+ var $result;
+
+ if($.isFunction(this.pagerRenderer)) {
+ $result = $(this.pagerRenderer({
+ pageIndex: this.pageIndex,
+ pageCount: this._pagesCount()
+ }));
+ } else {
+ $result = $("<div>").append(this._createPagerByFormat());
+ }
+
+ $result.addClass(this.pagerClass);
+
+ return $result;
+ },
+
+ _createPagerByFormat: function() {
+ var pageIndex = this.pageIndex,
+ pageCount = this._pagesCount(),
+ itemCount = this._itemsCount(),
+ pagerParts = this.pagerFormat.split(" ");
+
+ return $.map(pagerParts, $.proxy(function(pagerPart) {
+ var result = pagerPart;
+
+ if(pagerPart === PAGES_PLACEHOLDER) {
+ result = this._createPages();
+ } else if(pagerPart === FIRST_PAGE_PLACEHOLDER) {
+ result = this._createPagerNavButton(this.pageFirstText, 1, pageIndex > 1);
+ } else if(pagerPart === PREV_PAGE_PLACEHOLDER) {
+ result = this._createPagerNavButton(this.pagePrevText, pageIndex - 1, pageIndex > 1);
+ } else if(pagerPart === NEXT_PAGE_PLACEHOLDER) {
+ result = this._createPagerNavButton(this.pageNextText, pageIndex + 1, pageIndex < pageCount);
+ } else if(pagerPart === LAST_PAGE_PLACEHOLDER) {
+ result = this._createPagerNavButton(this.pageLastText, pageCount, pageIndex < pageCount);
+ } else if(pagerPart === PAGE_INDEX_PLACEHOLDER) {
+ result = pageIndex;
+ } else if(pagerPart === PAGE_COUNT_PLACEHOLDER) {
+ result = pageCount;
+ } else if(pagerPart === ITEM_COUNT_PLACEHOLDER) {
+ result = itemCount;
+ }
+
+ return $.isArray(result) ? result.concat([" "]) : [result, " "];
+ }, this));
+ },
+
+ _createPages: function() {
+ var pageCount = this._pagesCount(),
+ pageButtonCount = this.pageButtonCount,
+ firstDisplayingPage = this._firstDisplayingPage,
+ pages = [];
+
+ if(firstDisplayingPage > 1) {
+ pages.push(this._createPagerPageNavButton(this.pageNavigatorPrevText, this.showPrevPages));
+ }
+
+ for(var i = 0, pageNumber = firstDisplayingPage; i < pageButtonCount && pageNumber <= pageCount; i++, pageNumber++) {
+ pages.push(pageNumber === this.pageIndex
+ ? this._createPagerCurrentPage()
+ : this._createPagerPage(pageNumber));
+ }
+
+ if((firstDisplayingPage + pageButtonCount - 1) < pageCount) {
+ pages.push(this._createPagerPageNavButton(this.pageNavigatorNextText, this.showNextPages));
+ }
+
+ return pages;
+ },
+
+ _createPagerNavButton: function(text, pageIndex, isActive) {
+ return this._createPagerButton(text, this.pagerNavButtonClass + (isActive ? "" : " " + this.pagerNavButtonInactiveClass),
+ isActive ? function() { this.openPage(pageIndex); } : $.noop);
+ },
+
+ _createPagerPageNavButton: function(text, handler) {
+ return this._createPagerButton(text, this.pagerNavButtonClass, handler);
+ },
+
+ _createPagerPage: function(pageIndex) {
+ return this._createPagerButton(pageIndex, this.pageClass, function() {
+ this.openPage(pageIndex);
+ });
+ },
+
+ _createPagerButton: function(text, css, handler) {
+ var $link = $("<a>").attr("href", EMPTY_HREF)
+ .html(text)
+ .on("click", $.proxy(handler, this));
+
+ return $("<span>").addClass(css).append($link);
+ },
+
+ _createPagerCurrentPage: function() {
+ return $("<span>")
+ .addClass(this.pageClass)
+ .addClass(this.currentPageClass)
+ .text(this.pageIndex);
+ },
+
+ _refreshSize: function() {
+ this._refreshHeight();
+ this._refreshWidth();
+ },
+
+ _refreshWidth: function() {
+ var width = (this.width === "auto") ? this._getAutoWidth() : this.width;
+
+ this._container.width(width);
+ },
+
+ _getAutoWidth: function() {
+ var $headerGrid = this._headerGrid,
+ $header = this._header;
+
+ $headerGrid.width("auto");
+
+ var contentWidth = $headerGrid.outerWidth();
+ var borderWidth = $header.outerWidth() - $header.innerWidth();
+
+ $headerGrid.width("");
+
+ return contentWidth + borderWidth;
+ },
+
+ _scrollBarWidth: (function() {
+ var result;
+
+ return function() {
+ if(result === undefined) {
+ var $ghostContainer = $("<div style='width:50px;height:50px;overflow:hidden;position:absolute;top:-10000px;left:-10000px;'></div>");
+ var $ghostContent = $("<div style='height:100px;'></div>");
+ $ghostContainer.append($ghostContent).appendTo("body");
+ var width = $ghostContent.innerWidth();
+ $ghostContainer.css("overflow-y", "auto");
+ var widthExcludingScrollBar = $ghostContent.innerWidth();
+ $ghostContainer.remove();
+ result = width - widthExcludingScrollBar;
+ }
+ return result;
+ };
+ })(),
+
+ _refreshHeight: function() {
+ var container = this._container,
+ pagerContainer = this._pagerContainer,
+ height = this.height,
+ nonBodyHeight;
+
+ container.height(height);
+
+ if(height !== "auto") {
+ height = container.height();
+
+ nonBodyHeight = this._header.outerHeight(true);
+ if(pagerContainer.parents(container).length) {
+ nonBodyHeight += pagerContainer.outerHeight(true);
+ }
+
+ this._body.outerHeight(height - nonBodyHeight);
+ }
+ },
+
+ showPrevPages: function() {
+ var firstDisplayingPage = this._firstDisplayingPage,
+ pageButtonCount = this.pageButtonCount;
+
+ this._firstDisplayingPage = (firstDisplayingPage > pageButtonCount) ? firstDisplayingPage - pageButtonCount : 1;
+
+ this._refreshPager();
+ },
+
+ showNextPages: function() {
+ var firstDisplayingPage = this._firstDisplayingPage,
+ pageButtonCount = this.pageButtonCount,
+ pageCount = this._pagesCount();
+
+ this._firstDisplayingPage = (firstDisplayingPage + 2 * pageButtonCount > pageCount)
+ ? pageCount - pageButtonCount + 1
+ : firstDisplayingPage + pageButtonCount;
+
+ this._refreshPager();
+ },
+
+ openPage: function(pageIndex) {
+ if(pageIndex < 1 || pageIndex > this._pagesCount())
+ return;
+
+ this._setPage(pageIndex);
+ this._loadStrategy.openPage(pageIndex);
+ },
+
+ _setPage: function(pageIndex) {
+ var firstDisplayingPage = this._firstDisplayingPage,
+ pageButtonCount = this.pageButtonCount;
+
+ this.pageIndex = pageIndex;
+
+ if(pageIndex < firstDisplayingPage) {
+ this._firstDisplayingPage = pageIndex;
+ }
+
+ if(pageIndex > firstDisplayingPage + pageButtonCount - 1) {
+ this._firstDisplayingPage = pageIndex - pageButtonCount + 1;
+ }
+
+ this._callEventHandler(this.onPageChanged, {
+ pageIndex: pageIndex
+ });
+ },
+
+ _controllerCall: function(method, param, isCanceled, doneCallback) {
+ if(isCanceled)
+ return $.Deferred().reject().promise();
+
+ this._showLoading();
+
+ var controller = this._controller;
+ if(!controller || !controller[method]) {
+ throw Error("controller has no method '" + method + "'");
+ }
+
+ return normalizePromise(controller[method](param))
+ .done($.proxy(doneCallback, this))
+ .fail($.proxy(this._errorHandler, this))
+ .always($.proxy(this._hideLoading, this));
+ },
+
+ _errorHandler: function() {
+ this._callEventHandler(this.onError, {
+ args: $.makeArray(arguments)
+ });
+ },
+
+ _showLoading: function() {
+ if(!this.loadIndication)
+ return;
+
+ clearTimeout(this._loadingTimer);
+
+ this._loadingTimer = setTimeout($.proxy(function() {
+ this._loadIndicator.show();
+ }, this), this.loadIndicationDelay);
+ },
+
+ _hideLoading: function() {
+ if(!this.loadIndication)
+ return;
+
+ clearTimeout(this._loadingTimer);
+ this._loadIndicator.hide();
+ },
+
+ search: function(filter) {
+ this._resetSorting();
+ this._resetPager();
+ return this.loadData(filter);
+ },
+
+ loadData: function(filter) {
+ filter = filter || (this.filtering ? this.getFilter() : {});
+
+ $.extend(filter, this._loadStrategy.loadParams(), this._sortingParams());
+
+ var args = this._callEventHandler(this.onDataLoading, {
+ filter: filter
+ });
+
+ return this._controllerCall("loadData", filter, args.cancel, function(loadedData) {
+ if(!loadedData)
+ return;
+
+ this._loadStrategy.finishLoad(loadedData);
+
+ this._callEventHandler(this.onDataLoaded, {
+ data: loadedData
+ });
+ });
+ },
+
+ getFilter: function() {
+ var result = {};
+ this._eachField(function(field) {
+ if(field.filtering) {
+ this._setItemFieldValue(result, field, field.filterValue());
+ }
+ });
+ return result;
+ },
+
+ _sortingParams: function() {
+ if(this.sorting && this._sortField) {
+ return {
+ sortField: this._sortField.name,
+ sortOrder: this._sortOrder
+ };
+ }
+ return {};
+ },
+
+ getSorting: function() {
+ var sortingParams = this._sortingParams();
+ return {
+ field: sortingParams.sortField,
+ order: sortingParams.sortOrder
+ };
+ },
+
+ clearFilter: function() {
+ var $filterRow = this._createFilterRow();
+ this._filterRow.replaceWith($filterRow);
+ this._filterRow = $filterRow;
+ return this.search();
+ },
+
+ insertItem: function(item) {
+ var insertingItem = item || this._getValidatedInsertItem();
+
+ if(!insertingItem)
+ return $.Deferred().reject().promise();
+
+ var args = this._callEventHandler(this.onItemInserting, {
+ item: insertingItem
+ });
+
+ return this._controllerCall("insertItem", insertingItem, args.cancel, function(insertedItem) {
+ insertedItem = insertedItem || insertingItem;
+ this._loadStrategy.finishInsert(insertedItem);
+
+ this._callEventHandler(this.onItemInserted, {
+ item: insertedItem
+ });
+ });
+ },
+
+ _getValidatedInsertItem: function() {
+ var item = this._getInsertItem();
+ return this._validateItem(item, this._insertRow) ? item : null;
+ },
+
+ _getInsertItem: function() {
+ var result = {};
+ this._eachField(function(field) {
+ if(field.inserting) {
+ this._setItemFieldValue(result, field, field.insertValue());
+ }
+ });
+ return result;
+ },
+
+ _validateItem: function(item, $row) {
+ var validationErrors = [];
+
+ var args = {
+ item: item,
+ itemIndex: this._rowIndex($row),
+ row: $row
+ };
+
+ this._eachField(function(field) {
+ if(!field.validate ||
+ ($row === this._insertRow && !field.inserting) ||
+ ($row === this._getEditRow() && !field.editing))
+ return;
+
+ var fieldValue = this._getItemFieldValue(item, field);
+
+ var errors = this._validation.validate($.extend({
+ value: fieldValue,
+ rules: field.validate
+ }, args));
+
+ this._setCellValidity($row.children().eq(this._visibleFieldIndex(field)), errors);
+
+ if(!errors.length)
+ return;
+
+ validationErrors.push.apply(validationErrors,
+ $.map(errors, function(message) {
+ return { field: field, message: message };
+ }));
+ });
+
+ if(!validationErrors.length)
+ return true;
+
+ var invalidArgs = $.extend({
+ errors: validationErrors
+ }, args);
+ this._callEventHandler(this.onItemInvalid, invalidArgs);
+ this.invalidNotify(invalidArgs);
+
+ return false;
+ },
+
+ _setCellValidity: function($cell, errors) {
+ $cell
+ .toggleClass(this.invalidClass, !!errors.length)
+ .attr("title", errors.join("\n"));
+ },
+
+ clearInsert: function() {
+ var insertRow = this._createInsertRow();
+ this._insertRow.replaceWith(insertRow);
+ this._insertRow = insertRow;
+ this.refresh();
+ },
+
+ editItem: function(item) {
+ var $row = this.rowByItem(item);
+ if($row.length) {
+ this._editRow($row);
+ }
+ },
+
+ rowByItem: function(item) {
+ if(item.jquery || item.nodeType)
+ return $(item);
+
+ return this._content.find("tr").filter(function() {
+ return $.data(this, JSGRID_ROW_DATA_KEY) === item;
+ });
+ },
+
+ _editRow: function($row) {
+ if(!this.editing)
+ return;
+
+ var item = $row.data(JSGRID_ROW_DATA_KEY);
+
+ var args = this._callEventHandler(this.onItemEditing, {
+ row: $row,
+ item: item,
+ itemIndex: this._itemIndex(item)
+ });
+
+ if(args.cancel)
+ return;
+
+ if(this._editingRow) {
+ this.cancelEdit();
+ }
+
+ var $editRow = this._createEditRow(item);
+
+ this._editingRow = $row;
+ $row.hide();
+ $editRow.insertBefore($row);
+ $row.data(JSGRID_EDIT_ROW_DATA_KEY, $editRow);
+ },
+
+ _createEditRow: function(item) {
+ if($.isFunction(this.editRowRenderer)) {
+ return $(this.renderTemplate(this.editRowRenderer, this, { item: item, itemIndex: this._itemIndex(item) }));
+ }
+
+ var $result = $("<tr>").addClass(this.editRowClass);
+
+ this._eachField(function(field) {
+ var fieldValue = this._getItemFieldValue(item, field);
+
+ this._prepareCell("<td>", field, "editcss")
+ .append(this.renderTemplate(field.editTemplate || "", field, { value: fieldValue, item: item }))
+ .appendTo($result);
+ });
+
+ return $result;
+ },
+
+ updateItem: function(item, editedItem) {
+ if(arguments.length === 1) {
+ editedItem = item;
+ }
+
+ var $row = item ? this.rowByItem(item) : this._editingRow;
+ editedItem = editedItem || this._getValidatedEditedItem();
+
+ if(!editedItem)
+ return;
+
+ return this._updateRow($row, editedItem);
+ },
+
+ _getValidatedEditedItem: function() {
+ var item = this._getEditedItem();
+ return this._validateItem(item, this._getEditRow()) ? item : null;
+ },
+
+ _updateRow: function($updatingRow, editedItem) {
+ var updatingItem = $updatingRow.data(JSGRID_ROW_DATA_KEY),
+ updatingItemIndex = this._itemIndex(updatingItem),
+ updatedItem = $.extend(true, {}, updatingItem, editedItem);
+
+ var args = this._callEventHandler(this.onItemUpdating, {
+ row: $updatingRow,
+ item: updatedItem,
+ itemIndex: updatingItemIndex,
+ previousItem: updatingItem
+ });
+
+ return this._controllerCall("updateItem", updatedItem, args.cancel, function(loadedUpdatedItem) {
+ var previousItem = $.extend(true, {}, updatingItem);
+ updatedItem = loadedUpdatedItem || $.extend(true, updatingItem, editedItem);
+
+ var $updatedRow = this._finishUpdate($updatingRow, updatedItem, updatingItemIndex);
+
+ this._callEventHandler(this.onItemUpdated, {
+ row: $updatedRow,
+ item: updatedItem,
+ itemIndex: updatingItemIndex,
+ previousItem: previousItem
+ });
+ });
+ },
+
+ _rowIndex: function(row) {
+ return this._content.children().index($(row));
+ },
+
+ _itemIndex: function(item) {
+ return $.inArray(item, this.data);
+ },
+
+ _finishUpdate: function($updatingRow, updatedItem, updatedItemIndex) {
+ this.cancelEdit();
+ this.data[updatedItemIndex] = updatedItem;
+
+ var $updatedRow = this._createRow(updatedItem, updatedItemIndex);
+ $updatingRow.replaceWith($updatedRow);
+ return $updatedRow;
+ },
+
+ _getEditedItem: function() {
+ var result = {};
+ this._eachField(function(field) {
+ if(field.editing) {
+ this._setItemFieldValue(result, field, field.editValue());
+ }
+ });
+ return result;
+ },
+
+ cancelEdit: function() {
+ if(!this._editingRow)
+ return;
+
+ this._getEditRow().remove();
+ this._editingRow.show();
+ this._editingRow = null;
+ },
+
+ _getEditRow: function() {
+ return this._editingRow && this._editingRow.data(JSGRID_EDIT_ROW_DATA_KEY);
+ },
+
+ deleteItem: function(item) {
+ var $row = this.rowByItem(item);
+
+ if(!$row.length)
+ return;
+
+ if(this.confirmDeleting && !window.confirm(getOrApply(this.deleteConfirm, this, $row.data(JSGRID_ROW_DATA_KEY))))
+ return;
+
+ return this._deleteRow($row);
+ },
+
+ _deleteRow: function($row) {
+ var deletingItem = $row.data(JSGRID_ROW_DATA_KEY),
+ deletingItemIndex = this._itemIndex(deletingItem);
+
+ var args = this._callEventHandler(this.onItemDeleting, {
+ row: $row,
+ item: deletingItem,
+ itemIndex: deletingItemIndex
+ });
+
+ return this._controllerCall("deleteItem", deletingItem, args.cancel, function() {
+ this._loadStrategy.finishDelete(deletingItem, deletingItemIndex);
+
+ this._callEventHandler(this.onItemDeleted, {
+ row: $row,
+ item: deletingItem,
+ itemIndex: deletingItemIndex
+ });
+ });
+ }
+ };
+
+ $.fn.jsGrid = function(config) {
+ var args = $.makeArray(arguments),
+ methodArgs = args.slice(1),
+ result = this;
+
+ this.each(function() {
+ var $element = $(this),
+ instance = $element.data(JSGRID_DATA_KEY),
+ methodResult;
+
+ if(instance) {
+ if(typeof config === "string") {
+ methodResult = instance[config].apply(instance, methodArgs);
+ if(methodResult !== undefined && methodResult !== instance) {
+ result = methodResult;
+ return false;
+ }
+ } else {
+ instance._detachWindowResizeCallback();
+ instance._init(config);
+ instance.render();
+ }
+ } else {
+ new Grid($element, config);
+ }
+ });
+
+ return result;
+ };
+
+ var fields = {};
+
+ var setDefaults = function(config) {
+ var componentPrototype;
+
+ if($.isPlainObject(config)) {
+ componentPrototype = Grid.prototype;
+ } else {
+ componentPrototype = fields[config].prototype;
+ config = arguments[1] || {};
+ }
+
+ $.extend(componentPrototype, config);
+ };
+
+ var locales = {};
+
+ var locale = function(lang) {
+ var localeConfig = $.isPlainObject(lang) ? lang : locales[lang];
+
+ if(!localeConfig)
+ throw Error("unknown locale " + lang);
+
+ setLocale(jsGrid, localeConfig);
+ };
+
+ var setLocale = function(obj, localeConfig) {
+ $.each(localeConfig, function(field, value) {
+ if($.isPlainObject(value)) {
+ setLocale(obj[field] || obj[field[0].toUpperCase() + field.slice(1)], value);
+ return;
+ }
+
+ if(obj.hasOwnProperty(field)) {
+ obj[field] = value;
+ } else {
+ obj.prototype[field] = value;
+ }
+ });
+ };
+
+ window.jsGrid = {
+ Grid: Grid,
+ fields: fields,
+ setDefaults: setDefaults,
+ locales: locales,
+ locale: locale,
+ version: '1.5.3'
+ };
+
+}(window, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ function LoadIndicator(config) {
+ this._init(config);
+ }
+
+ LoadIndicator.prototype = {
+
+ container: "body",
+ message: "Loading...",
+ shading: true,
+
+ zIndex: 1000,
+ shaderClass: "jsgrid-load-shader",
+ loadPanelClass: "jsgrid-load-panel",
+
+ _init: function(config) {
+ $.extend(true, this, config);
+
+ this._initContainer();
+ this._initShader();
+ this._initLoadPanel();
+ },
+
+ _initContainer: function() {
+ this._container = $(this.container);
+ },
+
+ _initShader: function() {
+ if(!this.shading)
+ return;
+
+ this._shader = $("<div>").addClass(this.shaderClass)
+ .hide()
+ .css({
+ position: "absolute",
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0,
+ zIndex: this.zIndex
+ })
+ .appendTo(this._container);
+ },
+
+ _initLoadPanel: function() {
+ this._loadPanel = $("<div>").addClass(this.loadPanelClass)
+ .text(this.message)
+ .hide()
+ .css({
+ position: "absolute",
+ top: "50%",
+ left: "50%",
+ zIndex: this.zIndex
+ })
+ .appendTo(this._container);
+ },
+
+ show: function() {
+ var $loadPanel = this._loadPanel.show();
+
+ var actualWidth = $loadPanel.outerWidth();
+ var actualHeight = $loadPanel.outerHeight();
+
+ $loadPanel.css({
+ marginTop: -actualHeight / 2,
+ marginLeft: -actualWidth / 2
+ });
+
+ this._shader.show();
+ },
+
+ hide: function() {
+ this._loadPanel.hide();
+ this._shader.hide();
+ }
+
+ };
+
+ jsGrid.LoadIndicator = LoadIndicator;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ function DirectLoadingStrategy(grid) {
+ this._grid = grid;
+ }
+
+ DirectLoadingStrategy.prototype = {
+
+ firstDisplayIndex: function() {
+ var grid = this._grid;
+ return grid.option("paging") ? (grid.option("pageIndex") - 1) * grid.option("pageSize") : 0;
+ },
+
+ lastDisplayIndex: function() {
+ var grid = this._grid;
+ var itemsCount = grid.option("data").length;
+
+ return grid.option("paging")
+ ? Math.min(grid.option("pageIndex") * grid.option("pageSize"), itemsCount)
+ : itemsCount;
+ },
+
+ itemsCount: function() {
+ return this._grid.option("data").length;
+ },
+
+ openPage: function(index) {
+ this._grid.refresh();
+ },
+
+ loadParams: function() {
+ return {};
+ },
+
+ sort: function() {
+ this._grid._sortData();
+ this._grid.refresh();
+ return $.Deferred().resolve().promise();
+ },
+
+ reset: function() {
+ this._grid.refresh();
+ return $.Deferred().resolve().promise();
+ },
+
+ finishLoad: function(loadedData) {
+ this._grid.option("data", loadedData);
+ },
+
+ finishInsert: function(insertedItem) {
+ var grid = this._grid;
+ grid.option("data").push(insertedItem);
+ grid.refresh();
+ },
+
+ finishDelete: function(deletedItem, deletedItemIndex) {
+ var grid = this._grid;
+ grid.option("data").splice(deletedItemIndex, 1);
+ grid.reset();
+ }
+ };
+
+
+ function PageLoadingStrategy(grid) {
+ this._grid = grid;
+ this._itemsCount = 0;
+ }
+
+ PageLoadingStrategy.prototype = {
+
+ firstDisplayIndex: function() {
+ return 0;
+ },
+
+ lastDisplayIndex: function() {
+ return this._grid.option("data").length;
+ },
+
+ itemsCount: function() {
+ return this._itemsCount;
+ },
+
+ openPage: function(index) {
+ this._grid.loadData();
+ },
+
+ loadParams: function() {
+ var grid = this._grid;
+ return {
+ pageIndex: grid.option("pageIndex"),
+ pageSize: grid.option("pageSize")
+ };
+ },
+
+ reset: function() {
+ return this._grid.loadData();
+ },
+
+ sort: function() {
+ return this._grid.loadData();
+ },
+
+ finishLoad: function(loadedData) {
+ this._itemsCount = loadedData.itemsCount;
+ this._grid.option("data", loadedData.data);
+ },
+
+ finishInsert: function(insertedItem) {
+ this._grid.search();
+ },
+
+ finishDelete: function(deletedItem, deletedItemIndex) {
+ this._grid.search();
+ }
+ };
+
+ jsGrid.loadStrategies = {
+ DirectLoadingStrategy: DirectLoadingStrategy,
+ PageLoadingStrategy: PageLoadingStrategy
+ };
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var isDefined = function(val) {
+ return typeof(val) !== "undefined" && val !== null;
+ };
+
+ var sortStrategies = {
+ string: function(str1, str2) {
+ if(!isDefined(str1) && !isDefined(str2))
+ return 0;
+
+ if(!isDefined(str1))
+ return -1;
+
+ if(!isDefined(str2))
+ return 1;
+
+ return ("" + str1).localeCompare("" + str2);
+ },
+
+ number: function(n1, n2) {
+ return n1 - n2;
+ },
+
+ date: function(dt1, dt2) {
+ return dt1 - dt2;
+ },
+
+ numberAsString: function(n1, n2) {
+ return parseFloat(n1) - parseFloat(n2);
+ }
+ };
+
+ jsGrid.sortStrategies = sortStrategies;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ function Validation(config) {
+ this._init(config);
+ }
+
+ Validation.prototype = {
+
+ _init: function(config) {
+ $.extend(true, this, config);
+ },
+
+ validate: function(args) {
+ var errors = [];
+
+ $.each(this._normalizeRules(args.rules), function(_, rule) {
+ if(rule.validator(args.value, args.item, rule.param))
+ return;
+
+ var errorMessage = $.isFunction(rule.message) ? rule.message(args.value, args.item) : rule.message;
+ errors.push(errorMessage);
+ });
+
+ return errors;
+ },
+
+ _normalizeRules: function(rules) {
+ if(!$.isArray(rules))
+ rules = [rules];
+
+ return $.map(rules, $.proxy(function(rule) {
+ return this._normalizeRule(rule);
+ }, this));
+ },
+
+ _normalizeRule: function(rule) {
+ if(typeof rule === "string")
+ rule = { validator: rule };
+
+ if($.isFunction(rule))
+ rule = { validator: rule };
+
+ if($.isPlainObject(rule))
+ rule = $.extend({}, rule);
+ else
+ throw Error("wrong validation config specified");
+
+ if($.isFunction(rule.validator))
+ return rule;
+
+ return this._applyNamedValidator(rule, rule.validator);
+ },
+
+ _applyNamedValidator: function(rule, validatorName) {
+ delete rule.validator;
+
+ var validator = validators[validatorName];
+ if(!validator)
+ throw Error("unknown validator \"" + validatorName + "\"");
+
+ if($.isFunction(validator)) {
+ validator = { validator: validator };
+ }
+
+ return $.extend({}, validator, rule);
+ }
+ };
+
+ jsGrid.Validation = Validation;
+
+
+ var validators = {
+ required: {
+ message: "Field is required",
+ validator: function(value) {
+ return value !== undefined && value !== null && value !== "";
+ }
+ },
+
+ rangeLength: {
+ message: "Field value length is out of the defined range",
+ validator: function(value, _, param) {
+ return value.length >= param[0] && value.length <= param[1];
+ }
+ },
+
+ minLength: {
+ message: "Field value is too short",
+ validator: function(value, _, param) {
+ return value.length >= param;
+ }
+ },
+
+ maxLength: {
+ message: "Field value is too long",
+ validator: function(value, _, param) {
+ return value.length <= param;
+ }
+ },
+
+ pattern: {
+ message: "Field value is not matching the defined pattern",
+ validator: function(value, _, param) {
+ if(typeof param === "string") {
+ param = new RegExp("^(?:" + param + ")$");
+ }
+ return param.test(value);
+ }
+ },
+
+ range: {
+ message: "Field value is out of the defined range",
+ validator: function(value, _, param) {
+ return value >= param[0] && value <= param[1];
+ }
+ },
+
+ min: {
+ message: "Field value is too small",
+ validator: function(value, _, param) {
+ return value >= param;
+ }
+ },
+
+ max: {
+ message: "Field value is too large",
+ validator: function(value, _, param) {
+ return value <= param;
+ }
+ }
+ };
+
+ jsGrid.validators = validators;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ function Field(config) {
+ $.extend(true, this, config);
+ this.sortingFunc = this._getSortingFunc();
+ }
+
+ Field.prototype = {
+ name: "",
+ title: null,
+ css: "",
+ align: "",
+ width: 100,
+
+ visible: true,
+ filtering: true,
+ inserting: true,
+ editing: true,
+ sorting: true,
+ sorter: "string", // name of SortStrategy or function to compare elements
+
+ headerTemplate: function() {
+ return (this.title === undefined || this.title === null) ? this.name : this.title;
+ },
+
+ itemTemplate: function(value, item) {
+ return value;
+ },
+
+ filterTemplate: function() {
+ return "";
+ },
+
+ insertTemplate: function() {
+ return "";
+ },
+
+ editTemplate: function(value, item) {
+ this._value = value;
+ return this.itemTemplate(value, item);
+ },
+
+ filterValue: function() {
+ return "";
+ },
+
+ insertValue: function() {
+ return "";
+ },
+
+ editValue: function() {
+ return this._value;
+ },
+
+ _getSortingFunc: function() {
+ var sorter = this.sorter;
+
+ if($.isFunction(sorter)) {
+ return sorter;
+ }
+
+ if(typeof sorter === "string") {
+ return jsGrid.sortStrategies[sorter];
+ }
+
+ throw Error("wrong sorter for the field \"" + this.name + "\"!");
+ }
+ };
+
+ jsGrid.Field = Field;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var Field = jsGrid.Field;
+
+ function TextField(config) {
+ Field.call(this, config);
+ }
+
+ TextField.prototype = new Field({
+
+ autosearch: true,
+ readOnly: false,
+
+ filterTemplate: function() {
+ if(!this.filtering)
+ return "";
+
+ var grid = this._grid,
+ $result = this.filterControl = this._createTextBox();
+
+ if(this.autosearch) {
+ $result.on("keypress", function(e) {
+ if(e.which === 13) {
+ grid.search();
+ e.preventDefault();
+ }
+ });
+ }
+
+ return $result;
+ },
+
+ insertTemplate: function() {
+ if(!this.inserting)
+ return "";
+
+ return this.insertControl = this._createTextBox();
+ },
+
+ editTemplate: function(value) {
+ if(!this.editing)
+ return this.itemTemplate.apply(this, arguments);
+
+ var $result = this.editControl = this._createTextBox();
+ $result.val(value);
+ return $result;
+ },
+
+ filterValue: function() {
+ return this.filterControl.val();
+ },
+
+ insertValue: function() {
+ return this.insertControl.val();
+ },
+
+ editValue: function() {
+ return this.editControl.val();
+ },
+
+ _createTextBox: function() {
+ return $("<input>").attr("type", "text")
+ .prop("readonly", !!this.readOnly);
+ }
+ });
+
+ jsGrid.fields.text = jsGrid.TextField = TextField;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var TextField = jsGrid.TextField;
+
+ function NumberField(config) {
+ TextField.call(this, config);
+ }
+
+ NumberField.prototype = new TextField({
+
+ sorter: "number",
+ align: "right",
+ readOnly: false,
+
+ filterValue: function() {
+ return this.filterControl.val()
+ ? parseInt(this.filterControl.val() || 0, 10)
+ : undefined;
+ },
+
+ insertValue: function() {
+ return this.insertControl.val()
+ ? parseInt(this.insertControl.val() || 0, 10)
+ : undefined;
+ },
+
+ editValue: function() {
+ return this.editControl.val()
+ ? parseInt(this.editControl.val() || 0, 10)
+ : undefined;
+ },
+
+ _createTextBox: function() {
+ return $("<input>").attr("type", "number")
+ .prop("readonly", !!this.readOnly);
+ }
+ });
+
+ jsGrid.fields.number = jsGrid.NumberField = NumberField;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var TextField = jsGrid.TextField;
+
+ function TextAreaField(config) {
+ TextField.call(this, config);
+ }
+
+ TextAreaField.prototype = new TextField({
+
+ insertTemplate: function() {
+ if(!this.inserting)
+ return "";
+
+ return this.insertControl = this._createTextArea();
+ },
+
+ editTemplate: function(value) {
+ if(!this.editing)
+ return this.itemTemplate.apply(this, arguments);
+
+ var $result = this.editControl = this._createTextArea();
+ $result.val(value);
+ return $result;
+ },
+
+ _createTextArea: function() {
+ return $("<textarea>").prop("readonly", !!this.readOnly);
+ }
+ });
+
+ jsGrid.fields.textarea = jsGrid.TextAreaField = TextAreaField;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var NumberField = jsGrid.NumberField;
+ var numberValueType = "number";
+ var stringValueType = "string";
+
+ function SelectField(config) {
+ this.items = [];
+ this.selectedIndex = -1;
+ this.valueField = "";
+ this.textField = "";
+
+ if(config.valueField && config.items.length) {
+ var firstItemValue = config.items[0][config.valueField];
+ this.valueType = (typeof firstItemValue) === numberValueType ? numberValueType : stringValueType;
+ }
+
+ this.sorter = this.valueType;
+
+ NumberField.call(this, config);
+ }
+
+ SelectField.prototype = new NumberField({
+
+ align: "center",
+ valueType: numberValueType,
+
+ itemTemplate: function(value) {
+ var items = this.items,
+ valueField = this.valueField,
+ textField = this.textField,
+ resultItem;
+
+ if(valueField) {
+ resultItem = $.grep(items, function(item, index) {
+ return item[valueField] === value;
+ })[0] || {};
+ }
+ else {
+ resultItem = items[value];
+ }
+
+ var result = (textField ? resultItem[textField] : resultItem);
+
+ return (result === undefined || result === null) ? "" : result;
+ },
+
+ filterTemplate: function() {
+ if(!this.filtering)
+ return "";
+
+ var grid = this._grid,
+ $result = this.filterControl = this._createSelect();
+
+ if(this.autosearch) {
+ $result.on("change", function(e) {
+ grid.search();
+ });
+ }
+
+ return $result;
+ },
+
+ insertTemplate: function() {
+ if(!this.inserting)
+ return "";
+
+ return this.insertControl = this._createSelect();
+ },
+
+ editTemplate: function(value) {
+ if(!this.editing)
+ return this.itemTemplate.apply(this, arguments);
+
+ var $result = this.editControl = this._createSelect();
+ (value !== undefined) && $result.val(value);
+ return $result;
+ },
+
+ filterValue: function() {
+ var val = this.filterControl.val();
+ return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
+ },
+
+ insertValue: function() {
+ var val = this.insertControl.val();
+ return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
+ },
+
+ editValue: function() {
+ var val = this.editControl.val();
+ return this.valueType === numberValueType ? parseInt(val || 0, 10) : val;
+ },
+
+ _createSelect: function() {
+ var $result = $("<select>"),
+ valueField = this.valueField,
+ textField = this.textField,
+ selectedIndex = this.selectedIndex;
+
+ $.each(this.items, function(index, item) {
+ var value = valueField ? item[valueField] : index,
+ text = textField ? item[textField] : item;
+
+ var $option = $("<option>")
+ .attr("value", value)
+ .text(text)
+ .appendTo($result);
+
+ $option.prop("selected", (selectedIndex === index));
+ });
+
+ $result.prop("disabled", !!this.readOnly);
+
+ return $result;
+ }
+ });
+
+ jsGrid.fields.select = jsGrid.SelectField = SelectField;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var Field = jsGrid.Field;
+
+ function CheckboxField(config) {
+ Field.call(this, config);
+ }
+
+ CheckboxField.prototype = new Field({
+
+ sorter: "number",
+ align: "center",
+ autosearch: true,
+
+ itemTemplate: function(value) {
+ return this._createCheckbox().prop({
+ checked: value,
+ disabled: true
+ });
+ },
+
+ filterTemplate: function() {
+ if(!this.filtering)
+ return "";
+
+ var grid = this._grid,
+ $result = this.filterControl = this._createCheckbox();
+
+ $result.prop({
+ readOnly: true,
+ indeterminate: true
+ });
+
+ $result.on("click", function() {
+ var $cb = $(this);
+
+ if($cb.prop("readOnly")) {
+ $cb.prop({
+ checked: false,
+ readOnly: false
+ });
+ }
+ else if(!$cb.prop("checked")) {
+ $cb.prop({
+ readOnly: true,
+ indeterminate: true
+ });
+ }
+ });
+
+ if(this.autosearch) {
+ $result.on("click", function() {
+ grid.search();
+ });
+ }
+
+ return $result;
+ },
+
+ insertTemplate: function() {
+ if(!this.inserting)
+ return "";
+
+ return this.insertControl = this._createCheckbox();
+ },
+
+ editTemplate: function(value) {
+ if(!this.editing)
+ return this.itemTemplate.apply(this, arguments);
+
+ var $result = this.editControl = this._createCheckbox();
+ $result.prop("checked", value);
+ return $result;
+ },
+
+ filterValue: function() {
+ return this.filterControl.get(0).indeterminate
+ ? undefined
+ : this.filterControl.is(":checked");
+ },
+
+ insertValue: function() {
+ return this.insertControl.is(":checked");
+ },
+
+ editValue: function() {
+ return this.editControl.is(":checked");
+ },
+
+ _createCheckbox: function() {
+ return $("<input>").attr("type", "checkbox");
+ }
+ });
+
+ jsGrid.fields.checkbox = jsGrid.CheckboxField = CheckboxField;
+
+}(jsGrid, jQuery));
+
+(function(jsGrid, $, undefined) {
+
+ var Field = jsGrid.Field;
+
+ function ControlField(config) {
+ Field.call(this, config);
+ this._configInitialized = false;
+ }
+
+ ControlField.prototype = new Field({
+ css: "jsgrid-control-field",
+ align: "center",
+ width: 50,
+ filtering: false,
+ inserting: false,
+ editing: false,
+ sorting: false,
+
+ buttonClass: "jsgrid-button",
+ modeButtonClass: "jsgrid-mode-button",
+
+ modeOnButtonClass: "jsgrid-mode-on-button",
+ searchModeButtonClass: "jsgrid-search-mode-button",
+ insertModeButtonClass: "jsgrid-insert-mode-button",
+ editButtonClass: "jsgrid-edit-button",
+ deleteButtonClass: "jsgrid-delete-button",
+ searchButtonClass: "jsgrid-search-button",
+ clearFilterButtonClass: "jsgrid-clear-filter-button",
+ insertButtonClass: "jsgrid-insert-button",
+ updateButtonClass: "jsgrid-update-button",
+ cancelEditButtonClass: "jsgrid-cancel-edit-button",
+
+ searchModeButtonTooltip: "Switch to searching",
+ insertModeButtonTooltip: "Switch to inserting",
+ editButtonTooltip: "Edit",
+ deleteButtonTooltip: "Delete",
+ searchButtonTooltip: "Search",
+ clearFilterButtonTooltip: "Clear filter",
+ insertButtonTooltip: "Insert",
+ updateButtonTooltip: "Update",
+ cancelEditButtonTooltip: "Cancel edit",
+
+ editButton: true,
+ deleteButton: true,
+ clearFilterButton: true,
+ modeSwitchButton: true,
+
+ _initConfig: function() {
+ this._hasFiltering = this._grid.filtering;
+ this._hasInserting = this._grid.inserting;
+
+ if(this._hasInserting && this.modeSwitchButton) {
+ this._grid.inserting = false;
+ }
+
+ this._configInitialized = true;
+ },
+
+ headerTemplate: function() {
+ if(!this._configInitialized) {
+ this._initConfig();
+ }
+
+ var hasFiltering = this._hasFiltering;
+ var hasInserting = this._hasInserting;
+
+ if(!this.modeSwitchButton || (!hasFiltering && !hasInserting))
+ return "";
+
+ if(hasFiltering && !hasInserting)
+ return this._createFilterSwitchButton();
+
+ if(hasInserting && !hasFiltering)
+ return this._createInsertSwitchButton();
+
+ return this._createModeSwitchButton();
+ },
+
+ itemTemplate: function(value, item) {
+ var $result = $([]);
+
+ if(this.editButton) {
+ $result = $result.add(this._createEditButton(item));
+ }
+
+ if(this.deleteButton) {
+ $result = $result.add(this._createDeleteButton(item));
+ }
+
+ return $result;
+ },
+
+ filterTemplate: function() {
+ var $result = this._createSearchButton();
+ return this.clearFilterButton ? $result.add(this._createClearFilterButton()) : $result;
+ },
+
+ insertTemplate: function() {
+ return this._createInsertButton();
+ },
+
+ editTemplate: function() {
+ return this._createUpdateButton().add(this._createCancelEditButton());
+ },
+
+ _createFilterSwitchButton: function() {
+ return this._createOnOffSwitchButton("filtering", this.searchModeButtonClass, true);
+ },
+
+ _createInsertSwitchButton: function() {
+ return this._createOnOffSwitchButton("inserting", this.insertModeButtonClass, false);
+ },
+
+ _createOnOffSwitchButton: function(option, cssClass, isOnInitially) {
+ var isOn = isOnInitially;
+
+ var updateButtonState = $.proxy(function() {
+ $button.toggleClass(this.modeOnButtonClass, isOn);
+ }, this);
+
+ var $button = this._createGridButton(this.modeButtonClass + " " + cssClass, "", function(grid) {
+ isOn = !isOn;
+ grid.option(option, isOn);
+ updateButtonState();
+ });
+
+ updateButtonState();
+
+ return $button;
+ },
+
+ _createModeSwitchButton: function() {
+ var isInserting = false;
+
+ var updateButtonState = $.proxy(function() {
+ $button.attr("title", isInserting ? this.searchModeButtonTooltip : this.insertModeButtonTooltip)
+ .toggleClass(this.insertModeButtonClass, !isInserting)
+ .toggleClass(this.searchModeButtonClass, isInserting);
+ }, this);
+
+ var $button = this._createGridButton(this.modeButtonClass, "", function(grid) {
+ isInserting = !isInserting;
+ grid.option("inserting", isInserting);
+ grid.option("filtering", !isInserting);
+ updateButtonState();
+ });
+
+ updateButtonState();
+
+ return $button;
+ },
+
+ _createEditButton: function(item) {
+ return this._createGridButton(this.editButtonClass, this.editButtonTooltip, function(grid, e) {
+ grid.editItem(item);
+ e.stopPropagation();
+ });
+ },
+
+ _createDeleteButton: function(item) {
+ return this._createGridButton(this.deleteButtonClass, this.deleteButtonTooltip, function(grid, e) {
+ grid.deleteItem(item);
+ e.stopPropagation();
+ });
+ },
+
+ _createSearchButton: function() {
+ return this._createGridButton(this.searchButtonClass, this.searchButtonTooltip, function(grid) {
+ grid.search();
+ });
+ },
+
+ _createClearFilterButton: function() {
+ return this._createGridButton(this.clearFilterButtonClass, this.clearFilterButtonTooltip, function(grid) {
+ grid.clearFilter();
+ });
+ },
+
+ _createInsertButton: function() {
+ return this._createGridButton(this.insertButtonClass, this.insertButtonTooltip, function(grid) {
+ grid.insertItem().done(function() {
+ grid.clearInsert();
+ });
+ });
+ },
+
+ _createUpdateButton: function() {
+ return this._createGridButton(this.updateButtonClass, this.updateButtonTooltip, function(grid, e) {
+ grid.updateItem();
+ e.stopPropagation();
+ });
+ },
+
+ _createCancelEditButton: function() {
+ return this._createGridButton(this.cancelEditButtonClass, this.cancelEditButtonTooltip, function(grid, e) {
+ grid.cancelEdit();
+ e.stopPropagation();
+ });
+ },
+
+ _createGridButton: function(cls, tooltip, clickHandler) {
+ var grid = this._grid;
+
+ return $("<input>").addClass(this.buttonClass)
+ .addClass(cls)
+ .attr({
+ type: "button",
+ title: tooltip
+ })
+ .on("click", function(e) {
+ clickHandler(grid, e);
+ });
+ },
+
+ editValue: function() {
+ return "";
+ }
+
+ });
+
+ jsGrid.fields.control = jsGrid.ControlField = ControlField;
+
+}(jsGrid, jQuery));
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid.min.css b/build/resources/main/static/plugins/jsgrid/jsgrid.min.css
new file mode 100644
index 0000000..dac794d
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid.min.css
@@ -0,0 +1,7 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+.jsgrid{position:relative;overflow:hidden;font-size:1em}.jsgrid,.jsgrid *,.jsgrid :after,.jsgrid :before{box-sizing:border-box}.jsgrid input,.jsgrid select,.jsgrid textarea{font-size:1em}.jsgrid-grid-header{overflow-x:hidden;overflow-y:scroll;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.jsgrid-grid-body{overflow-x:auto;overflow-y:scroll;-webkit-overflow-scrolling:touch}.jsgrid-table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0}.jsgrid-cell{padding:.5em}.jsgrid-header-cell,.jsgrid-сell{box-sizing:border-box}.jsgrid-align-left{text-align:left}.jsgrid-align-center,.jsgrid-align-center input,.jsgrid-align-center select,.jsgrid-align-center textarea{text-align:center}.jsgrid-align-right,.jsgrid-align-right input,.jsgrid-align-right select,.jsgrid-align-right textarea{text-align:right}.jsgrid-header-cell{padding:.5em}.jsgrid-edit-row input,.jsgrid-edit-row select,.jsgrid-edit-row textarea,.jsgrid-filter-row input,.jsgrid-filter-row select,.jsgrid-filter-row textarea,.jsgrid-insert-row input,.jsgrid-insert-row select,.jsgrid-insert-row textarea{width:100%;padding:.3em .5em}.jsgrid-edit-row input[type=checkbox],.jsgrid-filter-row input[type=checkbox],.jsgrid-insert-row input[type=checkbox]{width:auto}.jsgrid-selected-row .jsgrid-cell{cursor:pointer}.jsgrid-nodata-row .jsgrid-cell{padding:.5em 0;text-align:center}.jsgrid-header-sort{cursor:pointer}.jsgrid-pager{padding:.5em 0}.jsgrid-pager-nav-button{padding:.2em .6em}.jsgrid-pager-nav-inactive-button{display:none;pointer-events:none}.jsgrid-pager-page{padding:.2em .6em} \ No newline at end of file
diff --git a/build/resources/main/static/plugins/jsgrid/jsgrid.min.js b/build/resources/main/static/plugins/jsgrid/jsgrid.min.js
new file mode 100644
index 0000000..6738ff5
--- /dev/null
+++ b/build/resources/main/static/plugins/jsgrid/jsgrid.min.js
@@ -0,0 +1,8 @@
+/*
+ * jsGrid v1.5.3 (http://js-grid.com)
+ * (c) 2016 Artem Tabalin
+ * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE)
+ */
+
+!function(a,b,c){function d(a,c){var d=b(a);d.data(f,this),this._container=d,this.data=[],this.fields=[],this._editingRow=null,this._sortField=null,this._sortOrder=i,this._firstDisplayingPage=1,this._init(c),this.render()}var e="JSGrid",f=e,g="JSGridItem",h="JSGridEditRow",i="asc",j="desc",k="{first}",l="{pages}",m="{prev}",n="{next}",o="{last}",p="{pageIndex}",q="{pageCount}",r="{itemCount}",s="javascript:void(0);",t=function(a,c){return b.isFunction(a)?a.apply(c,b.makeArray(arguments).slice(2)):a},u=function(a){var c=b.Deferred();return a&&a.then?a.then(function(){c.resolve.apply(c,arguments)},function(){c.reject.apply(c,arguments)}):c.resolve(a),c.promise()},v={loadData:b.noop,insertItem:b.noop,updateItem:b.noop,deleteItem:b.noop};d.prototype={width:"auto",height:"auto",updateOnResize:!0,rowClass:b.noop,rowRenderer:null,rowClick:function(a){this.editing&&this.editItem(b(a.event.target).closest("tr"))},rowDoubleClick:b.noop,noDataContent:"Not found",noDataRowClass:"jsgrid-nodata-row",heading:!0,headerRowRenderer:null,headerRowClass:"jsgrid-header-row",headerCellClass:"jsgrid-header-cell",filtering:!1,filterRowRenderer:null,filterRowClass:"jsgrid-filter-row",inserting:!1,insertRowRenderer:null,insertRowClass:"jsgrid-insert-row",editing:!1,editRowRenderer:null,editRowClass:"jsgrid-edit-row",confirmDeleting:!0,deleteConfirm:"Are you sure?",selecting:!0,selectedRowClass:"jsgrid-selected-row",oddRowClass:"jsgrid-row",evenRowClass:"jsgrid-alt-row",cellClass:"jsgrid-cell",sorting:!1,sortableClass:"jsgrid-header-sortable",sortAscClass:"jsgrid-header-sort jsgrid-header-sort-asc",sortDescClass:"jsgrid-header-sort jsgrid-header-sort-desc",paging:!1,pagerContainer:null,pageIndex:1,pageSize:20,pageButtonCount:15,pagerFormat:"Pages: {first} {prev} {pages} {next} {last} &nbsp;&nbsp; {pageIndex} of {pageCount}",pagePrevText:"Prev",pageNextText:"Next",pageFirstText:"First",pageLastText:"Last",pageNavigatorNextText:"...",pageNavigatorPrevText:"...",pagerContainerClass:"jsgrid-pager-container",pagerClass:"jsgrid-pager",pagerNavButtonClass:"jsgrid-pager-nav-button",pagerNavButtonInactiveClass:"jsgrid-pager-nav-inactive-button",pageClass:"jsgrid-pager-page",currentPageClass:"jsgrid-pager-current-page",customLoading:!1,pageLoading:!1,autoload:!1,controller:v,loadIndication:!0,loadIndicationDelay:500,loadMessage:"Please, wait...",loadShading:!0,invalidMessage:"Invalid data entered!",invalidNotify:function(c){var d=b.map(c.errors,function(a){return a.message||null});a.alert([this.invalidMessage].concat(d).join("\n"))},onInit:b.noop,onRefreshing:b.noop,onRefreshed:b.noop,onPageChanged:b.noop,onItemDeleting:b.noop,onItemDeleted:b.noop,onItemInserting:b.noop,onItemInserted:b.noop,onItemEditing:b.noop,onItemUpdating:b.noop,onItemUpdated:b.noop,onItemInvalid:b.noop,onDataLoading:b.noop,onDataLoaded:b.noop,onOptionChanging:b.noop,onOptionChanged:b.noop,onError:b.noop,invalidClass:"jsgrid-invalid",containerClass:"jsgrid",tableClass:"jsgrid-table",gridHeaderClass:"jsgrid-grid-header",gridBodyClass:"jsgrid-grid-body",_init:function(a){b.extend(this,a),this._initLoadStrategy(),this._initController(),this._initFields(),this._attachWindowLoadResize(),this._attachWindowResizeCallback(),this._callEventHandler(this.onInit)},loadStrategy:function(){return this.pageLoading?new jsGrid.loadStrategies.PageLoadingStrategy(this):new jsGrid.loadStrategies.DirectLoadingStrategy(this)},_initLoadStrategy:function(){this._loadStrategy=t(this.loadStrategy,this)},_initController:function(){this._controller=b.extend({},v,t(this.controller,this))},renderTemplate:function(a,b,d){args=[];for(var e in d)args.push(d[e]);return args.unshift(a,b),a=t.apply(null,args),a===c||null===a?"":a},loadIndicator:function(a){return new jsGrid.LoadIndicator(a)},validation:function(a){return jsGrid.Validation&&new jsGrid.Validation(a)},_initFields:function(){var a=this;a.fields=b.map(a.fields,function(c){if(b.isPlainObject(c)){var d=c.type&&jsGrid.fields[c.type]||jsGrid.Field;c=new d(c)}return c._grid=a,c})},_attachWindowLoadResize:function(){b(a).on("load",b.proxy(this._refreshSize,this))},_attachWindowResizeCallback:function(){this.updateOnResize&&b(a).on("resize",b.proxy(this._refreshSize,this))},_detachWindowResizeCallback:function(){b(a).off("resize",this._refreshSize)},option:function(a,b){var c,d;return 1===arguments.length?this[a]:(c={option:a,oldValue:this[a],newValue:b},this._callEventHandler(this.onOptionChanging,c),this._handleOptionChange(c.option,c.newValue),d={option:c.option,value:c.newValue},void this._callEventHandler(this.onOptionChanged,d))},fieldOption:function(a,b,c){return a=this._normalizeField(a),2===arguments.length?a[b]:(a[b]=c,void this._renderGrid())},_handleOptionChange:function(a,b){switch(this[a]=b,a){case"width":case"height":this._refreshSize();break;case"rowClass":case"rowRenderer":case"rowClick":case"rowDoubleClick":case"noDataRowClass":case"noDataContent":case"selecting":case"selectedRowClass":case"oddRowClass":case"evenRowClass":this._refreshContent();break;case"pageButtonCount":case"pagerFormat":case"pagePrevText":case"pageNextText":case"pageFirstText":case"pageLastText":case"pageNavigatorNextText":case"pageNavigatorPrevText":case"pagerClass":case"pagerNavButtonClass":case"pageClass":case"currentPageClass":case"pagerRenderer":this._refreshPager();break;case"fields":this._initFields(),this.render();break;case"data":case"editing":case"heading":case"filtering":case"inserting":case"paging":this.refresh();break;case"loadStrategy":case"pageLoading":this._initLoadStrategy(),this.search();break;case"pageIndex":this.openPage(b);break;case"pageSize":this.refresh(),this.search();break;case"editRowRenderer":case"editRowClass":this.cancelEdit();break;case"updateOnResize":this._detachWindowResizeCallback(),this._attachWindowResizeCallback();break;case"invalidNotify":case"invalidMessage":break;default:this.render()}},destroy:function(){this._detachWindowResizeCallback(),this._clear(),this._container.removeData(f)},render:function(){return this._renderGrid(),this.autoload?this.loadData():b.Deferred().resolve().promise()},_renderGrid:function(){this._clear(),this._container.addClass(this.containerClass).css("position","relative").append(this._createHeader()).append(this._createBody()),this._pagerContainer=this._createPagerContainer(),this._loadIndicator=this._createLoadIndicator(),this._validation=this._createValidation(),this.refresh()},_createLoadIndicator:function(){return t(this.loadIndicator,this,{message:this.loadMessage,shading:this.loadShading,container:this._container})},_createValidation:function(){return t(this.validation,this)},_clear:function(){this.cancelEdit(),clearTimeout(this._loadingTimer),this._pagerContainer&&this._pagerContainer.empty(),this._container.empty().css({position:"",width:"",height:""})},_createHeader:function(){var a=this._headerRow=this._createHeaderRow(),c=this._filterRow=this._createFilterRow(),d=this._insertRow=this._createInsertRow(),e=this._headerGrid=b("<table>").addClass(this.tableClass).append(a).append(c).append(d),f=this._header=b("<div>").addClass(this.gridHeaderClass).addClass(this._scrollBarWidth()?"jsgrid-header-scrollbar":"").append(e);return f},_createBody:function(){var a=this._content=b("<tbody>"),c=this._bodyGrid=b("<table>").addClass(this.tableClass).append(a),d=this._body=b("<div>").addClass(this.gridBodyClass).append(c).on("scroll",b.proxy(function(a){this._header.scrollLeft(a.target.scrollLeft)},this));return d},_createPagerContainer:function(){var a=this.pagerContainer||b("<div>").appendTo(this._container);return b(a).addClass(this.pagerContainerClass)},_eachField:function(a){var c=this;b.each(this.fields,function(b,d){d.visible&&a.call(c,d,b)})},_createHeaderRow:function(){if(b.isFunction(this.headerRowRenderer))return b(this.renderTemplate(this.headerRowRenderer,this));var a=b("<tr>").addClass(this.headerRowClass);return this._eachField(function(c,d){var e=this._prepareCell("<th>",c,"headercss",this.headerCellClass).append(this.renderTemplate(c.headerTemplate,c)).appendTo(a);this.sorting&&c.sorting&&e.addClass(this.sortableClass).on("click",b.proxy(function(){this.sort(d)},this))}),a},_prepareCell:function(a,c,d,e){return b(a).css("width",c.width).addClass(e||this.cellClass).addClass(d&&c[d]||c.css).addClass(c.align?"jsgrid-align-"+c.align:"")},_createFilterRow:function(){if(b.isFunction(this.filterRowRenderer))return b(this.renderTemplate(this.filterRowRenderer,this));var a=b("<tr>").addClass(this.filterRowClass);return this._eachField(function(b){this._prepareCell("<td>",b,"filtercss").append(this.renderTemplate(b.filterTemplate,b)).appendTo(a)}),a},_createInsertRow:function(){if(b.isFunction(this.insertRowRenderer))return b(this.renderTemplate(this.insertRowRenderer,this));var a=b("<tr>").addClass(this.insertRowClass);return this._eachField(function(b){this._prepareCell("<td>",b,"insertcss").append(this.renderTemplate(b.insertTemplate,b)).appendTo(a)}),a},_callEventHandler:function(a,c){return a.call(this,b.extend(c,{grid:this})),c},reset:function(){return this._resetSorting(),this._resetPager(),this._loadStrategy.reset()},_resetPager:function(){this._firstDisplayingPage=1,this._setPage(1)},_resetSorting:function(){this._sortField=null,this._sortOrder=i,this._clearSortingCss()},refresh:function(){this._callEventHandler(this.onRefreshing),this.cancelEdit(),this._refreshHeading(),this._refreshFiltering(),this._refreshInserting(),this._refreshContent(),this._refreshPager(),this._refreshSize(),this._callEventHandler(this.onRefreshed)},_refreshHeading:function(){this._headerRow.toggle(this.heading)},_refreshFiltering:function(){this._filterRow.toggle(this.filtering)},_refreshInserting:function(){this._insertRow.toggle(this.inserting)},_refreshContent:function(){var a=this._content;if(a.empty(),!this.data.length)return a.append(this._createNoDataRow()),this;for(var b=this._loadStrategy.firstDisplayIndex(),c=this._loadStrategy.lastDisplayIndex(),d=b;c>d;d++){var e=this.data[d];a.append(this._createRow(e,d))}},_createNoDataRow:function(){var a=0;return this._eachField(function(){a++}),b("<tr>").addClass(this.noDataRowClass).append(b("<td>").addClass(this.cellClass).attr("colspan",a).append(this.renderTemplate(this.noDataContent,this)))},_createRow:function(a,c){var d;return b.isFunction(this.rowRenderer)?d=this.renderTemplate(this.rowRenderer,this,{item:a,itemIndex:c}):(d=b("<tr>"),this._renderCells(d,a)),d.addClass(this._getRowClasses(a,c)).data(g,a).on("click",b.proxy(function(b){this.rowClick({item:a,itemIndex:c,event:b})},this)).on("dblclick",b.proxy(function(b){this.rowDoubleClick({item:a,itemIndex:c,event:b})},this)),this.selecting&&this._attachRowHover(d),d},_getRowClasses:function(a,b){var c=[];return c.push((b+1)%2?this.oddRowClass:this.evenRowClass),c.push(t(this.rowClass,this,a,b)),c.join(" ")},_attachRowHover:function(a){var c=this.selectedRowClass;a.hover(function(){b(this).addClass(c)},function(){b(this).removeClass(c)})},_renderCells:function(a,b){return this._eachField(function(c){a.append(this._createCell(b,c))}),this},_createCell:function(a,c){var d,e=this._getItemFieldValue(a,c),f={value:e,item:a};return d=b.isFunction(c.cellRenderer)?this.renderTemplate(c.cellRenderer,c,f):b("<td>").append(this.renderTemplate(c.itemTemplate||e,c,f)),this._prepareCell(d,c)},_getItemFieldValue:function(a,b){for(var c=b.name.split("."),d=a[c.shift()];d&&c.length;)d=d[c.shift()];return d},_setItemFieldValue:function(a,b,c){for(var d=b.name.split("."),e=a,f=d[0];e&&d.length;)a=e,f=d.shift(),e=a[f];if(!e)for(;d.length;)a=a[f]={},f=d.shift();a[f]=c},sort:function(a,c){return b.isPlainObject(a)&&(c=a.order,a=a.field),this._clearSortingCss(),this._setSortingParams(a,c),this._setSortingCss(),this._loadStrategy.sort()},_clearSortingCss:function(){this._headerRow.find("th").removeClass(this.sortAscClass).removeClass(this.sortDescClass)},_setSortingParams:function(a,b){a=this._normalizeField(a),b=b||(this._sortField===a?this._reversedSortOrder(this._sortOrder):i),this._sortField=a,this._sortOrder=b},_normalizeField:function(a){return b.isNumeric(a)?this.fields[a]:"string"==typeof a?b.grep(this.fields,function(b){return b.name===a})[0]:a},_reversedSortOrder:function(a){return a===i?j:i},_setSortingCss:function(){var a=this._visibleFieldIndex(this._sortField);this._headerRow.find("th").eq(a).addClass(this._sortOrder===i?this.sortAscClass:this.sortDescClass)},_visibleFieldIndex:function(a){return b.inArray(a,b.grep(this.fields,function(a){return a.visible}))},_sortData:function(){var a=this._sortFactor(),b=this._sortField;b&&this.data.sort(function(c,d){return a*b.sortingFunc(c[b.name],d[b.name])})},_sortFactor:function(){return this._sortOrder===i?1:-1},_itemsCount:function(){return this._loadStrategy.itemsCount()},_pagesCount:function(){var a=this._itemsCount(),b=this.pageSize;return Math.floor(a/b)+(a%b?1:0)},_refreshPager:function(){var a=this._pagerContainer;a.empty(),this.paging&&a.append(this._createPager());var b=this.paging&&this._pagesCount()>1;a.toggle(b)},_createPager:function(){var a;return a=b.isFunction(this.pagerRenderer)?b(this.pagerRenderer({pageIndex:this.pageIndex,pageCount:this._pagesCount()})):b("<div>").append(this._createPagerByFormat()),a.addClass(this.pagerClass),a},_createPagerByFormat:function(){var a=this.pageIndex,c=this._pagesCount(),d=this._itemsCount(),e=this.pagerFormat.split(" ");return b.map(e,b.proxy(function(e){var f=e;return e===l?f=this._createPages():e===k?f=this._createPagerNavButton(this.pageFirstText,1,a>1):e===m?f=this._createPagerNavButton(this.pagePrevText,a-1,a>1):e===n?f=this._createPagerNavButton(this.pageNextText,a+1,c>a):e===o?f=this._createPagerNavButton(this.pageLastText,c,c>a):e===p?f=a:e===q?f=c:e===r&&(f=d),b.isArray(f)?f.concat([" "]):[f," "]},this))},_createPages:function(){var a=this._pagesCount(),b=this.pageButtonCount,c=this._firstDisplayingPage,d=[];c>1&&d.push(this._createPagerPageNavButton(this.pageNavigatorPrevText,this.showPrevPages));for(var e=0,f=c;b>e&&a>=f;e++,f++)d.push(f===this.pageIndex?this._createPagerCurrentPage():this._createPagerPage(f));return a>c+b-1&&d.push(this._createPagerPageNavButton(this.pageNavigatorNextText,this.showNextPages)),d},_createPagerNavButton:function(a,c,d){return this._createPagerButton(a,this.pagerNavButtonClass+(d?"":" "+this.pagerNavButtonInactiveClass),d?function(){this.openPage(c)}:b.noop)},_createPagerPageNavButton:function(a,b){return this._createPagerButton(a,this.pagerNavButtonClass,b)},_createPagerPage:function(a){return this._createPagerButton(a,this.pageClass,function(){this.openPage(a)})},_createPagerButton:function(a,c,d){var e=b("<a>").attr("href",s).html(a).on("click",b.proxy(d,this));return b("<span>").addClass(c).append(e)},_createPagerCurrentPage:function(){return b("<span>").addClass(this.pageClass).addClass(this.currentPageClass).text(this.pageIndex)},_refreshSize:function(){this._refreshHeight(),this._refreshWidth()},_refreshWidth:function(){var a="auto"===this.width?this._getAutoWidth():this.width;this._container.width(a)},_getAutoWidth:function(){var a=this._headerGrid,b=this._header;a.width("auto");var c=a.outerWidth(),d=b.outerWidth()-b.innerWidth();return a.width(""),c+d},_scrollBarWidth:function(){var a;return function(){if(a===c){var d=b("<div style='width:50px;height:50px;overflow:hidden;position:absolute;top:-10000px;left:-10000px;'></div>"),e=b("<div style='height:100px;'></div>");d.append(e).appendTo("body");var f=e.innerWidth();d.css("overflow-y","auto");var g=e.innerWidth();d.remove(),a=f-g}return a}}(),_refreshHeight:function(){var a,b=this._container,c=this._pagerContainer,d=this.height;b.height(d),"auto"!==d&&(d=b.height(),a=this._header.outerHeight(!0),c.parents(b).length&&(a+=c.outerHeight(!0)),this._body.outerHeight(d-a))},showPrevPages:function(){var a=this._firstDisplayingPage,b=this.pageButtonCount;this._firstDisplayingPage=a>b?a-b:1,this._refreshPager()},showNextPages:function(){var a=this._firstDisplayingPage,b=this.pageButtonCount,c=this._pagesCount();this._firstDisplayingPage=a+2*b>c?c-b+1:a+b,this._refreshPager()},openPage:function(a){1>a||a>this._pagesCount()||(this._setPage(a),this._loadStrategy.openPage(a))},_setPage:function(a){var b=this._firstDisplayingPage,c=this.pageButtonCount;this.pageIndex=a,b>a&&(this._firstDisplayingPage=a),a>b+c-1&&(this._firstDisplayingPage=a-c+1),this._callEventHandler(this.onPageChanged,{pageIndex:a})},_controllerCall:function(a,c,d,e){if(d)return b.Deferred().reject().promise();this._showLoading();var f=this._controller;if(!f||!f[a])throw Error("controller has no method '"+a+"'");return u(f[a](c)).done(b.proxy(e,this)).fail(b.proxy(this._errorHandler,this)).always(b.proxy(this._hideLoading,this))},_errorHandler:function(){this._callEventHandler(this.onError,{args:b.makeArray(arguments)})},_showLoading:function(){this.loadIndication&&(clearTimeout(this._loadingTimer),this._loadingTimer=setTimeout(b.proxy(function(){this._loadIndicator.show()},this),this.loadIndicationDelay))},_hideLoading:function(){this.loadIndication&&(clearTimeout(this._loadingTimer),this._loadIndicator.hide())},search:function(a){return this._resetSorting(),this._resetPager(),this.loadData(a)},loadData:function(a){a=a||(this.filtering?this.getFilter():{}),b.extend(a,this._loadStrategy.loadParams(),this._sortingParams());var c=this._callEventHandler(this.onDataLoading,{filter:a});return this._controllerCall("loadData",a,c.cancel,function(a){a&&(this._loadStrategy.finishLoad(a),this._callEventHandler(this.onDataLoaded,{data:a}))})},getFilter:function(){var a={};return this._eachField(function(b){b.filtering&&this._setItemFieldValue(a,b,b.filterValue())}),a},_sortingParams:function(){return this.sorting&&this._sortField?{sortField:this._sortField.name,sortOrder:this._sortOrder}:{}},getSorting:function(){var a=this._sortingParams();return{field:a.sortField,order:a.sortOrder}},clearFilter:function(){var a=this._createFilterRow();return this._filterRow.replaceWith(a),this._filterRow=a,this.search()},insertItem:function(a){var c=a||this._getValidatedInsertItem();if(!c)return b.Deferred().reject().promise();var d=this._callEventHandler(this.onItemInserting,{item:c});return this._controllerCall("insertItem",c,d.cancel,function(a){a=a||c,this._loadStrategy.finishInsert(a),this._callEventHandler(this.onItemInserted,{item:a})})},_getValidatedInsertItem:function(){var a=this._getInsertItem();return this._validateItem(a,this._insertRow)?a:null},_getInsertItem:function(){var a={};return this._eachField(function(b){b.inserting&&this._setItemFieldValue(a,b,b.insertValue())}),a},_validateItem:function(a,c){var d=[],e={item:a,itemIndex:this._rowIndex(c),row:c};if(this._eachField(function(f){if(f.validate&&(c!==this._insertRow||f.inserting)&&(c!==this._getEditRow()||f.editing)){var g=this._getItemFieldValue(a,f),h=this._validation.validate(b.extend({value:g,rules:f.validate},e));this._setCellValidity(c.children().eq(this._visibleFieldIndex(f)),h),h.length&&d.push.apply(d,b.map(h,function(a){return{field:f,message:a}}))}}),!d.length)return!0;var f=b.extend({errors:d},e);return this._callEventHandler(this.onItemInvalid,f),this.invalidNotify(f),!1},_setCellValidity:function(a,b){a.toggleClass(this.invalidClass,!!b.length).attr("title",b.join("\n"))},clearInsert:function(){var a=this._createInsertRow();this._insertRow.replaceWith(a),this._insertRow=a,this.refresh()},editItem:function(a){var b=this.rowByItem(a);b.length&&this._editRow(b)},rowByItem:function(a){return a.jquery||a.nodeType?b(a):this._content.find("tr").filter(function(){return b.data(this,g)===a})},_editRow:function(a){if(this.editing){var b=a.data(g),c=this._callEventHandler(this.onItemEditing,{row:a,item:b,itemIndex:this._itemIndex(b)});if(!c.cancel){this._editingRow&&this.cancelEdit();var d=this._createEditRow(b);this._editingRow=a,a.hide(),d.insertBefore(a),a.data(h,d)}}},_createEditRow:function(a){if(b.isFunction(this.editRowRenderer))return b(this.renderTemplate(this.editRowRenderer,this,{item:a,itemIndex:this._itemIndex(a)}));var c=b("<tr>").addClass(this.editRowClass);return this._eachField(function(b){var d=this._getItemFieldValue(a,b);this._prepareCell("<td>",b,"editcss").append(this.renderTemplate(b.editTemplate||"",b,{value:d,item:a})).appendTo(c)}),c},updateItem:function(a,b){1===arguments.length&&(b=a);var c=a?this.rowByItem(a):this._editingRow;return(b=b||this._getValidatedEditedItem())?this._updateRow(c,b):void 0},_getValidatedEditedItem:function(){var a=this._getEditedItem();return this._validateItem(a,this._getEditRow())?a:null},_updateRow:function(a,c){var d=a.data(g),e=this._itemIndex(d),f=b.extend(!0,{},d,c),h=this._callEventHandler(this.onItemUpdating,{row:a,item:f,itemIndex:e,previousItem:d});return this._controllerCall("updateItem",f,h.cancel,function(g){var h=b.extend(!0,{},d);f=g||b.extend(!0,d,c);var i=this._finishUpdate(a,f,e);this._callEventHandler(this.onItemUpdated,{row:i,item:f,itemIndex:e,previousItem:h})})},_rowIndex:function(a){return this._content.children().index(b(a))},_itemIndex:function(a){return b.inArray(a,this.data)},_finishUpdate:function(a,b,c){this.cancelEdit(),this.data[c]=b;var d=this._createRow(b,c);return a.replaceWith(d),d},_getEditedItem:function(){var a={};return this._eachField(function(b){b.editing&&this._setItemFieldValue(a,b,b.editValue())}),a},cancelEdit:function(){this._editingRow&&(this._getEditRow().remove(),this._editingRow.show(),this._editingRow=null)},_getEditRow:function(){return this._editingRow&&this._editingRow.data(h)},deleteItem:function(b){var c=this.rowByItem(b);if(c.length&&(!this.confirmDeleting||a.confirm(t(this.deleteConfirm,this,c.data(g)))))return this._deleteRow(c)},_deleteRow:function(a){var b=a.data(g),c=this._itemIndex(b),d=this._callEventHandler(this.onItemDeleting,{row:a,item:b,itemIndex:c});return this._controllerCall("deleteItem",b,d.cancel,function(){this._loadStrategy.finishDelete(b,c),this._callEventHandler(this.onItemDeleted,{row:a,item:b,itemIndex:c})})}},b.fn.jsGrid=function(a){var e=b.makeArray(arguments),g=e.slice(1),h=this;return this.each(function(){var e,i=b(this),j=i.data(f);if(j)if("string"==typeof a){if(e=j[a].apply(j,g),e!==c&&e!==j)return h=e,!1}else j._detachWindowResizeCallback(),j._init(a),j.render();else new d(i,a)}),h};var w={},x=function(a){var c;b.isPlainObject(a)?c=d.prototype:(c=w[a].prototype,a=arguments[1]||{}),b.extend(c,a)},y={},z=function(a){var c=b.isPlainObject(a)?a:y[a];if(!c)throw Error("unknown locale "+a);A(jsGrid,c)},A=function(a,c){b.each(c,function(c,d){return b.isPlainObject(d)?void A(a[c]||a[c[0].toUpperCase()+c.slice(1)],d):void(a.hasOwnProperty(c)?a[c]=d:a.prototype[c]=d)})};a.jsGrid={Grid:d,fields:w,setDefaults:x,locales:y,locale:z,version:"1.5.3"}}(window,jQuery),function(a,b){function c(a){this._init(a)}c.prototype={container:"body",message:"Loading...",shading:!0,zIndex:1e3,shaderClass:"jsgrid-load-shader",loadPanelClass:"jsgrid-load-panel",_init:function(a){b.extend(!0,this,a),this._initContainer(),this._initShader(),this._initLoadPanel()},_initContainer:function(){this._container=b(this.container)},_initShader:function(){this.shading&&(this._shader=b("<div>").addClass(this.shaderClass).hide().css({position:"absolute",top:0,right:0,bottom:0,left:0,zIndex:this.zIndex}).appendTo(this._container))},_initLoadPanel:function(){this._loadPanel=b("<div>").addClass(this.loadPanelClass).text(this.message).hide().css({position:"absolute",top:"50%",left:"50%",zIndex:this.zIndex}).appendTo(this._container)},show:function(){var a=this._loadPanel.show(),b=a.outerWidth(),c=a.outerHeight();a.css({marginTop:-c/2,marginLeft:-b/2}),this._shader.show()},hide:function(){this._loadPanel.hide(),this._shader.hide()}},a.LoadIndicator=c}(jsGrid,jQuery),function(a,b){function c(a){this._grid=a}function d(a){this._grid=a,this._itemsCount=0}c.prototype={firstDisplayIndex:function(){var a=this._grid;return a.option("paging")?(a.option("pageIndex")-1)*a.option("pageSize"):0},lastDisplayIndex:function(){var a=this._grid,b=a.option("data").length;return a.option("paging")?Math.min(a.option("pageIndex")*a.option("pageSize"),b):b},itemsCount:function(){return this._grid.option("data").length},openPage:function(){this._grid.refresh()},loadParams:function(){return{}},sort:function(){return this._grid._sortData(),this._grid.refresh(),b.Deferred().resolve().promise()},reset:function(){return this._grid.refresh(),b.Deferred().resolve().promise()},finishLoad:function(a){this._grid.option("data",a)},finishInsert:function(a){var b=this._grid;b.option("data").push(a),b.refresh()},finishDelete:function(a,b){var c=this._grid;c.option("data").splice(b,1),c.reset()}},d.prototype={firstDisplayIndex:function(){return 0},lastDisplayIndex:function(){return this._grid.option("data").length},itemsCount:function(){return this._itemsCount},openPage:function(){this._grid.loadData()},loadParams:function(){var a=this._grid;return{pageIndex:a.option("pageIndex"),pageSize:a.option("pageSize")}},reset:function(){return this._grid.loadData()},sort:function(){return this._grid.loadData()},finishLoad:function(a){this._itemsCount=a.itemsCount,this._grid.option("data",a.data)},finishInsert:function(){this._grid.search()},finishDelete:function(){this._grid.search()}},a.loadStrategies={DirectLoadingStrategy:c,PageLoadingStrategy:d}}(jsGrid,jQuery),function(a){var b=function(a){return"undefined"!=typeof a&&null!==a},c={string:function(a,c){return b(a)||b(c)?b(a)?b(c)?(""+a).localeCompare(""+c):1:-1:0},number:function(a,b){return a-b},date:function(a,b){return a-b},numberAsString:function(a,b){return parseFloat(a)-parseFloat(b)}};a.sortStrategies=c}(jsGrid,jQuery),function(a,b,c){function d(a){this._init(a)}d.prototype={_init:function(a){b.extend(!0,this,a)},validate:function(a){var c=[];return b.each(this._normalizeRules(a.rules),function(d,e){if(!e.validator(a.value,a.item,e.param)){var f=b.isFunction(e.message)?e.message(a.value,a.item):e.message;c.push(f)}}),c},_normalizeRules:function(a){return b.isArray(a)||(a=[a]),b.map(a,b.proxy(function(a){return this._normalizeRule(a)},this))},_normalizeRule:function(a){if("string"==typeof a&&(a={validator:a}),b.isFunction(a)&&(a={validator:a}),!b.isPlainObject(a))throw Error("wrong validation config specified");return a=b.extend({},a),b.isFunction(a.validator)?a:this._applyNamedValidator(a,a.validator)},_applyNamedValidator:function(a,c){delete a.validator;var d=e[c];if(!d)throw Error('unknown validator "'+c+'"');return b.isFunction(d)&&(d={validator:d}),b.extend({},d,a)}},a.Validation=d;var e={required:{message:"Field is required",validator:function(a){return a!==c&&null!==a&&""!==a}},rangeLength:{message:"Field value length is out of the defined range",validator:function(a,b,c){return a.length>=c[0]&&a.length<=c[1]}},minLength:{message:"Field value is too short",validator:function(a,b,c){return a.length>=c}},maxLength:{message:"Field value is too long",validator:function(a,b,c){return a.length<=c}},pattern:{message:"Field value is not matching the defined pattern",validator:function(a,b,c){return"string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a)}},range:{message:"Field value is out of the defined range",validator:function(a,b,c){return a>=c[0]&&a<=c[1]}},min:{message:"Field value is too small",validator:function(a,b,c){return a>=c}},max:{message:"Field value is too large",validator:function(a,b,c){return c>=a}}};a.validators=e}(jsGrid,jQuery),function(a,b,c){function d(a){b.extend(!0,this,a),this.sortingFunc=this._getSortingFunc()}d.prototype={name:"",title:null,css:"",align:"",width:100,visible:!0,filtering:!0,inserting:!0,editing:!0,sorting:!0,sorter:"string",headerTemplate:function(){return this.title===c||null===this.title?this.name:this.title},itemTemplate:function(a){return a},filterTemplate:function(){return""},insertTemplate:function(){return""},editTemplate:function(a,b){return this._value=a,this.itemTemplate(a,b)},filterValue:function(){return""},insertValue:function(){return""},editValue:function(){return this._value},_getSortingFunc:function(){var c=this.sorter;if(b.isFunction(c))return c;if("string"==typeof c)return a.sortStrategies[c];throw Error('wrong sorter for the field "'+this.name+'"!')}},a.Field=d}(jsGrid,jQuery),function(a,b){function c(a){d.call(this,a)}var d=a.Field;c.prototype=new d({autosearch:!0,readOnly:!1,filterTemplate:function(){if(!this.filtering)return"";var a=this._grid,b=this.filterControl=this._createTextBox();return this.autosearch&&b.on("keypress",function(b){13===b.which&&(a.search(),b.preventDefault())}),b},insertTemplate:function(){return this.inserting?this.insertControl=this._createTextBox():""},editTemplate:function(a){if(!this.editing)return this.itemTemplate.apply(this,arguments);var b=this.editControl=this._createTextBox();return b.val(a),b},filterValue:function(){return this.filterControl.val()},insertValue:function(){return this.insertControl.val()},editValue:function(){return this.editControl.val()},_createTextBox:function(){return b("<input>").attr("type","text").prop("readonly",!!this.readOnly)}}),a.fields.text=a.TextField=c}(jsGrid,jQuery),function(a,b,c){function d(a){e.call(this,a)}var e=a.TextField;d.prototype=new e({sorter:"number",align:"right",readOnly:!1,filterValue:function(){return this.filterControl.val()?parseInt(this.filterControl.val()||0,10):c},insertValue:function(){return this.insertControl.val()?parseInt(this.insertControl.val()||0,10):c},editValue:function(){return this.editControl.val()?parseInt(this.editControl.val()||0,10):c},_createTextBox:function(){return b("<input>").attr("type","number").prop("readonly",!!this.readOnly)}}),a.fields.number=a.NumberField=d}(jsGrid,jQuery),function(a,b){function c(a){d.call(this,a)}var d=a.TextField;c.prototype=new d({insertTemplate:function(){return this.inserting?this.insertControl=this._createTextArea():""},editTemplate:function(a){if(!this.editing)return this.itemTemplate.apply(this,arguments);var b=this.editControl=this._createTextArea();return b.val(a),b},_createTextArea:function(){return b("<textarea>").prop("readonly",!!this.readOnly)}}),a.fields.textarea=a.TextAreaField=c}(jsGrid,jQuery),function(a,b,c){function d(a){if(this.items=[],this.selectedIndex=-1,this.valueField="",this.textField="",a.valueField&&a.items.length){var b=a.items[0][a.valueField];this.valueType=typeof b===f?f:g}this.sorter=this.valueType,e.call(this,a)}var e=a.NumberField,f="number",g="string";d.prototype=new e({align:"center",valueType:f,itemTemplate:function(a){var d,e=this.items,f=this.valueField,g=this.textField;d=f?b.grep(e,function(b){return b[f]===a})[0]||{}:e[a];var h=g?d[g]:d;return h===c||null===h?"":h},filterTemplate:function(){if(!this.filtering)return"";var a=this._grid,b=this.filterControl=this._createSelect();return this.autosearch&&b.on("change",function(){a.search()}),b},insertTemplate:function(){return this.inserting?this.insertControl=this._createSelect():""},editTemplate:function(a){if(!this.editing)return this.itemTemplate.apply(this,arguments);var b=this.editControl=this._createSelect();return a!==c&&b.val(a),b},filterValue:function(){var a=this.filterControl.val();return this.valueType===f?parseInt(a||0,10):a},insertValue:function(){var a=this.insertControl.val();return this.valueType===f?parseInt(a||0,10):a},editValue:function(){var a=this.editControl.val();return this.valueType===f?parseInt(a||0,10):a},_createSelect:function(){var a=b("<select>"),c=this.valueField,d=this.textField,e=this.selectedIndex;return b.each(this.items,function(f,g){var h=c?g[c]:f,i=d?g[d]:g,j=b("<option>").attr("value",h).text(i).appendTo(a);j.prop("selected",e===f)}),a.prop("disabled",!!this.readOnly),a}}),a.fields.select=a.SelectField=d}(jsGrid,jQuery),function(a,b,c){function d(a){e.call(this,a)}var e=a.Field;d.prototype=new e({sorter:"number",align:"center",autosearch:!0,itemTemplate:function(a){return this._createCheckbox().prop({checked:a,disabled:!0})},filterTemplate:function(){if(!this.filtering)return"";var a=this._grid,c=this.filterControl=this._createCheckbox();return c.prop({readOnly:!0,indeterminate:!0}),c.on("click",function(){var a=b(this);
+a.prop("readOnly")?a.prop({checked:!1,readOnly:!1}):a.prop("checked")||a.prop({readOnly:!0,indeterminate:!0})}),this.autosearch&&c.on("click",function(){a.search()}),c},insertTemplate:function(){return this.inserting?this.insertControl=this._createCheckbox():""},editTemplate:function(a){if(!this.editing)return this.itemTemplate.apply(this,arguments);var b=this.editControl=this._createCheckbox();return b.prop("checked",a),b},filterValue:function(){return this.filterControl.get(0).indeterminate?c:this.filterControl.is(":checked")},insertValue:function(){return this.insertControl.is(":checked")},editValue:function(){return this.editControl.is(":checked")},_createCheckbox:function(){return b("<input>").attr("type","checkbox")}}),a.fields.checkbox=a.CheckboxField=d}(jsGrid,jQuery),function(a,b){function c(a){d.call(this,a),this._configInitialized=!1}var d=a.Field;c.prototype=new d({css:"jsgrid-control-field",align:"center",width:50,filtering:!1,inserting:!1,editing:!1,sorting:!1,buttonClass:"jsgrid-button",modeButtonClass:"jsgrid-mode-button",modeOnButtonClass:"jsgrid-mode-on-button",searchModeButtonClass:"jsgrid-search-mode-button",insertModeButtonClass:"jsgrid-insert-mode-button",editButtonClass:"jsgrid-edit-button",deleteButtonClass:"jsgrid-delete-button",searchButtonClass:"jsgrid-search-button",clearFilterButtonClass:"jsgrid-clear-filter-button",insertButtonClass:"jsgrid-insert-button",updateButtonClass:"jsgrid-update-button",cancelEditButtonClass:"jsgrid-cancel-edit-button",searchModeButtonTooltip:"Switch to searching",insertModeButtonTooltip:"Switch to inserting",editButtonTooltip:"Edit",deleteButtonTooltip:"Delete",searchButtonTooltip:"Search",clearFilterButtonTooltip:"Clear filter",insertButtonTooltip:"Insert",updateButtonTooltip:"Update",cancelEditButtonTooltip:"Cancel edit",editButton:!0,deleteButton:!0,clearFilterButton:!0,modeSwitchButton:!0,_initConfig:function(){this._hasFiltering=this._grid.filtering,this._hasInserting=this._grid.inserting,this._hasInserting&&this.modeSwitchButton&&(this._grid.inserting=!1),this._configInitialized=!0},headerTemplate:function(){this._configInitialized||this._initConfig();var a=this._hasFiltering,b=this._hasInserting;return this.modeSwitchButton&&(a||b)?a&&!b?this._createFilterSwitchButton():b&&!a?this._createInsertSwitchButton():this._createModeSwitchButton():""},itemTemplate:function(a,c){var d=b([]);return this.editButton&&(d=d.add(this._createEditButton(c))),this.deleteButton&&(d=d.add(this._createDeleteButton(c))),d},filterTemplate:function(){var a=this._createSearchButton();return this.clearFilterButton?a.add(this._createClearFilterButton()):a},insertTemplate:function(){return this._createInsertButton()},editTemplate:function(){return this._createUpdateButton().add(this._createCancelEditButton())},_createFilterSwitchButton:function(){return this._createOnOffSwitchButton("filtering",this.searchModeButtonClass,!0)},_createInsertSwitchButton:function(){return this._createOnOffSwitchButton("inserting",this.insertModeButtonClass,!1)},_createOnOffSwitchButton:function(a,c,d){var e=d,f=b.proxy(function(){g.toggleClass(this.modeOnButtonClass,e)},this),g=this._createGridButton(this.modeButtonClass+" "+c,"",function(b){e=!e,b.option(a,e),f()});return f(),g},_createModeSwitchButton:function(){var a=!1,c=b.proxy(function(){d.attr("title",a?this.searchModeButtonTooltip:this.insertModeButtonTooltip).toggleClass(this.insertModeButtonClass,!a).toggleClass(this.searchModeButtonClass,a)},this),d=this._createGridButton(this.modeButtonClass,"",function(b){a=!a,b.option("inserting",a),b.option("filtering",!a),c()});return c(),d},_createEditButton:function(a){return this._createGridButton(this.editButtonClass,this.editButtonTooltip,function(b,c){b.editItem(a),c.stopPropagation()})},_createDeleteButton:function(a){return this._createGridButton(this.deleteButtonClass,this.deleteButtonTooltip,function(b,c){b.deleteItem(a),c.stopPropagation()})},_createSearchButton:function(){return this._createGridButton(this.searchButtonClass,this.searchButtonTooltip,function(a){a.search()})},_createClearFilterButton:function(){return this._createGridButton(this.clearFilterButtonClass,this.clearFilterButtonTooltip,function(a){a.clearFilter()})},_createInsertButton:function(){return this._createGridButton(this.insertButtonClass,this.insertButtonTooltip,function(a){a.insertItem().done(function(){a.clearInsert()})})},_createUpdateButton:function(){return this._createGridButton(this.updateButtonClass,this.updateButtonTooltip,function(a,b){a.updateItem(),b.stopPropagation()})},_createCancelEditButton:function(){return this._createGridButton(this.cancelEditButtonClass,this.cancelEditButtonTooltip,function(a,b){a.cancelEdit(),b.stopPropagation()})},_createGridButton:function(a,c,d){var e=this._grid;return b("<input>").addClass(this.buttonClass).addClass(a).attr({type:"button",title:c}).on("click",function(a){d(e,a)})},editValue:function(){return""}}),a.fields.control=a.ControlField=c}(jsGrid,jQuery); \ No newline at end of file