jsxgrid 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +2329 -0
  3. package/dist/fields/jsgrid.field.XDateTimeField.min.js +6 -0
  4. package/dist/fields/jsgrid.field.XRowSelectField.min.js +6 -0
  5. package/dist/fields/jsgrid.field.Xcheckbox.min.js +6 -0
  6. package/dist/fields/jsgrid.field.XimgField.min.js +6 -0
  7. package/dist/fields/jsgrid.field.Xjsoneditor.min.js +6 -0
  8. package/dist/fields/jsgrid.field.Xselect.min.js +6 -0
  9. package/dist/fields/jsgrid.field.Xtextarea.min.js +6 -0
  10. package/dist/fields/lib/jsGridSummaryPlugin.min.js +6 -0
  11. package/dist/fields/lib/jsgrid.popup.basic.min.js +6 -0
  12. package/dist/i18n/jsgrid-Ko.js +46 -0
  13. package/dist/i18n/jsgrid-cs.js +46 -0
  14. package/dist/i18n/jsgrid-de.js +46 -0
  15. package/dist/i18n/jsgrid-el.js +46 -0
  16. package/dist/i18n/jsgrid-es.js +46 -0
  17. package/dist/i18n/jsgrid-fa.js +46 -0
  18. package/dist/i18n/jsgrid-fr.js +47 -0
  19. package/dist/i18n/jsgrid-he.js +46 -0
  20. package/dist/i18n/jsgrid-it.js +47 -0
  21. package/dist/i18n/jsgrid-ja.js +46 -0
  22. package/dist/i18n/jsgrid-ka.js +46 -0
  23. package/dist/i18n/jsgrid-lt.js +47 -0
  24. package/dist/i18n/jsgrid-pl.js +62 -0
  25. package/dist/i18n/jsgrid-pt-br.js +46 -0
  26. package/dist/i18n/jsgrid-pt.js +46 -0
  27. package/dist/i18n/jsgrid-ru.js +47 -0
  28. package/dist/i18n/jsgrid-tr.js +47 -0
  29. package/dist/i18n/jsgrid-zh-cn.js +46 -0
  30. package/dist/i18n/jsgrid-zh-tw.js +46 -0
  31. package/dist/icons-2x.png +0 -0
  32. package/dist/icons.png +0 -0
  33. package/dist/jsxgrid-fields.js +606 -0
  34. package/dist/jsxgrid-fields.min.js +6 -0
  35. package/dist/jsxgrid-theme.css +258 -0
  36. package/dist/jsxgrid-theme.min.css +1 -0
  37. package/dist/jsxgrid-xfields.js +979 -0
  38. package/dist/jsxgrid-xfields.min.js +6 -0
  39. package/dist/jsxgrid.css +126 -0
  40. package/dist/jsxgrid.js +2137 -0
  41. package/dist/jsxgrid.min.css +1 -0
  42. package/dist/jsxgrid.min.js +6 -0
  43. package/package.json +57 -0
  44. package/src/fields/jsgrid.field.XDateTimeField.js +122 -0
  45. package/src/fields/jsgrid.field.XRowSelectField.js +62 -0
  46. package/src/fields/jsgrid.field.Xcheckbox.js +108 -0
  47. package/src/fields/jsgrid.field.XimgField.js +99 -0
  48. package/src/fields/jsgrid.field.Xjsoneditor.js +165 -0
  49. package/src/fields/jsgrid.field.Xselect.js +176 -0
  50. package/src/fields/jsgrid.field.Xtextarea.js +97 -0
  51. package/src/fields/jsgrid.field.checkbox.js +97 -0
  52. package/src/fields/jsgrid.field.control.js +224 -0
  53. package/src/fields/jsgrid.field.number.js +41 -0
  54. package/src/fields/jsgrid.field.select.js +130 -0
  55. package/src/fields/jsgrid.field.text.js +69 -0
  56. package/src/fields/jsgrid.field.textarea.js +34 -0
  57. package/src/i18n/Ko.js +46 -0
  58. package/src/i18n/cs.js +46 -0
  59. package/src/i18n/de.js +46 -0
  60. package/src/i18n/el.js +46 -0
  61. package/src/i18n/es.js +46 -0
  62. package/src/i18n/fa.js +46 -0
  63. package/src/i18n/fr.js +47 -0
  64. package/src/i18n/he.js +46 -0
  65. package/src/i18n/it.js +47 -0
  66. package/src/i18n/ja.js +46 -0
  67. package/src/i18n/ka.js +46 -0
  68. package/src/i18n/lt.js +47 -0
  69. package/src/i18n/pl.js +62 -0
  70. package/src/i18n/pt-br.js +46 -0
  71. package/src/i18n/pt.js +46 -0
  72. package/src/i18n/ru.js +47 -0
  73. package/src/i18n/tr.js +47 -0
  74. package/src/i18n/zh-cn.js +46 -0
  75. package/src/i18n/zh-tw.js +46 -0
  76. package/src/jsgrid.core.js +1655 -0
  77. package/src/jsgrid.field.js +74 -0
  78. package/src/jsgrid.load-indicator.js +82 -0
  79. package/src/jsgrid.load-strategies.js +131 -0
  80. package/src/jsgrid.sort-strategies.js +49 -0
  81. package/src/jsgrid.validation.js +135 -0
  82. package/src/lib/jsGridSummaryPlugin.js +37 -0
  83. package/src/lib/jsgrid.popup.basic.js +107 -0
package/README.md ADDED
@@ -0,0 +1,2329 @@
1
+ # jsxgrid
2
+
3
+ **jsxgrid** is a lightweight client-side data grid control based on jQuery.
4
+ It supports basic grid operations like inserting, filtering, editing, deleting, paging, sorting, and validating,
5
+ and is tunable and allows to customize appearance and components. On top of that base, it ships with a set of
6
+ extra fields built in: avatars, a JSON editor, a collapsible textarea, a datetime picker (with range filtering),
7
+ a row-selection column with a bulk action, and a computed summary footer.
8
+
9
+ ## Credits
10
+
11
+ jsxgrid is a fork of [jsGrid](https://github.com/tabalinas/jsgrid) by Artem Tabalin, which provided the
12
+ original grid engine and design this project is built on. jsGrid saw no releases after 2016; jsxgrid
13
+ continues it — cherry-picked fixes from PRs that never got merged upstream (memory leak on grid destroy,
14
+ a CSP-unsafe inline style, a couple of correctness fixes), merges in a set of extra fields that used to be
15
+ a separate package (xfields), and is maintained going forward by Mikhail Kremza.
16
+
17
+ ## Table of contents
18
+
19
+ * [Demos](#demos)
20
+ * [Installation](#installation)
21
+ * [Basic Usage](#basic-usage)
22
+ * [Configuration](#configuration)
23
+ * [Grid Fields](#grid-fields)
24
+ * [Methods](#methods)
25
+ * [Callbacks](#callbacks)
26
+ * [Grid Controller](#grid-controller)
27
+ * [Validation](#validation)
28
+ * [Localization](#localization)
29
+ * [Sorting Strategies](#sorting-strategies)
30
+ * [Load Strategies](#load-strategies)
31
+ * [Load Indication](#load-indication)
32
+ * [Requirement](#requirement)
33
+ * [Compatibility](#compatibility)
34
+
35
+
36
+ ## Demos
37
+
38
+ See the [demos/](demos/) folder in this repo — `demos/xfields.html` in particular exercises every extra
39
+ field together on one grid.
40
+
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ npm install jsxgrid
46
+ ```
47
+
48
+ or via Composer, as an npm-mirrored asset:
49
+
50
+ ```bash
51
+ composer require npm-asset/jsxgrid
52
+ ```
53
+
54
+ The build is split into independent pieces - include only what you actually use:
55
+
56
+ - `dist/jsxgrid.js` (or `.min.js`) - the engine. Always required.
57
+ - `dist/jsxgrid-fields.js` - the native field types (`text`, `number`, `select`, `checkbox`, `textarea`, `control`). Skip this if you only use the extra fields below.
58
+ - `dist/jsxgrid-xfields.js` - the extra fields (`Xcheckbox`, `Xselect`, ...). Does *not* need `jsxgrid-fields.js` - every extra field extends the engine's base `Field` class directly, not the native field types.
59
+ - `dist/jsxgrid.css` and `dist/jsxgrid-theme.css` for styling.
60
+
61
+ Individual fields (native or extra) can also be loaded one at a time from `dist/fields/` instead of pulling in a whole bundle.
62
+
63
+
64
+ ## Basic Usage
65
+
66
+ Ensure that jQuery (version 3.0 or later) is included.
67
+
68
+ Include `jsgrid.min.js`, `jsgrid-theme.min.css`, and `jsgrid.min.css` files into the web page.
69
+
70
+ Create grid applying jQuery plugin `jsGrid` with grid config as follows:
71
+
72
+ ```javascript
73
+
74
+ $("#jsGrid").jsGrid({
75
+ width: "100%",
76
+ height: "400px",
77
+
78
+ filtering: true,
79
+ editing: true,
80
+ sorting: true,
81
+ paging: true,
82
+
83
+ data: db.clients,
84
+
85
+ fields: [
86
+ { name: "Name", type: "text", width: 150 },
87
+ { name: "Age", type: "number", width: 50 },
88
+ { name: "Address", type: "text", width: 200 },
89
+ { name: "Country", type: "select", items: db.countries, valueField: "Id", textField: "Name" },
90
+ { name: "Married", type: "checkbox", title: "Is Married", sorting: false },
91
+ { type: "control" }
92
+ ]
93
+ });
94
+
95
+ ```
96
+
97
+
98
+ ## Configuration
99
+
100
+ The config object may contain following options (default values are specified below):
101
+
102
+ ```javascript
103
+
104
+ {
105
+ fields: [],
106
+ data: [],
107
+
108
+ autoload: false,
109
+ controller: {
110
+ loadData: $.noop,
111
+ insertItem: $.noop,
112
+ updateItem: $.noop,
113
+ deleteItem: $.noop
114
+ },
115
+
116
+ width: "auto",
117
+ height: "auto",
118
+
119
+ heading: true,
120
+ filtering: false,
121
+ inserting: false,
122
+ editing: false,
123
+ selecting: true,
124
+ sorting: false,
125
+ paging: false,
126
+ pageLoading: false,
127
+
128
+ insertRowLocation: "bottom",
129
+
130
+ rowClass: function(item, itemIndex) { ... },
131
+ rowClick: function(args) { ... },
132
+ rowDoubleClick: function(args) { ... },
133
+
134
+ noDataContent: "Not found",
135
+
136
+ confirmDeleting: true,
137
+ deleteConfirm: "Are you sure?",
138
+
139
+ pagerContainer: null,
140
+ pageIndex: 1,
141
+ pageSize: 20,
142
+ pageButtonCount: 15,
143
+ pagerFormat: "Pages: {first} {prev} {pages} {next} {last}    {pageIndex} of {pageCount}",
144
+ pagePrevText: "Prev",
145
+ pageNextText: "Next",
146
+ pageFirstText: "First",
147
+ pageLastText: "Last",
148
+ pageNavigatorNextText: "...",
149
+ pageNavigatorPrevText: "...",
150
+
151
+ invalidNotify: function(args) { ... }
152
+ invalidMessage: "Invalid data entered!",
153
+
154
+ loadIndication: true,
155
+ loadIndicationDelay: 500,
156
+ loadMessage: "Please, wait...",
157
+ loadShading: true,
158
+ loadIndicator: function(config) { ... }
159
+ loadStrategy: function(config) { ... }
160
+
161
+ updateOnResize: true,
162
+
163
+ rowRenderer: null,
164
+ headerRowRenderer: null,
165
+ filterRowRenderer: null,
166
+ insertRowRenderer: null,
167
+ editRowRenderer: null,
168
+ pagerRenderer: null
169
+ }
170
+
171
+ ```
172
+
173
+ ### fields
174
+ An array of fields (columns) of the grid.
175
+
176
+ Each field has general options and specific options depending on field type.
177
+
178
+ General options peculiar to all field types:
179
+
180
+ ```javascript
181
+
182
+ {
183
+ type: "",
184
+ name: "",
185
+ title: "",
186
+ align: "",
187
+ width: 100,
188
+ visible: true,
189
+
190
+ css: "",
191
+ headercss: "",
192
+ filtercss: "",
193
+ insertcss: "",
194
+ editcss: "",
195
+
196
+ filtering: true,
197
+ inserting: true,
198
+ editing: true,
199
+ sorting: true,
200
+ sorter: "string",
201
+
202
+ headerTemplate: function() { ... },
203
+ itemTemplate: function(value, item) { ... },
204
+ filterTemplate: function() { ... },
205
+ insertTemplate: function() { ... },
206
+ editTemplate: function(value, item) { ... },
207
+
208
+ filterValue: function() { ... },
209
+ insertValue: function() { ... },
210
+ editValue: function() { ... },
211
+
212
+ cellRenderer: null,
213
+
214
+ validate: null
215
+ }
216
+
217
+ ```
218
+
219
+ - **type** is a string key of field (`"text"|"number"|"checkbox"|"select"|"textarea"|"control"`) in fields registry `jsGrid.fields` (the registry can be easily extended with custom field types).
220
+ - **name** is a property of data item associated with the column.
221
+ - **title** is a text to be displayed in the header of the column. If `title` is not specified, the `name` will be used instead.
222
+ - **align** is alignment of text in the cell. Accepts following values `"left"|"center"|"right"`.
223
+ - **width** is a width of the column.
224
+ - **visible** is a boolean specifying whether to show a column or not. (version added: 1.3)
225
+ - **css** is a string representing css classes to be attached to the table cell.
226
+ - **headercss** is a string representing css classes to be attached to the table header cell. If not specified, then **css** is attached instead.
227
+ - **filtercss** is a string representing css classes to be attached to the table filter row cell. If not specified, then **css** is attached instead.
228
+ - **insertcss** is a string representing css classes to be attached to the table insert row cell. If not specified, then **css** is attached instead.
229
+ - **editcss** is a string representing css classes to be attached to the table edit row cell. If not specified, then **css** is attached instead.
230
+ - **filtering** is a boolean specifying whether or not column has filtering (`filterTemplate()` is rendered and `filterValue()` is included in load filter object).
231
+ - **inserting** is a boolean specifying whether or not column has inserting (`insertTemplate()` is rendered and `insertValue()` is included in inserting item).
232
+ - **editing** is a boolean specifying whether or not column has editing (`editTemplate()` is rendered and `editValue()` is included in editing item).
233
+ - **sorting** is a boolean specifying whether or not column has sorting ability.
234
+ - **sorter** is a string or a function specifying how to sort item by the field. The string is a key of sorting strategy in the registry `jsGrid.sortStrategies` (the registry can be easily extended with custom sorting functions). Sorting function has the signature `function(value1, value2) { return -1|0|1; }`.
235
+ - **headerTemplate** is a function to create column header content. It should return markup as string, DomNode or jQueryElement.
236
+ - **itemTemplate** is a function to create cell content. It should return markup as string, DomNode or jQueryElement. The function signature is `function(value, item)`, where `value` is a value of column property of data item, and `item` is a row data item.
237
+ - **filterTemplate** is a function to create filter row cell content. It should return markup as string, DomNode or jQueryElement.
238
+ - **insertTemplate** is a function to create insert row cell content. It should return markup as string, DomNode or jQueryElement.
239
+ - **editTemplate** is a function to create cell content of editing row. It should return markup as string, DomNode or jQueryElement. The function signature is `function(value, item)`, where `value` is a value of column property of data item, and `item` is a row data item.
240
+ - **filterValue** is a function returning the value of filter property associated with the column.
241
+ - **insertValue** is a function returning the value of inserting item property associated with the column.
242
+ - **editValue** is a function returning the value of editing item property associated with the column.
243
+ - **cellRenderer** is a function to customize cell rendering. The function signature is `function(value, item)`, where `value` is a value of column property of data item, and `item` is a row data item. The function should return markup as a string, jQueryElement or DomNode representing table cell `td`.
244
+ - **validate** is a string as validate rule name or validation function or a validation configuration object or an array of validation configuration objects. Read more details about validation in the [Validation section](#validation).
245
+
246
+ Specific field options depends on concrete field type.
247
+ Read about build-in fields in [Grid Fields](#grid-fields) section.
248
+
249
+ ### data
250
+ An array of items to be displayed in the grid. The option should be used to provide static data. Use the `controller` option to provide non static data.
251
+
252
+ ### autoload (default `false`)
253
+ A boolean value specifying whether `controller.loadData` will be called when grid is rendered.
254
+
255
+ ### controller
256
+ An object or function returning an object with the following structure:
257
+
258
+ ```javascript
259
+
260
+ {
261
+ loadData: $.noop,
262
+ insertItem: $.noop,
263
+ updateItem: $.noop,
264
+ deleteItem: $.noop
265
+ }
266
+
267
+ ```
268
+
269
+ - **loadData** is a function returning an array of data or jQuery promise that will be resolved with an array of data (when `pageLoading` is `true` instead of object the structure `{ data: [items], itemsCount: [total items count] }` should be returned). Accepts filter parameter including current filter options and paging parameters when `pageLoading` is `true`.
270
+ - **insertItem** is a function returning inserted item or jQuery promise that will be resolved with inserted item. Accepts inserting item object.
271
+ - **updateItem** is a function returning updated item or jQuery promise that will be resolved with updated item. Accepts updating item object.
272
+ - **deleteItem** is a function deleting item. Returns jQuery promise that will be resolved when deletion is completed. Accepts deleting item object.
273
+
274
+ Read more about controller interface in [Grid Controller](#grid-controller) section.
275
+
276
+ ### width (default: `"auto"`)
277
+ Specifies the overall width of the grid.
278
+ Accepts all value types accepting by `jQuery.width`.
279
+
280
+ ### height (default: `"auto"`)
281
+ Specifies the overall height of the grid including the pager.
282
+ Accepts all value types accepting by `jQuery.height`.
283
+
284
+ ### heading (default: `true`)
285
+ A boolean value specifies whether to show grid header or not.
286
+
287
+ ### filtering (default: `false`)
288
+ A boolean value specifies whether to show filter row or not.
289
+
290
+ ### inserting (default: `false`)
291
+ A boolean value specifies whether to show inserting row or not.
292
+
293
+ ### editing (default: `false`)
294
+ A boolean value specifies whether editing is allowed.
295
+
296
+ ### selecting (default: `true`)
297
+ A boolean value specifies whether to highlight grid rows on hover.
298
+
299
+ ### sorting (default: `false`)
300
+ A boolean value specifies whether sorting is allowed.
301
+
302
+ ### paging (default: `false`)
303
+ A boolean value specifies whether data is displayed by pages.
304
+
305
+ ### pageLoading (default: `false`)
306
+ A boolean value specifies whether to load data by page.
307
+ When `pageLoading` is `true` the `loadData` method of controller accepts `filter` parameter with two additional properties `pageSize` and `pageIndex`.
308
+
309
+ ### insertRowLocation (default: `"bottom"`)
310
+ Specifies the location of an inserted row within the grid.
311
+ When `insertRowLocation` is `"bottom"` the new row will appear at the bottom of the grid. When set to `"top"`, the new row will appear at the top.
312
+
313
+ ### rowClass
314
+ A string or a function specifying row css classes.
315
+ A string contains classes separated with spaces.
316
+ A function has signature `function(item, itemIndex)`. It accepts the data item and index of the item. It should returns a string containing classes separated with spaces.
317
+
318
+ ### rowClick
319
+ A function handling row click. Accepts single argument with following structure:
320
+
321
+ ```javascript
322
+
323
+ {
324
+ item // data item
325
+ itemIndex // data item index
326
+ event // jQuery event
327
+ }
328
+
329
+ ```
330
+
331
+ By default `rowClick` performs row editing when `editing` is `true`.
332
+
333
+ ### rowDoubleClick
334
+ A function handling row double click. Accepts single argument with the following structure:
335
+
336
+ ```javascript
337
+
338
+ {
339
+ item // data item
340
+ itemIndex // data item index
341
+ event // jQuery event
342
+ }
343
+
344
+ ```
345
+
346
+ ### noDataContent (default `"Not found"`)
347
+ A string or a function returning a markup, jQueryElement or DomNode specifying the content to be displayed when `data` is an empty array.
348
+
349
+ ### confirmDeleting (default `true`)
350
+ A boolean value specifying whether to ask user to confirm item deletion.
351
+
352
+ ### deleteConfirm (default `"Are you sure?"`)
353
+ A string or a function returning string specifying delete confirmation message to be displayed to the user.
354
+ A function has the signature `function(item)` and accepts item to be deleted.
355
+
356
+ ### pagerContainer (default `null`)
357
+ A jQueryElement or DomNode to specify where to render a pager. Used for external pager rendering. When it is equal to `null`, the pager is rendered at the bottom of the grid.
358
+
359
+ ### pageIndex (default `1`)
360
+ An integer value specifying current page index. Applied only when `paging` is `true`.
361
+
362
+ ### pageSize (default `20`)
363
+ An integer value specifying the amount of items on the page. Applied only when `paging` is `true`.
364
+
365
+ ### pageButtonCount (default `15`)
366
+ An integer value specifying the maximum amount of page buttons to be displayed in the pager.
367
+
368
+ ### pagerFormat
369
+ A string specifying pager format.
370
+ The default value is `"Pages: {first} {prev} {pages} {next} {last}    {pageIndex} of {pageCount}"`
371
+
372
+ There are placeholders that can be used in the format:
373
+
374
+ ```javascript
375
+
376
+ {first} // link to first page
377
+ {prev} // link to previous page
378
+ {pages} // page links
379
+ {next} // link to next page
380
+ {last} // link to last page
381
+ {pageIndex} // current page index
382
+ {pageCount} // total amount of pages
383
+ {itemCount} // total amount of items
384
+
385
+ ```
386
+
387
+ ### pageNextText (default `"Next"`)
388
+ A string specifying the text of the link to the next page.
389
+
390
+ ### pagePrevText (default `"Prev"`)
391
+ A string specifying the text of the link to the previous page.
392
+
393
+ ### pageFirstText (default `"First"`)
394
+ A string specifying the text of the link to the first page.
395
+
396
+ ### pageLastText (default `"Last"`)
397
+ A string specifying the text of the link to the last page.
398
+
399
+ ### pageNavigatorNextText (default `"..."`)
400
+ A string specifying the text of the link to move to next set of page links, when total amount of pages more than `pageButtonCount`.
401
+
402
+ ### pageNavigatorPrevText (default `"..."`)
403
+ A string specifying the text of the link to move to previous set of page links, when total amount of pages more than `pageButtonCount`.
404
+
405
+ ### invalidMessage (default `"Invalid data entered!"`)
406
+ A string specifying the text of the alert message, when invalid data was entered.
407
+
408
+ ### invalidNotify
409
+ A function triggered, when invalid data was entered.
410
+ By default all violated validators messages are alerted.
411
+ The behavior can be customized by providing custom function.
412
+
413
+ The function accepts a single argument with the following structure:
414
+
415
+ ```javascript
416
+
417
+ {
418
+ item // inserting/editing item
419
+ itemIndex // inserting/editing item index
420
+ errors // array of validation violations in format { field: "fieldName", message: "validator message" }
421
+ }
422
+
423
+ ```
424
+
425
+ In the following example error messages are printed in the console instead of alerting:
426
+
427
+ ```javascript
428
+
429
+ $("#grid").jsGrid({
430
+ ...
431
+
432
+ invalidNotify: function(args) {
433
+ var messages = $.map(args.errors, function(error) {
434
+ return error.field + ": " + error.message;
435
+ });
436
+
437
+ console.log(messages);
438
+ }
439
+
440
+ ...
441
+ });
442
+
443
+ ```
444
+
445
+ ### loadIndication (default `true`)
446
+ A boolean value specifying whether to show loading indication during controller operations execution.
447
+
448
+ ### loadIndicationDelay (default `500`)
449
+ An integer value specifying the delay in ms before showing load indication. Applied only when `loadIndication` is `true`.
450
+
451
+ ### loadMessage (default `"Please, wait..."`)
452
+ A string specifying the text of loading indication panel. Applied only when `loadIndication` is `true`.
453
+
454
+ ### loadShading (default `true`)
455
+ A boolean value specifying whether to show overlay (shader) over grid content during loading indication. Applied only when `loadIndication` is `true`.
456
+
457
+ ### loadIndicator
458
+ An object or a function returning an object representing grid load indicator. Load indicator could be any js object supporting two methods `show` and `hide`.
459
+ `show` is called on each loading start. `hide` method is called on each loading finish. Read more about custom load indicator in the [Load Indication](#load-indication) section.
460
+
461
+ ### loadStrategy
462
+ An object or a function returning an object representing grid load strategy. Load strategy defines behavior of the grid after loading data (any interaction with grid controller methods including data manipulation like inserting, updating and removing).
463
+ There are two build-in load strategies: `DirectLoadingStrategy` and `PageLoadingStrategy`. Load strategy depends on `pageLoading` option value.
464
+ For advanced scenarios custom load strategy can be provided. Read more about custom load strategies in the [Load Strategies](#load-strategies) section.
465
+
466
+ ### updateOnResize (default `true`)
467
+ A boolean value specifying whether to refresh grid on window resize event.
468
+
469
+ ### rowRenderer (default `null`)
470
+ A function to customize row rendering. The function signature is `function(item, itemIndex)`, where `item` is row data item, and `itemIndex` is the item index.
471
+ The function should return markup as a string, jQueryElement or DomNode representing table row `tr`.
472
+
473
+ ### headerRowRenderer (default `null`)
474
+ A function to customize grid header row.
475
+ The function should return markup as a string, jQueryElement or DomNode representing table row `tr`.
476
+
477
+ ### filterRowRenderer (default `null`)
478
+ A function to customize grid filter row.
479
+ The function should return markup as a string, jQueryElement or DomNode representing table row `tr`.
480
+
481
+ ### insertRowRenderer (default `null`)
482
+ A function to customize grid inserting row.
483
+ The function should return markup as a string, jQueryElement or DomNode representing table row `tr`.
484
+
485
+ ### editRowRenderer (default `null`)
486
+ A function to customize editing row rendering. The function signature is `function(item, itemIndex)`, where `item` is row data item, and `itemIndex` is the item index.
487
+ The function should return markup as a string, jQueryElement or DomNode representing table row `tr`.
488
+
489
+ ### pagerRenderer (default `null`)
490
+ > version added: 1.2
491
+
492
+ A function to customize pager rendering. The function accepts a single argument with the following structure:
493
+
494
+ ```javascript
495
+ {
496
+ pageIndex, // index of the currently opened page
497
+ pageCount // total amount of grid pages
498
+ }
499
+ ```
500
+
501
+ The function should return markup as a string, jQueryElement or DomNode representing the pager.
502
+ If `pagerRenderer` is specified, then `pagerFormat` option will be ignored.
503
+
504
+
505
+ ## Grid Fields
506
+
507
+ All fields supporting by grid are stored in `jsGrid.fields` object, where key is a type of the field and the value is the field class.
508
+
509
+ `jsGrid.fields` contains following build-in fields:
510
+
511
+ ```javascript
512
+
513
+ {
514
+ text: { ... }, // simple text input
515
+ number: { ... }, // number input
516
+ select: { ... }, // select control
517
+ checkbox: { ... }, // checkbox input
518
+ textarea: { ... }, // textarea control (renders textarea for inserting and editing and text input for filtering)
519
+ control: { ... } // control field with delete and editing buttons for data rows, search and add buttons for filter and inserting row
520
+ }
521
+
522
+ ```
523
+
524
+ Each build-in field can be easily customized with general configuration properties described in [fields](#fields) section and custom field-specific properties described below.
525
+
526
+ ### text
527
+ Text field renders `<input type="text">` in filter, inserting and editing rows.
528
+
529
+ Custom properties:
530
+
531
+ ```javascript
532
+
533
+ {
534
+ autosearch: true, // triggers searching when the user presses `enter` key in the filter input
535
+ readOnly: false // a boolean defines whether input is readonly (added in v1.4)
536
+ }
537
+
538
+ ```
539
+
540
+ ### number
541
+ Number field renders `<input type="number">` in filter, inserting and editing rows.
542
+
543
+ Custom properties:
544
+
545
+ ```javascript
546
+
547
+ {
548
+ sorter: "number", // uses sorter for numbers
549
+ align: "right", // right text alignment
550
+ readOnly: false // a boolean defines whether input is readonly (added in v1.4)
551
+ }
552
+
553
+ ```
554
+
555
+ ### select
556
+ Select field renders `<select>` control in filter, inserting and editing rows.
557
+
558
+ Custom properties:
559
+
560
+ ```javascript
561
+
562
+ {
563
+ align: "center", // center text alignment
564
+ autosearch: true, // triggers searching when the user changes the selected item in the filter
565
+ items: [], // an array of items for select
566
+ valueField: "", // name of property of item to be used as value
567
+ textField: "", // name of property of item to be used as displaying value
568
+ selectedIndex: -1, // index of selected item by default
569
+ valueType: "number|string", // the data type of the value
570
+ readOnly: false // a boolean defines whether select is readonly (added in v1.4)
571
+ }
572
+
573
+ ```
574
+
575
+ If valueField is not defined, then the item index is used instead.
576
+ If textField is not defined, then item itself is used to display value.
577
+
578
+ For instance the simple select field config may look like:
579
+
580
+ ```javascript
581
+
582
+ {
583
+ name: "Country",
584
+ type: "select",
585
+ items: [ "", "United States", "Canada", "United Kingdom" ]
586
+ }
587
+
588
+ ```
589
+
590
+ or more complex with items as objects:
591
+
592
+ ```javascript
593
+
594
+ {
595
+ name: "Country",
596
+ type: "select"
597
+ items: [
598
+ { Name: "", Id: 0 },
599
+ { Name: "United States", Id: 1 },
600
+ { Name: "Canada", Id: 2 },
601
+ { Name: "United Kingdom", Id: 3 }
602
+ ],
603
+ valueField: "Id",
604
+ textField: "Name"
605
+ }
606
+
607
+ ```
608
+
609
+ `valueType` defines whether the field value should be converted to a number or returned as a string.
610
+ The value of the option is determined automatically depending on the data type of `valueField` of the first item, but it can be overridden.
611
+
612
+ ### checkbox
613
+ Checkbox field renders `<input type="checkbox">` in filter, inserting and editing rows.
614
+ Filter checkbox supports intermediate state for, so click switches between 3 states (checked|intermediate|unchecked).
615
+
616
+ Custom properties:
617
+
618
+ ```javascript
619
+
620
+ {
621
+ sorter: "number", // uses sorter for numbers
622
+ align: "center", // center text alignment
623
+ autosearch: true // triggers searching when the user clicks checkbox in filter
624
+ }
625
+
626
+ ```
627
+
628
+ ### textarea
629
+ Textarea field renders `<textarea>` in inserting and editing rows and `<input type="text">` in filter row.
630
+
631
+ Custom properties:
632
+
633
+ ```javascript
634
+
635
+ {
636
+ autosearch: true, // triggers searching when the user presses `enter` key in the filter input
637
+ readOnly: false // a boolean defines whether textarea is readonly (added in v1.4)
638
+ }
639
+
640
+ ```
641
+
642
+ ### control
643
+ Control field renders delete and editing buttons in data row, search and add buttons in filter and inserting row accordingly.
644
+ It also renders button switching between filtering and searching in header row.
645
+
646
+ Custom properties:
647
+
648
+ ```javascript
649
+
650
+ {
651
+ editButton: true, // show edit button
652
+ deleteButton: true, // show delete button
653
+ clearFilterButton: true, // show clear filter button
654
+ modeSwitchButton: true, // show switching filtering/inserting button
655
+
656
+ align: "center", // center content alignment
657
+ width: 50, // default column width is 50px
658
+ filtering: false, // disable filtering for column
659
+ inserting: false, // disable inserting for column
660
+ editing: false, // disable editing for column
661
+ sorting: false, // disable sorting for column
662
+
663
+ searchModeButtonTooltip: "Switch to searching", // tooltip of switching filtering/inserting button in inserting mode
664
+ insertModeButtonTooltip: "Switch to inserting", // tooltip of switching filtering/inserting button in filtering mode
665
+ editButtonTooltip: "Edit", // tooltip of edit item button
666
+ deleteButtonTooltip: "Delete", // tooltip of delete item button
667
+ searchButtonTooltip: "Search", // tooltip of search button
668
+ clearFilterButtonTooltip: "Clear filter", // tooltip of clear filter button
669
+ insertButtonTooltip: "Insert", // tooltip of insert button
670
+ updateButtonTooltip: "Update", // tooltip of update item button
671
+ cancelEditButtonTooltip: "Cancel edit", // tooltip of cancel editing button
672
+ }
673
+
674
+ ```
675
+
676
+ ### Extra fields
677
+
678
+ Fields below ship with jsxgrid on top of the base set. Every one of them (except `XRowSelectField`, which
679
+ never filters) supports a shared `defaultSelected` convention: a value used to preset the filter control the
680
+ *first* time its filter row is rendered, then reset to `null` so it doesn't keep overriding what the user
681
+ searches for afterwards.
682
+
683
+ #### Xcheckbox
684
+
685
+ Drop-in replacement for `checkbox`. Returns `1`/`0` instead of `true`/`false`, which avoids a lot of backend
686
+ type-coercion headaches (especially with databases).
687
+
688
+ | Option | Default | Description |
689
+ |---|---|---|
690
+ | `defaultSelected` | `null` | `0`/`1`/`true`/`false` to preset the filter checkbox as unchecked/checked; leave `null` for the default indeterminate ("any") state. |
691
+
692
+ #### XimgField
693
+
694
+ Text field that previews its value as an `<img>`.
695
+
696
+ | Option | Default | Description |
697
+ |---|---|---|
698
+ | `fm_callback` | `null` | `function(control)` — if set, insert/edit renders a button instead of a text input, and clicking it calls this callback with the jQuery-wrapped control so you can wire up your own file manager/picker. |
699
+ | `editButtonText` | `'Open FM'` | Text for that button. |
700
+ | `defaultSelected` | `null` | A string to preset the filter input with. |
701
+
702
+ #### Xselect
703
+
704
+ Drop-in replacement for `select`, plus:
705
+
706
+ | Option | Default | Description |
707
+ |---|---|---|
708
+ | `pseudoElement` | `null` | An extra item unshifted to the start of the filter dropdown (e.g. an "any" option). Shape must match your `items` (object for object-items, or a `{[textField]:'', [valueField]:null}`-like item for array items). |
709
+ | `select2` | `null` | Config object passed to [select2](https://select2.org/) on the filter control (`width` is always forced to `100%`). Applied via `setTimeout(0)` so the control is attached to the DOM first. |
710
+ | `defaultSelected` | `null` | A value to preselect in the filter, matched against `items` by `valueField` (or by array index / object key if there's no `valueField`). |
711
+
712
+ #### Xtextarea
713
+
714
+ Long text is collapsed and expandable on click.
715
+
716
+ | Option | Default | Description |
717
+ |---|---|---|
718
+ | `maxShowSymbols` | `50` | Values longer than this are truncated with `...`; click the cell to expand. |
719
+ | `defaultSelected` | `null` | A string to preset the filter input with. |
720
+
721
+ #### Xjsoneditor
722
+
723
+ Edits/views a JSON value through [jsoneditor](https://www.npmjs.com/package/jsoneditor) (**required peer
724
+ dependency** — must be loaded on the page, e.g. via CDN, or `Xjsoneditor` will throw when you try to open
725
+ the editor).
726
+
727
+ | Option | Default | Description |
728
+ |---|---|---|
729
+ | `templates` | `[]` | Forwarded to jsoneditor's `templates` option. |
730
+ | `editText` | `'Editor'` | Text of the button shown in view mode. |
731
+ | `closeText` | `'Save'` | Close-button text used when opening the editor for insert/edit. |
732
+ | `defaultSelected` | `null` | A string to preset the (text-based) filter input with — the filter matches against the raw JSON string, not parsed values. |
733
+
734
+ #### XRowSelectField
735
+
736
+ A checkbox-per-row selection column with an optional header action button. `filtering` is hardcoded to
737
+ `false`, so there's no filter row and no `defaultSelected` support.
738
+
739
+ | Option | Default | Description |
740
+ |---|---|---|
741
+ | `buttonText` | `''` | Header button text. Header button is hidden entirely if left empty. |
742
+ | `selectedItemsAction` | no-op | `function(selectedItems)` — called when the header button is clicked. Override this to implement your bulk action. |
743
+
744
+ Field instance also exposes:
745
+ - `selectItem(item)` / `unselectItem(item)` — used internally by the row checkboxes.
746
+ - `unselectAll()` — clears `selectedItems` and unchecks every row checkbox for this field. Call it at the end of your `selectedItemsAction` if you want selection to reset after the action runs.
747
+
748
+ #### XDateTimeField
749
+
750
+ Date/datetime field backed by a native `<input type="datetime-local">` (or whatever `datePickerType` you set).
751
+
752
+ | Option | Default | Description |
753
+ |---|---|---|
754
+ | `datePickerType` | `'datetime-local'` | Any native `<input>` date/time type (`date`, `datetime-local`, `time`, ...). |
755
+ | `dateRange` | `false` | When `true`, the filter renders two date inputs (`from`/`to`) instead of one, and `filterValue()` returns `{from, to}`. |
756
+ | `options` | built-in `Intl.DateTimeFormat` options | Passed to `toLocaleDateString()` when rendering the item view. Empty values render as an empty string. |
757
+ | `defaultSelected` | `null` | A value (matching `datePickerType`'s input format) to preset the filter with. When `dateRange` is `true`, pass `{from, to}` instead. |
758
+
759
+ #### popup.basic
760
+
761
+ A minimal, jQuery-only modal used by `Xjsoneditor` (and available for your own use) as `jsGrid.popup` /
762
+ `jsGrid.popupBasic`:
763
+
764
+ ```javascript
765
+
766
+ jsGrid.popup(formContentOrElement, {
767
+ heading: "Title", // optional
768
+ closeText: "Close", // optional
769
+ styles: "...", // optional, overrides the injected default CSS (injected once per page)
770
+ onClose: function (popup) { /* ... */ }
771
+ });
772
+
773
+ ```
774
+
775
+ You can swap in your own modal implementation entirely by overwriting `jsGrid.popup`.
776
+
777
+ #### jsGridSummaryPlugin
778
+
779
+ Patches `$.fn.jsGrid` so any field can define a `summary(data)` function; the results are rendered as a
780
+ `<tfoot>` row (`.jsgrid-summary-footer`) after every grid refresh:
781
+
782
+ ```javascript
783
+
784
+ {
785
+ name: "Age", type: "number",
786
+ summary: function (data) {
787
+ var total = data.reduce(function (s, i) { return s + (parseFloat(i.Age) || 0); }, 0);
788
+ return "Sum: " + total; // rendered via .html(), so markup is allowed
789
+ }
790
+ }
791
+
792
+ ```
793
+
794
+
795
+ ### Custom Field
796
+
797
+ If you need a completely custom field, the object `jsGrid.fields` can be easily extended.
798
+
799
+ In this example we define new grid field `date`:
800
+
801
+ ```javascript
802
+
803
+ var MyDateField = function(config) {
804
+ jsGrid.Field.call(this, config);
805
+ };
806
+
807
+ MyDateField.prototype = new jsGrid.Field({
808
+
809
+ css: "date-field", // redefine general property 'css'
810
+ align: "center", // redefine general property 'align'
811
+
812
+ myCustomProperty: "foo", // custom property
813
+
814
+ sorter: function(date1, date2) {
815
+ return new Date(date1) - new Date(date2);
816
+ },
817
+
818
+ itemTemplate: function(value) {
819
+ return new Date(value).toDateString();
820
+ },
821
+
822
+ insertTemplate: function(value) {
823
+ return this._insertPicker = $("<input>").datepicker({ defaultDate: new Date() });
824
+ },
825
+
826
+ editTemplate: function(value) {
827
+ return this._editPicker = $("<input>").datepicker().datepicker("setDate", new Date(value));
828
+ },
829
+
830
+ insertValue: function() {
831
+ return this._insertPicker.datepicker("getDate").toISOString();
832
+ },
833
+
834
+ editValue: function() {
835
+ return this._editPicker.datepicker("getDate").toISOString();
836
+ }
837
+ });
838
+
839
+ jsGrid.fields.date = MyDateField;
840
+
841
+ ```
842
+
843
+ To have all general grid field properties custom field class should inherit `jsGrid.Field` class or any other field class.
844
+ Here `itemTemplate` just returns the string representation of a date.
845
+ `insertTemplate` and `editTemplate` create jQuery UI datePicker for inserting and editing row.
846
+ Of course jquery ui library should be included to make it work.
847
+ `insertValue` and `editValue` return date to insert and update items accordingly.
848
+ We also defined date specific sorter.
849
+
850
+ Now, our new field `date` can be used in the grid config as follows:
851
+
852
+ ```javascript
853
+
854
+ {
855
+ fields: [
856
+ ...
857
+ { type: "date", myCustomProperty: "bar" },
858
+ ...
859
+ ]
860
+ }
861
+
862
+ ```
863
+
864
+
865
+ ## Methods
866
+
867
+ jsGrid methods could be called with `jsGrid` jQuery plugin or directly.
868
+
869
+ To use jsGrid plugin to call a method, just call `jsGrid` with method name and required parameters as next arguments:
870
+
871
+ ```javascript
872
+
873
+ // calling method with jQuery plugin
874
+ $("#grid").jsGrid("methodName", param1, param2);
875
+
876
+ ```
877
+
878
+ To call method directly you need to retrieve grid instance or just create grid with the constructor:
879
+
880
+ ```javascript
881
+
882
+ // retrieve grid instance from element data
883
+ var grid = $("#grid").data("JSGrid");
884
+
885
+ // create grid with the constructor
886
+ var grid = new jsGrid.Grid($("#grid"), { ... });
887
+
888
+ // call method directly
889
+ grid.methodName(param1, param2);
890
+
891
+ ```
892
+
893
+ ### cancelEdit()
894
+ Cancels row editing.
895
+
896
+ ```javascript
897
+
898
+ $("#grid").jsGrid("cancelEdit");
899
+
900
+ ```
901
+
902
+ ### clearFilter(): `Promise`
903
+ Clears current filter and performs search with empty filter.
904
+ Returns jQuery promise resolved when data filtering is completed.
905
+
906
+ ```javascript
907
+
908
+ $("#grid").jsGrid("clearFilter").done(function() {
909
+ console.log("filtering completed");
910
+ });
911
+
912
+ ```
913
+
914
+ ### clearInsert()
915
+ Clears current inserting row.
916
+
917
+ ```javascript
918
+
919
+ $("#grid").jsGrid("clearInsert");
920
+
921
+ ```
922
+
923
+ ### deleteItem(item|$row|rowNode): `Promise`
924
+ Removes specified row from the grid.
925
+ Returns jQuery promise resolved when deletion is completed.
926
+
927
+ **item|$row|rowNode** is the reference to the item or the row jQueryElement or the row DomNode.
928
+
929
+ ```javascript
930
+
931
+ // delete row by item reference
932
+ $("#grid").jsGrid("deleteItem", item);
933
+
934
+ // delete row by jQueryElement
935
+ $("#grid").jsGrid("deleteItem", $(".specific-row"));
936
+
937
+ // delete row by DomNode
938
+ $("#grid").jsGrid("deleteItem", rowNode);
939
+
940
+ ```
941
+
942
+ ### destroy()
943
+ Destroys the grid and brings the Node to its original state.
944
+
945
+ ```javascript
946
+
947
+ $("#grid").jsGrid("destroy");
948
+
949
+ ```
950
+
951
+ ### editItem(item|$row|rowNode)
952
+ Sets grid editing row.
953
+
954
+ **item|$row|rowNode** is the reference to the item or the row jQueryElement or the row DomNode.
955
+
956
+ ```javascript
957
+
958
+ // edit row by item reference
959
+ $("#grid").jsGrid("editItem", item);
960
+
961
+ // edit row by jQueryElement
962
+ $("#grid").jsGrid("editItem", $(".specific-row"));
963
+
964
+ // edit row by DomNode
965
+ $("#grid").jsGrid("editItem", rowNode);
966
+
967
+ ```
968
+
969
+ ### getFilter(): `Object`
970
+ Get grid filter as a plain object.
971
+
972
+ ```javascript
973
+
974
+ var filter = $("#grid").jsGrid("getFilter");
975
+
976
+ ```
977
+
978
+ ### getSorting(): `Object`
979
+ > version added: 1.2
980
+
981
+ Get grid current sorting params as a plain object with the following format:
982
+
983
+ ```javascript
984
+
985
+ {
986
+ field, // the name of the field by which grid is sorted
987
+ order // 'asc' or 'desc' depending on sort order
988
+ }
989
+
990
+ ```
991
+
992
+ ```javascript
993
+
994
+ var sorting = $("#grid").jsGrid("getSorting");
995
+
996
+ ```
997
+
998
+ ### fieldOption(fieldName|fieldIndex, optionName, [optionValue])
999
+ > version added: 1.3
1000
+
1001
+ Gets or sets the value of a field option.
1002
+
1003
+ **fieldName|fieldIndex** is the name or the index of the field to get/set the option value (if the grid contains more than one field with the same name, the first field will be used).
1004
+
1005
+ **optionName** is the name of the field option.
1006
+
1007
+ **optionValue** is the new option value to set.
1008
+
1009
+ If `optionValue` is not specified, then the value of the field option `optionName` will be returned.
1010
+
1011
+ ```javascript
1012
+
1013
+ // hide the field "ClientName"
1014
+ $("#grid").jsGrid("fieldOption", "ClientName", "visible", false);
1015
+
1016
+ // get width of the 2nd field
1017
+ var secondFieldOption = $("#grid").jsGrid("fieldOption", 1, "width");
1018
+
1019
+ ```
1020
+
1021
+ ### insertItem([item]): `Promise`
1022
+ Inserts row into the grid based on item.
1023
+ Returns jQuery promise resolved when insertion is completed.
1024
+
1025
+ **item** is the item to pass to `controller.insertItem`.
1026
+
1027
+ If `item` is not specified the data from inserting row will be inserted.
1028
+
1029
+ ```javascript
1030
+
1031
+ // insert item from inserting row
1032
+ $("#grid").jsGrid("insertItem");
1033
+
1034
+ // insert item
1035
+ $("#grid").jsGrid("insertItem", { Name: "John", Age: 25, Country: 2 }).done(function() {
1036
+ console.log("insertion completed");
1037
+ });
1038
+
1039
+ ```
1040
+
1041
+ ### loadData([filter]): `Promise`
1042
+ Loads data calling corresponding `controller.loadData` method.
1043
+ Returns jQuery promise resolved when data loading is completed.
1044
+ It preserves current sorting and paging unlike the `search` method .
1045
+
1046
+ **filter** is a filter to pass to `controller.loadData`.
1047
+
1048
+ If `filter` is not specified the current filter (filtering row values) will be applied.
1049
+
1050
+ ```javascript
1051
+
1052
+ // load data with current grid filter
1053
+ $("#grid").jsGrid("loadData");
1054
+
1055
+ // loadData with custom filter
1056
+ $("#grid").jsGrid("loadData", { Name: "John" }).done(function() {
1057
+ console.log("data loaded");
1058
+ });
1059
+
1060
+ ```
1061
+
1062
+ ### exportData([options])
1063
+ Transforms the grid data into the specified output type.
1064
+ Output can be formatted, filtered or modified by providing options.
1065
+ Currently only supports CSV output.
1066
+
1067
+ ```javascript
1068
+ //Basic export
1069
+ var csv = $("#grid").jsGrid("exportData");
1070
+
1071
+ //Full Options
1072
+ var csv = $("#grid").jsGrid("exportData", {
1073
+ type: "csv", //Only CSV supported
1074
+ subset: "all" | "visible", //Visible will only output the currently displayed page
1075
+ delimiter: "|", //If using csv, the character to seperate fields
1076
+ includeHeaders: true, //Include header row in output
1077
+ encapsulate: true, //Surround each field with qoutation marks; needed for some systems
1078
+ newline: "\r\n", //Newline character to use
1079
+
1080
+ //Takes each item and returns true if it should be included in output.
1081
+ //Executed only on the records within the given subset above.
1082
+ filter: function(item){return true},
1083
+
1084
+ //Transformations are a way to modify the display value of the output.
1085
+ //Provide a key of the field name, and a function that takes the current value.
1086
+ transformations: {
1087
+ "Married": function(value){
1088
+ if (value === true){
1089
+ return "Yes"
1090
+ }
1091
+ else{
1092
+ return "No"
1093
+ }
1094
+ }
1095
+ }
1096
+ });
1097
+
1098
+ ```
1099
+
1100
+ ### openPage(pageIndex)
1101
+ Opens the page of specified index.
1102
+
1103
+ **pageIndex** is one-based index of the page to open. The value should be in range from 1 to [total amount of pages].
1104
+
1105
+
1106
+ ### option(optionName, [optionValue])
1107
+ Gets or sets the value of an option.
1108
+
1109
+ **optionName** is the name of the option.
1110
+
1111
+ **optionValue** is the new option value to set.
1112
+
1113
+ If `optionValue` is not specified, then the value of the option `optionName` will be returned.
1114
+
1115
+ ```javascript
1116
+
1117
+ // turn off paging
1118
+ $("#grid").jsGrid("option", "paging", false);
1119
+
1120
+ // get current page index
1121
+ var pageIndex = $("#grid").jsGrid("option", "pageIndex");
1122
+
1123
+ ```
1124
+
1125
+ ### refresh()
1126
+ Refreshes the grid. Renders the grid body and pager content, recalculates sizes.
1127
+
1128
+ ```javascript
1129
+
1130
+ $("#grid").jsGrid("refresh");
1131
+
1132
+ ```
1133
+
1134
+ ### render(): `Promise`
1135
+ Performs complete grid rendering. If option `autoload` is `true` calls `controller.loadData`. The state of the grid like current page and sorting is retained.
1136
+ Returns jQuery promise resolved when data loading is completed. If auto-loading is disabled the promise is instantly resolved.
1137
+
1138
+ ```javascript
1139
+
1140
+ $("#grid").jsGrid("render").done(function() {
1141
+ console.log("rendering completed and data loaded");
1142
+ });
1143
+
1144
+ ```
1145
+
1146
+ ### reset()
1147
+ Resets the state of the grid. Goes to the first data page, resets sorting, and then calls `refresh`.
1148
+
1149
+ ```javascript
1150
+
1151
+ $("#grid").jsGrid("reset");
1152
+
1153
+ ```
1154
+
1155
+ ### rowByItem(item): `jQueryElement`
1156
+ > version added: 1.3
1157
+
1158
+ Gets the row jQuery element corresponding to the item.
1159
+
1160
+ **item** is the item corresponding to the row.
1161
+
1162
+ ```javascript
1163
+
1164
+ var $row = $("#grid").jsGrid("rowByItem", item);
1165
+
1166
+ ```
1167
+
1168
+ ### search([filter]): `Promise`
1169
+ Performs filtering of the grid.
1170
+ Returns jQuery promise resolved when data loading is completed.
1171
+ It resets current sorting and paging unlike the `loadData` method.
1172
+
1173
+ **filter** is a filter to pass to `controller.loadData`.
1174
+
1175
+ If `filter` is not specified the current filter (filtering row values) will be applied.
1176
+
1177
+ ```javascript
1178
+
1179
+ // search with current grid filter
1180
+ $("#grid").jsGrid("search");
1181
+
1182
+ // search with custom filter
1183
+ $("#grid").jsGrid("search", { Name: "John" }).done(function() {
1184
+ console.log("filtering completed");
1185
+ });
1186
+
1187
+ ```
1188
+
1189
+ ### showPrevPages()
1190
+ Shows previous set of pages, when total amount of pages more than `pageButtonCount`.
1191
+
1192
+ ```javascript
1193
+
1194
+ $("#grid").jsGrid("showPrevPages");
1195
+
1196
+ ```
1197
+
1198
+ ### showNextPages()
1199
+ Shows next set of pages, when total amount of pages more than `pageButtonCount`.
1200
+
1201
+ ```javascript
1202
+
1203
+ $("#grid").jsGrid("showNextPages");
1204
+
1205
+ ```
1206
+
1207
+ ### sort(sortConfig|field, [order]): `Promise`
1208
+ Sorts grid by specified field.
1209
+ Returns jQuery promise resolved when sorting is completed.
1210
+
1211
+ **sortConfig** is the plain object of the following structure `{ field: (fieldIndex|fieldName|field), order: ("asc"|"desc") }`
1212
+
1213
+ **field** is the field to sort by. It could be zero-based field index or field name or field reference
1214
+
1215
+ **order** is the sorting order. Accepts the following values: "asc"|"desc"
1216
+
1217
+ If `order` is not specified, then data is sorted in the reversed to current order, when grid is already sorted by the same field. Or `"asc"` for sorting by another field.
1218
+
1219
+ When grid data is loaded by pages (`pageLoading` is `true`) sorting calls `controller.loadData` with sorting parameters. Read more in [Grid Controller](#grid-controller) section.
1220
+
1221
+ ```javascript
1222
+
1223
+ // sorting grid by first field
1224
+ $("#grid").jsGrid("sort", 0);
1225
+
1226
+ // sorting grid by field "Name" in descending order
1227
+ $("#grid").jsGrid("sort", { field: "Name", order: "desc" });
1228
+
1229
+ // sorting grid by myField in ascending order
1230
+ $("#grid").jsGrid("sort", myField, "asc").done(function() {
1231
+ console.log("sorting completed");
1232
+ });
1233
+
1234
+ ```
1235
+
1236
+ ### updateItem([item|$row|rowNode], [editedItem]): `Promise`
1237
+ Updates item and row of the grid.
1238
+ Returns jQuery promise resolved when update is completed.
1239
+
1240
+ **item|$row|rowNode** is the reference to the item or the row jQueryElement or the row DomNode.
1241
+
1242
+ **editedItem** is the changed item to pass to `controller.updateItem`.
1243
+
1244
+ If `item|$row|rowNode` is not specified then editing row will be updated.
1245
+
1246
+ If `editedItem` is not specified the data from editing row will be taken.
1247
+
1248
+ ```javascript
1249
+
1250
+ // update currently editing row
1251
+ $("#grid").jsGrid("updateItem");
1252
+
1253
+ // update currently editing row with specified data
1254
+ $("#grid").jsGrid("updateItem", { ID: 1, Name: "John", Age: 25, Country: 2 });
1255
+
1256
+ // update specified item with particular data (row DomNode or row jQueryElement can be used instead of item reference)
1257
+ $("#grid").jsGrid("updateItem", item, { ID: 1, Name: "John", Age: 25, Country: 2 }).done(function() {
1258
+ console.log("update completed");
1259
+ });
1260
+
1261
+ ```
1262
+
1263
+ ### jsGrid.locale(localeName|localeConfig)
1264
+ > version added: 1.4
1265
+
1266
+ Set current locale of all grids.
1267
+
1268
+ **localeName|localeConfig** is the name of the supported locale (see [available locales](src/i18n)) or a custom localization config.
1269
+ Find more information on custom localization config in [Localization](#localization).
1270
+
1271
+ ```javascript
1272
+
1273
+ // set French locale
1274
+ jsGrid.locale("fr");
1275
+
1276
+ ```
1277
+
1278
+ ### jsGrid.setDefaults(config)
1279
+ Set default options for all grids.
1280
+
1281
+ ```javascript
1282
+
1283
+ jsGrid.setDefaults({
1284
+ filtering: true,
1285
+ inserting: true
1286
+ });
1287
+
1288
+ ```
1289
+
1290
+ ### jsGrid.setDefaults(fieldName, config)
1291
+ Set default options of the particular field.
1292
+
1293
+ ```javascript
1294
+
1295
+ jsGrid.setDefaults("text", {
1296
+ width: 150,
1297
+ css: "text-field-cls"
1298
+ });
1299
+
1300
+ ```
1301
+
1302
+
1303
+ ## Callbacks
1304
+
1305
+ jsGrid allows to specify a callback function to be executed on a particular event.
1306
+
1307
+ The following callbacks are supported:
1308
+
1309
+ ```javascript
1310
+
1311
+ {
1312
+ onDataLoading: function(args) {}, // before controller.loadData
1313
+ onDataLoaded: function(args) {}, // on done of controller.loadData
1314
+ onDataExporting: function() {}, // before data export
1315
+
1316
+ onInit: function(args) {}, // after grid initialization
1317
+
1318
+ onItemInserting: function(args) {}, // before controller.insertItem
1319
+ onItemInserted: function(args) {}, // on done of controller.insertItem
1320
+ onItemUpdating: function(args) {}, // before controller.updateItem
1321
+ onItemUpdated: function(args) {}, // on done of controller.updateItem
1322
+ onItemDeleting: function(args) {}, // before controller.deleteItem
1323
+ onItemDeleted: function(args) {}, // on done of controller.deleteItem
1324
+ onItemInvalid: function(args) {}, // after item validation, in case data is invalid
1325
+
1326
+ onError: function(args) {}, // on fail of any controller call
1327
+
1328
+ onOptionChanging: function(args) {}, // before changing the grid option
1329
+ onOptionChanged: function(args) {}, // after changing the grid option
1330
+
1331
+ onPageChanged: function(args) {}, // after changing the current page
1332
+
1333
+ onRefreshing: function(args) {}, // before grid refresh
1334
+ onRefreshed: function(args) {}, // after grid refresh
1335
+ }
1336
+
1337
+ ```
1338
+
1339
+ ### onDataLoading
1340
+ Fires before data loading.
1341
+
1342
+ Has the following arguments:
1343
+
1344
+ ```javascript
1345
+
1346
+ {
1347
+ grid // grid instance
1348
+ filter // loading filter object
1349
+ }
1350
+
1351
+ ```
1352
+
1353
+ #### Cancel Data Loading
1354
+ > version added: 1.2
1355
+
1356
+ To cancel data loading set `args.cancel = true`.
1357
+
1358
+ In the following example loading is canceled when the filter has empty 'name' field:
1359
+
1360
+ ```javascript
1361
+
1362
+ $("#grid").jsGrid({
1363
+ ...
1364
+
1365
+ onDataLoading: function(args) {
1366
+ // cancel loading data if 'name' is empty
1367
+ if(args.filter.name === "") {
1368
+ args.cancel = true;
1369
+ }
1370
+ }
1371
+ });
1372
+
1373
+ ```
1374
+
1375
+ ### onDataLoaded
1376
+ Fires after data loading.
1377
+
1378
+ Has the following arguments:
1379
+
1380
+ ```javascript
1381
+
1382
+ {
1383
+ grid // grid instance
1384
+ data // load result (array of items or data structure for loading by page scenario)
1385
+ }
1386
+
1387
+ ```
1388
+
1389
+ In the following example the loaded data is written to the browser console.
1390
+
1391
+ ```javascript
1392
+
1393
+ $("#grid").jsGrid({
1394
+ ...
1395
+
1396
+ onDataLoaded: function(args) {
1397
+ console.log(args.data);
1398
+ }
1399
+ });
1400
+
1401
+ ```
1402
+
1403
+ ### onInit
1404
+ > version added: 1.5
1405
+
1406
+ Fires after grid initialization right before rendering. Usually used to get grid instance.
1407
+
1408
+ Has the following arguments:
1409
+
1410
+ ```javascript
1411
+
1412
+ {
1413
+ grid // grid instance
1414
+ }
1415
+
1416
+ ```
1417
+
1418
+ In the following example we get the grid instance on initialization:
1419
+
1420
+ ```javascript
1421
+
1422
+ var gridInstance;
1423
+
1424
+ $("#grid").jsGrid({
1425
+ ...
1426
+
1427
+ onInit: function(args) {
1428
+ gridInstance = args.grid;
1429
+ }
1430
+ });
1431
+
1432
+ ```
1433
+
1434
+ ### onError
1435
+ Fires when controller handler promise failed.
1436
+
1437
+ Has the following arguments:
1438
+
1439
+ ```javascript
1440
+
1441
+ {
1442
+ grid // grid instance
1443
+ args // an array of arguments provided to fail promise handler
1444
+ }
1445
+
1446
+ ```
1447
+
1448
+ ### onItemDeleting
1449
+ Fires before item deletion.
1450
+
1451
+ Has the following arguments:
1452
+
1453
+ ```javascript
1454
+
1455
+ {
1456
+ grid // grid instance
1457
+ row // deleting row jQuery element
1458
+ item // deleting item
1459
+ itemIndex // deleting item index
1460
+ }
1461
+
1462
+ ```
1463
+
1464
+ #### Cancel Item Deletion
1465
+ > version added: 1.2
1466
+
1467
+ To cancel item deletion set `args.cancel = true`. This allows to do a validation before performing the actual deletion.
1468
+
1469
+ In the following example the deletion of items marked as `protected` is canceled:
1470
+
1471
+ ```javascript
1472
+
1473
+ $("#grid").jsGrid({
1474
+ ...
1475
+
1476
+ onItemDeleting: function(args) {
1477
+ // cancel deletion of the item with 'protected' field
1478
+ if(args.item.protected) {
1479
+ args.cancel = true;
1480
+ }
1481
+ }
1482
+ });
1483
+
1484
+ ```
1485
+
1486
+ ### onItemDeleted
1487
+ Fires after item deletion.
1488
+
1489
+ Has the following arguments:
1490
+
1491
+ ```javascript
1492
+
1493
+ {
1494
+ grid // grid instance
1495
+ row // deleted row jQuery element
1496
+ item // deleted item
1497
+ itemIndex // deleted item index
1498
+ }
1499
+
1500
+ ```
1501
+
1502
+
1503
+ ### onItemEditing
1504
+ > version added: 1.4
1505
+
1506
+ Fires before item editing.
1507
+
1508
+ Has the following arguments:
1509
+
1510
+ ```javascript
1511
+
1512
+ {
1513
+ grid // grid instance
1514
+ row // editing row jQuery element
1515
+ item // editing item
1516
+ itemIndex // editing item index
1517
+ }
1518
+
1519
+ ```
1520
+
1521
+ #### Cancel Item Editing
1522
+ To cancel item editing set `args.cancel = true`. This allows to prevent row from editing conditionally.
1523
+
1524
+ In the following example the editing of the row for item with 'ID' = 0 is canceled:
1525
+
1526
+ ```javascript
1527
+
1528
+ $("#grid").jsGrid({
1529
+ ...
1530
+
1531
+ onItemEditing: function(args) {
1532
+ // cancel editing of the row of item with field 'ID' = 0
1533
+ if(args.item.ID === 0) {
1534
+ args.cancel = true;
1535
+ }
1536
+ }
1537
+ });
1538
+
1539
+ ```
1540
+
1541
+
1542
+ ### onItemInserting
1543
+ Fires before item insertion.
1544
+
1545
+ Has the following arguments:
1546
+
1547
+ ```javascript
1548
+
1549
+ {
1550
+ grid // grid instance
1551
+ item // inserting item
1552
+ }
1553
+
1554
+ ```
1555
+
1556
+ #### Cancel Item Insertion
1557
+ > version added: 1.2
1558
+
1559
+ To cancel item insertion set `args.cancel = true`. This allows to do a validation before performing the actual insertion.
1560
+
1561
+ In the following example insertion of items with the 'name' specified is allowed:
1562
+
1563
+ ```javascript
1564
+
1565
+ $("#grid").jsGrid({
1566
+ ...
1567
+
1568
+ onItemInserting: function(args) {
1569
+ // cancel insertion of the item with empty 'name' field
1570
+ if(args.item.name === "") {
1571
+ args.cancel = true;
1572
+ alert("Specify the name of the item!");
1573
+ }
1574
+ }
1575
+ });
1576
+
1577
+ ```
1578
+
1579
+ ### onItemInserted
1580
+ Fires after item insertion.
1581
+
1582
+ Has the following arguments:
1583
+
1584
+ ```javascript
1585
+
1586
+ {
1587
+ grid // grid instance
1588
+ item // inserted item
1589
+ }
1590
+
1591
+ ```
1592
+
1593
+ ### onItemInvalid
1594
+ Fired when item is not following validation rules on inserting or updating.
1595
+
1596
+ Has the following arguments:
1597
+
1598
+ ```javascript
1599
+
1600
+ {
1601
+ grid // grid instance
1602
+ row // inserting/editing row jQuery element
1603
+ item // inserting/editing item
1604
+ itemIndex // inserting/editing item index
1605
+ errors // array of validation violations in format { field: "fieldName", message: "validator message" }
1606
+ }
1607
+
1608
+ ```
1609
+
1610
+ The following handler prints errors on the console
1611
+
1612
+ ```javascript
1613
+
1614
+ $("#grid").jsGrid({
1615
+ ...
1616
+
1617
+ onItemInvalid: function(args) {
1618
+ // prints [{ field: "Name", message: "Enter client name" }]
1619
+ console.log(args.errors);
1620
+ }
1621
+ });
1622
+
1623
+ ```
1624
+
1625
+ ### onItemUpdating
1626
+ Fires before item update.
1627
+
1628
+ Has the following arguments:
1629
+
1630
+ ```javascript
1631
+
1632
+ {
1633
+ grid // grid instance
1634
+ row // updating row jQuery element
1635
+ item // updating item
1636
+ itemIndex // updating item index
1637
+ previousItem // shallow copy (not deep copy) of item before editing
1638
+ }
1639
+
1640
+ ```
1641
+
1642
+ #### Cancel Item Update
1643
+ > version added: 1.2
1644
+
1645
+ To cancel item update set `args.cancel = true`. This allows to do a validation before performing the actual update.
1646
+
1647
+ In the following example update of items with the 'name' specified is allowed:
1648
+
1649
+ ```javascript
1650
+
1651
+ $("#grid").jsGrid({
1652
+ ...
1653
+
1654
+ onItemUpdating: function(args) {
1655
+ // cancel update of the item with empty 'name' field
1656
+ if(args.item.name === "") {
1657
+ args.cancel = true;
1658
+ alert("Specify the name of the item!");
1659
+ }
1660
+ }
1661
+ });
1662
+
1663
+ ```
1664
+
1665
+ ### onItemUpdated
1666
+ Fires after item update.
1667
+
1668
+ Has the following arguments:
1669
+
1670
+ ```javascript
1671
+
1672
+ {
1673
+ grid // grid instance
1674
+ row // updated row jQuery element
1675
+ item // updated item
1676
+ itemIndex // updated item index
1677
+ previousItem // shallow copy (not deep copy) of item before editing
1678
+ }
1679
+
1680
+ ```
1681
+
1682
+ ### onOptionChanging
1683
+ Fires before grid option value change.
1684
+
1685
+ Has the following arguments:
1686
+
1687
+ ```javascript
1688
+
1689
+ {
1690
+ grid // grid instance
1691
+ option // name of option to be changed
1692
+ oldValue // old value of option
1693
+ newValue // new value of option
1694
+ }
1695
+
1696
+ ```
1697
+
1698
+ ### onOptionChanged
1699
+ Fires after grid option value change.
1700
+
1701
+ Has the following arguments:
1702
+
1703
+ ```javascript
1704
+
1705
+ {
1706
+ grid // grid instance
1707
+ option // name of changed option
1708
+ value // changed option value
1709
+ }
1710
+
1711
+ ```
1712
+
1713
+ ### onPageChanged
1714
+ > version added: 1.5
1715
+
1716
+ Fires once grid current page index is changed. It happens either by switching between the pages with the pager links, or by calling the method `openPage`, or changing the option `pageIndex`.
1717
+
1718
+ Has the following arguments:
1719
+
1720
+ ```javascript
1721
+
1722
+ {
1723
+ grid // grid instance
1724
+ pageIndex // current page index
1725
+ }
1726
+
1727
+ ```
1728
+
1729
+ In the following example we print the current page index in the browser console once it has been changed:
1730
+
1731
+ ```javascript
1732
+
1733
+ $("#grid").jsGrid({
1734
+ ...
1735
+
1736
+ onPageChanged: function(args) {
1737
+ console.log(args.pageIndex);
1738
+ }
1739
+ });
1740
+
1741
+ ```
1742
+
1743
+ ### onRefreshing
1744
+ Fires before grid refresh.
1745
+
1746
+ Has the following arguments:
1747
+
1748
+ ```javascript
1749
+
1750
+ {
1751
+ grid // grid instance
1752
+ }
1753
+
1754
+ ```
1755
+
1756
+ ### onRefreshed
1757
+ Fires after grid refresh.
1758
+
1759
+ Has the following arguments:
1760
+
1761
+ ```javascript
1762
+
1763
+ {
1764
+ grid // grid instance
1765
+ }
1766
+
1767
+ ```
1768
+
1769
+
1770
+ ## Grid Controller
1771
+
1772
+ The controller is a gateway between grid and data storage. All data manipulations call accordant controller methods.
1773
+ By default grid has an empty controller and can work with static array of items stored in option `data`.
1774
+
1775
+ A controller should implement the following methods:
1776
+
1777
+ ```javascript
1778
+
1779
+ {
1780
+ loadData: function(filter) { ... },
1781
+ insertItem: function(item) { ... },
1782
+ updateItem: function(item) { ... },
1783
+ deleteItem: function(item) { ... }
1784
+ }
1785
+
1786
+ ```
1787
+
1788
+ Asynchronous controller methods should return a Promise, resolved once the request is completed.
1789
+ Starting v1.5 jsGrid supports standard JavaScript Promise/A, earlier versions support only jQuery.Promise.
1790
+
1791
+ For instance the controller for typical REST service might look like:
1792
+
1793
+ ```javascript
1794
+
1795
+ {
1796
+ loadData: function(filter) {
1797
+ return $.ajax({
1798
+ type: "GET",
1799
+ url: "/items",
1800
+ data: filter
1801
+ });
1802
+ },
1803
+
1804
+ insertItem: function(item) {
1805
+ return $.ajax({
1806
+ type: "POST",
1807
+ url: "/items",
1808
+ data: item
1809
+ });
1810
+ },
1811
+
1812
+ updateItem: function(item) {
1813
+ return $.ajax({
1814
+ type: "PUT",
1815
+ url: "/items",
1816
+ data: item
1817
+ });
1818
+ },
1819
+
1820
+ deleteItem: function(item) {
1821
+ return $.ajax({
1822
+ type: "DELETE",
1823
+ url: "/items",
1824
+ data: item
1825
+ });
1826
+ },
1827
+ }
1828
+
1829
+ ```
1830
+
1831
+ ### loadData(filter): `Promise|dataResult`
1832
+ Called on data loading.
1833
+
1834
+ **filter** contains all filter parameters of fields with enabled filtering
1835
+
1836
+ When `pageLoading` is `true` and data is loaded by page, `filter` includes two more parameters:
1837
+
1838
+ ```javascript
1839
+
1840
+ {
1841
+ pageIndex // current page index
1842
+ pageSize // the size of page
1843
+ }
1844
+
1845
+ ```
1846
+
1847
+ When grid sorting is enabled, `filter` includes two more parameters:
1848
+
1849
+ ```javascript
1850
+
1851
+ {
1852
+ sortField // the name of sorting field
1853
+ sortOrder // the order of sorting as string "asc"|"desc"
1854
+ }
1855
+
1856
+ ```
1857
+
1858
+ Method should return `dataResult` or jQuery promise that will be resolved with `dataResult`.
1859
+
1860
+ **dataResult** depends on `pageLoading`. When `pageLoading` is `false` (by default), then data result is a plain javascript array of objects.
1861
+ If `pageLoading` is `true` data result should have following structure
1862
+
1863
+ ```javascript
1864
+
1865
+ {
1866
+ data // array of items
1867
+ itemsCount // total items amount in storage
1868
+ }
1869
+
1870
+ ```
1871
+
1872
+ ### insertItem(item): `Promise|insertedItem`
1873
+ Called on item insertion.
1874
+
1875
+ Method should return `insertedItem` or jQuery promise that will be resolved with `insertedItem`.
1876
+ If no item is returned, inserting item will be used as inserted item.
1877
+
1878
+ **item** is the item to be inserted.
1879
+
1880
+ ### updateItem(item): `Promise|updatedItem`
1881
+ Called on item update.
1882
+
1883
+ Method should return `updatedItem` or jQuery promise that will be resolved with `updatedItem`.
1884
+ If no item is returned, updating item will be used as updated item.
1885
+
1886
+ **item** is the item to be updated.
1887
+
1888
+ ### deleteItem(item): `Promise`
1889
+ Called on item deletion.
1890
+
1891
+ If deletion is asynchronous, method should return jQuery promise that will be resolved when deletion is completed.
1892
+
1893
+ **item** is the item to be deleted.
1894
+
1895
+ ## Validation
1896
+ > version added: 1.4
1897
+
1898
+ ### Field Validation Config
1899
+
1900
+ `validate` option of the field can have 4 different value types `string|Object|Array|function`:
1901
+
1902
+ 1. `validate: "validatorName"`
1903
+
1904
+ **validatorName** - is a string key of the validator in the `jsGrid.validators` registry. The registry can be easily extended. See available [built-in validators here](#built-in-validators).
1905
+
1906
+ In the following example the `required` validator is applied:
1907
+
1908
+ ```javascript
1909
+
1910
+ $("#grid").jsGrid({
1911
+ ...
1912
+
1913
+ fields: [{ type: "text", name: "FieldName", validate: "required" }]
1914
+ });
1915
+
1916
+ ```
1917
+
1918
+ 2. `validate: validationConfig`
1919
+
1920
+ **validateConfig** - is a plain object of the following structure:
1921
+
1922
+ ```javascript
1923
+ {
1924
+ validator: string|function(value, item, param), // built-in validator name or custom validation function
1925
+ message: string|function, // validation message or a function(value, item) returning validation message
1926
+ param: any // a plain object with parameters to be passed to validation function
1927
+ }
1928
+ ```
1929
+
1930
+ In the following example the `range` validator is applied with custom validation message and range provided in parameters:
1931
+
1932
+ ```javascript
1933
+
1934
+ $("#grid").jsGrid({
1935
+ ...
1936
+
1937
+ fields: [{
1938
+ type: "number",
1939
+ name: "Age",
1940
+ validate: {
1941
+ validator: "range",
1942
+ message: function(value, item) {
1943
+ return "The client age should be between 21 and 80. Entered age is \"" + value + "\" is out of specified range.";
1944
+ },
1945
+ param: [21, 80]
1946
+ }
1947
+ }]
1948
+ });
1949
+
1950
+ ```
1951
+
1952
+ 3. `validate: validateArray`
1953
+
1954
+ **validateArray** - is an array of validators. It can contain
1955
+
1956
+ * `string` - validator name
1957
+ * `Object` - validator configuration of structure `{ validator, message, param }`
1958
+ * `function` - validation function as `function(value, item)`
1959
+
1960
+ In the following example the field has three validators: `required`, `range`, and a custom function validator:
1961
+
1962
+ ```javascript
1963
+
1964
+ $("#grid").jsGrid({
1965
+ ...
1966
+
1967
+ fields: [{
1968
+ type: "number",
1969
+ name: "Age",
1970
+ validate: [
1971
+ "required",
1972
+ { validator: "range", param: [21, 80] },
1973
+ function(value, item) {
1974
+ return item.IsRetired ? value > 55 : true;
1975
+ }
1976
+ ]
1977
+ }]
1978
+ });
1979
+
1980
+ ```
1981
+
1982
+ 4. `validate: function(value, item, param)`
1983
+
1984
+ The parameters of the function:
1985
+
1986
+ * `value` - entered value of the field
1987
+ * `item` - editing/inserting item
1988
+ * `param` - a parameter provided by validator (applicable only when validation config is defined at validation object or an array of objects)
1989
+
1990
+ In the following example the field has custom validation function:
1991
+
1992
+ ```javascript
1993
+
1994
+ $("#grid").jsGrid({
1995
+ ...
1996
+
1997
+ fields: [{
1998
+ type: "text",
1999
+ name: "Phone",
2000
+ validate: function(value, item) {
2001
+ return value.length == 10 && phoneBelongsToCountry(value, item.Country);
2002
+ }
2003
+ }]
2004
+ });
2005
+
2006
+ ```
2007
+
2008
+ ### Built-in Validators
2009
+
2010
+ The `jsGrid.validators` object contains all built-in validators. The key of the hash is a validator name and the value is the validator config.
2011
+
2012
+ `jsGrid.validators` contains the following build-in validators:
2013
+
2014
+ * **required** - the field value is required
2015
+ * **rangeLength** - the length of the field value is limited by range (the range should be provided as an array in `param` field of validation config)
2016
+ * **minLength** - the minimum length of the field value is limited (the minimum value should be provided in `param` field of validation config)
2017
+ * **maxLength** - the maximum length of the field value is limited (the maximum value should be provided in `param` field of validation config)
2018
+ * **pattern** - the field value should match the defined pattern (the pattern should be provided as a regexp literal or string in `param` field of validation config)
2019
+ * **range** - the value of the number field is limited by range (the range should be provided as an array in `param` field of validation config)
2020
+ * **min** - the minimum value of the number field is limited (the minimum should be provided in `param` field of validation config)
2021
+ * **max** - the maximum value of the number field is limited (the maximum should be provided in `param` field of validation config)
2022
+
2023
+ ### Custom Validators
2024
+
2025
+ To define a custom validator just add it to the `jsGrid.validators` object.
2026
+
2027
+ In the following example a custom validator `time` is registered:
2028
+
2029
+ ```javascript
2030
+
2031
+ jsGrid.validators.time = {
2032
+ message: "Please enter a valid time, between 00:00 and 23:59",
2033
+ validator: function(value, item) {
2034
+ return /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(value);
2035
+ }
2036
+ }
2037
+
2038
+ ```
2039
+
2040
+
2041
+ ## Localization
2042
+ > version added: 1.4
2043
+
2044
+ Current locale can be set for all grids on the page with the [`jsGrid.locale(localeName)`](#jsgridlocalelocalenamelocaleconfig) method.
2045
+
2046
+ New custom locale can be added to `jsGrid.locales` hash like the following:
2047
+
2048
+ ```javascript
2049
+
2050
+ jsGrid.locales.my_lang = {
2051
+ // localization config goes here
2052
+ ...
2053
+ };
2054
+
2055
+ ```
2056
+
2057
+ Here is how localization config looks like for Spanish [i18n/es.js](src/i18n/es.js).
2058
+
2059
+ Find all available locales [here](src/i18n).
2060
+
2061
+
2062
+ ## Sorting Strategies
2063
+
2064
+ All supported sorting strategies are stored in `jsGrid.sortStrategies` object, where key is a name of the strategy and the value is a `sortingFunction`.
2065
+
2066
+ `jsGrid.sortStrategies` contains following build-in sorting strategies:
2067
+
2068
+ ```javascript
2069
+
2070
+ {
2071
+ string: { ... }, // string sorter
2072
+ number: { ... }, // number sorter
2073
+ date: { ... }, // date sorter
2074
+ numberAsString: { ... } // numbers are parsed before comparison
2075
+ }
2076
+
2077
+ ```
2078
+
2079
+ **sortingFunction** is a sorting function with the following format:
2080
+
2081
+ ```javascript
2082
+
2083
+ function(value1, value2) {
2084
+ if(value1 < value2) return -1; // return negative value when first is less than second
2085
+ if(value1 === value2) return 0; // return zero if values are equal
2086
+ if(value1 > value2) return 1; // return positive value when first is greater than second
2087
+ }
2088
+
2089
+ ```
2090
+
2091
+ ### Custom Sorting Strategy
2092
+
2093
+ If you need a custom sorting strategy, the object `jsGrid.sortStrategies` can be easily extended.
2094
+
2095
+ In this example we define new sorting strategy for our client objects:
2096
+
2097
+ ```javascript
2098
+
2099
+ // clients array
2100
+ var clients = [{
2101
+ Index: 1,
2102
+ Name: "John",
2103
+ Age: 25
2104
+ }, ...];
2105
+
2106
+ // sort clients by name and then by age
2107
+ jsGrid.sortStrategies.client = function(index1, index2) {
2108
+ var client1 = clients[index1];
2109
+ var client2 = clients[index2];
2110
+ return client1.Name.localeCompare(client2.Name)
2111
+ || client1.Age - client2.Age;
2112
+ };
2113
+
2114
+ ```
2115
+
2116
+ Now, our new sorting strategy `client` can be used in the grid config as follows:
2117
+
2118
+ ```javascript
2119
+
2120
+ {
2121
+ fields: [
2122
+ ...
2123
+ { name: "Index", sorter: "client" },
2124
+ ...
2125
+ ]
2126
+ }
2127
+
2128
+ ```
2129
+
2130
+ Worth to mention, that if you need particular sorting only once, you can just inline sorting function in `sorter` not registering the new strategy:
2131
+
2132
+ ```javascript
2133
+ {
2134
+ fields: [
2135
+ ...
2136
+ {
2137
+ name: "Index",
2138
+ sorter: function(index1, index2) {
2139
+ var client1 = clients[index1];
2140
+ var client2 = clients[index2];
2141
+ return client1.Name.localeCompare(client2.Name)
2142
+ || client1.Age - client2.Age;
2143
+ }
2144
+ },
2145
+ ...
2146
+ ]
2147
+ }
2148
+ ```
2149
+
2150
+ ## Load Strategies
2151
+
2152
+ The behavior of the grid regarding data source interaction is defined by load strategy.
2153
+
2154
+ The load strategy has the following methods:
2155
+
2156
+ ```javascript
2157
+ {
2158
+ firstDisplayIndex: function() {}, // returns the index of the first displayed item
2159
+ lastDisplayIndex: function() {}, // returns the index of the last displayed item
2160
+ itemsCount: function() {}, // returns the total amount of grid items
2161
+
2162
+ openPage: function(index) {}, // handles opening of the particular page
2163
+ loadParams: function() {}, // returns additional parameters for controller.loadData method
2164
+ sort: function() {}, // handles sorting of data in the grid, should return a Promise
2165
+ reset: function() {}, // handles grid refresh on grid reset with 'reset' method call, should return a Promise
2166
+
2167
+ finishLoad: function(loadedData) {}, // handles the finish of loading data by controller.loadData
2168
+ finishInsert: function(insertedItem) {}, // handles the finish of inserting item by controller.insertItem
2169
+ finishDelete: function(deletedItem, deletedItemIndex) {} // handles the finish of deleting item by controller.deleteItem
2170
+ }
2171
+ ```
2172
+
2173
+ There are two build-in load strategies: DirectLoadingStrategy (for `pageLoading=false`) and PageLoadingStrategy (for `pageLoading=true`).
2174
+
2175
+ ### DirectLoadingStrategy
2176
+
2177
+ **DirectLoadingStrategy** is used when loading by page is turned off (`pageLoading=false`).
2178
+
2179
+ It provides the following behavior:
2180
+
2181
+ - **firstDisplayIndex** returns the index of the first item on the displayed page
2182
+ - **lastDisplayIndex** returns the index of the last item on the displayed page
2183
+ - **itemsCount** returns the actual amount of all the loaded items
2184
+ - **openPage** refreshes the grid to render items of current page
2185
+ - **loadParams** returns empty object, since no extra load params are needed
2186
+ - **sort** sorts data items and refreshes the grid calling `grid.refresh`
2187
+ - **reset** calls `grid.refresh` method to refresh the grid
2188
+ - **finishLoad** puts the data coming from `controller.loadData` into the option `data` of the grid
2189
+ - **finishInsert** pushes new inserted item into the option `data` and refreshes the grid
2190
+ - **finishDelete** removes deleted item from the option `data` and resets the grid
2191
+
2192
+ ### PageLoadingStrategy
2193
+
2194
+ **PageLoadingStrategy** is used when data is loaded to the grid by pages (`pageLoading=true`).
2195
+
2196
+ It provides the following behavior:
2197
+
2198
+ - **firstDisplayIndex** returns 0, because all loaded items displayed on the current page
2199
+ - **lastDisplayIndex** returns the amount of loaded items, since data loaded by page
2200
+ - **itemsCount** returns `itemsCount` provided by `controller.loadData` (read more in section [controller.loadData](#loaddatafilter-promisedataresult))
2201
+ - **openPage** calls `grid.loadData` to load data for the current page
2202
+ - **loadParams** returns an object with the structure `{ pageIndex, pageSize }` to provide server with paging info
2203
+ - **sort** calls `grid.loadData` to load sorted data from the server
2204
+ - **reset** calls `grid.loadData` method to refresh the data
2205
+ - **finishLoad** saves `itemsCount` returned by server and puts the `data` into the option `data` of the grid
2206
+ - **finishInsert** calls `grid.search` to reload the data
2207
+ - **finishDelete** calls `grid.search` to reload the data
2208
+
2209
+ ### Custom LoadStrategy
2210
+
2211
+ The option `loadStrategy` allows to specify a custom load strategy to customize the behavior of the grid.
2212
+ The easiest way to do it is to inherit from existing strategy.
2213
+
2214
+ By default DirectLoadingStrategy resets the grid (resets the paging and sorting) when an item is deleted.
2215
+ The following example shows how to create a custom strategy to avoid grid reset on deletion of an item.
2216
+
2217
+ ```javascript
2218
+ var MyCustomDirectLoadStrategy = function(grid) {
2219
+ jsGrid.loadStrategies.DirectLoadingStrategy.call(this, grid);
2220
+ };
2221
+
2222
+ MyCustomDirectLoadStrategy.prototype = new jsGrid.loadStrategies.DirectLoadingStrategy();
2223
+
2224
+ MyCustomDirectLoadStrategy.prototype.finishDelete = function(deletedItem, deletedItemIndex) {
2225
+ var grid = this._grid;
2226
+ grid.option("data").splice(deletedItemIndex, 1);
2227
+ grid.refresh();
2228
+ };
2229
+
2230
+ // use custom strategy in grid config
2231
+ $("#grid").jsGrid({
2232
+
2233
+ loadStrategy: function() {
2234
+ return new MyCustomDirectLoadStrategy(this);
2235
+ },
2236
+
2237
+ ...
2238
+
2239
+ });
2240
+
2241
+ ```
2242
+
2243
+
2244
+ ## Load Indication
2245
+
2246
+ By default jsGrid uses jsGrid.LoadIndicator. Load indicator can be customized with the `loadIndicator` option.
2247
+ Set an object or a function returning an object supporting the following interface:
2248
+
2249
+ ```javascript
2250
+ {
2251
+ show: function() { ... } // called on loading start
2252
+ hide: function() { ... } // called on loading finish
2253
+ }
2254
+ ```
2255
+
2256
+ This simple example prints messages to console instead of showing load indicator:
2257
+
2258
+ ```javascript
2259
+ {
2260
+ loadIndicator: {
2261
+ show: function() {
2262
+ console.log("loading started");
2263
+ },
2264
+ hide: function() {
2265
+ console.log("loading finished");
2266
+ }
2267
+ }
2268
+ }
2269
+ ```
2270
+
2271
+ If `loadIndicator` is a function, it accepts the config of load indicator in the following format:
2272
+
2273
+ ```javascript
2274
+ {
2275
+ container, // grid container div
2276
+ message, // the loading message is a value of the option loadMessage
2277
+ shading // the boolean value defining whether to show shading. This is a value of the option loadShading
2278
+ }
2279
+ ```
2280
+
2281
+ The similar example printing messages to console shows how to configure loading indicator with a function returning an object:
2282
+
2283
+ ```javascript
2284
+ {
2285
+ loadIndicator: function(config) {
2286
+ return {
2287
+ show: function() {
2288
+ console.log("loading started: " + config.message);
2289
+ },
2290
+ hide: function() {
2291
+ console.log("loading finished");
2292
+ }
2293
+ };
2294
+ }
2295
+ }
2296
+ ```
2297
+
2298
+ Customization of loading indicator is useful, when you want to use any external load indicator that is used for all other ajax requests on the page.
2299
+
2300
+ This example shows how to use [spin.js](http://fgnass.github.io/spin.js/) to indicate loading:
2301
+
2302
+ ```javascript
2303
+ {
2304
+ loadIndicator: function(config) {
2305
+ var container = config.container[0];
2306
+ var spinner = new Spinner();
2307
+
2308
+ return {
2309
+ show: function() {
2310
+ spinner.spin(container);
2311
+ },
2312
+ hide: function() {
2313
+ spinner.stop();
2314
+ }
2315
+ };
2316
+ }
2317
+ }
2318
+ ```
2319
+
2320
+ ## Requirement
2321
+
2322
+ jQuery (3.0 or later). `Xjsoneditor` additionally requires [jsoneditor](https://www.npmjs.com/package/jsoneditor)
2323
+ to be loaded; `Xselect`'s `select2` option requires [select2](https://select2.org/) — both are optional and
2324
+ only needed if you actually use that field/option.
2325
+
2326
+
2327
+ ## Compatibility
2328
+
2329
+ Any current evergreen browser (Chrome, Firefox, Safari, Edge) on desktop and mobile.