slickgrid 2.3.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +20 -0
  4. data/README.md +30 -0
  5. data/lib/slickgrid.rb +6 -0
  6. data/lib/slickgrid/version.rb +3 -0
  7. data/slickgrid.gemspec +20 -0
  8. data/vendor/assets/images/slickgrid/CheckboxN.png +0 -0
  9. data/vendor/assets/images/slickgrid/CheckboxY.png +0 -0
  10. data/vendor/assets/images/slickgrid/GrpCheckboxN.png +0 -0
  11. data/vendor/assets/images/slickgrid/GrpCheckboxY.png +0 -0
  12. data/vendor/assets/images/slickgrid/actions.gif +0 -0
  13. data/vendor/assets/images/slickgrid/ajax-loader-small.gif +0 -0
  14. data/vendor/assets/images/slickgrid/arrow-right.gif +0 -0
  15. data/vendor/assets/images/slickgrid/arrow_redo.png +0 -0
  16. data/vendor/assets/images/slickgrid/arrow_right_peppermint.png +0 -0
  17. data/vendor/assets/images/slickgrid/arrow_right_spearmint.png +0 -0
  18. data/vendor/assets/images/slickgrid/arrow_undo.png +0 -0
  19. data/vendor/assets/images/slickgrid/bullet_blue.png +0 -0
  20. data/vendor/assets/images/slickgrid/bullet_star.png +0 -0
  21. data/vendor/assets/images/slickgrid/bullet_toggle_minus.png +0 -0
  22. data/vendor/assets/images/slickgrid/bullet_toggle_plus.png +0 -0
  23. data/vendor/assets/images/slickgrid/calendar.gif +0 -0
  24. data/vendor/assets/images/slickgrid/collapse.gif +0 -0
  25. data/vendor/assets/images/slickgrid/comment_yellow.gif +0 -0
  26. data/vendor/assets/images/slickgrid/delete.png +0 -0
  27. data/vendor/assets/images/slickgrid/down.gif +0 -0
  28. data/vendor/assets/images/slickgrid/drag-handle.png +0 -0
  29. data/vendor/assets/images/slickgrid/editor-helper-bg.gif +0 -0
  30. data/vendor/assets/images/slickgrid/expand.gif +0 -0
  31. data/vendor/assets/images/slickgrid/header-bg.gif +0 -0
  32. data/vendor/assets/images/slickgrid/header-columns-bg.gif +0 -0
  33. data/vendor/assets/images/slickgrid/header-columns-over-bg.gif +0 -0
  34. data/vendor/assets/images/slickgrid/help.png +0 -0
  35. data/vendor/assets/images/slickgrid/info.gif +0 -0
  36. data/vendor/assets/images/slickgrid/listview.gif +0 -0
  37. data/vendor/assets/images/slickgrid/pencil.gif +0 -0
  38. data/vendor/assets/images/slickgrid/row-over-bg.gif +0 -0
  39. data/vendor/assets/images/slickgrid/sort-asc.gif +0 -0
  40. data/vendor/assets/images/slickgrid/sort-asc.png +0 -0
  41. data/vendor/assets/images/slickgrid/sort-desc.gif +0 -0
  42. data/vendor/assets/images/slickgrid/sort-desc.png +0 -0
  43. data/vendor/assets/images/slickgrid/stripes.png +0 -0
  44. data/vendor/assets/images/slickgrid/tag_red.png +0 -0
  45. data/vendor/assets/images/slickgrid/tick.png +0 -0
  46. data/vendor/assets/images/slickgrid/user_identity.gif +0 -0
  47. data/vendor/assets/images/slickgrid/user_identity_plus.gif +0 -0
  48. data/vendor/assets/javascripts/slickgrid.js +5 -0
  49. data/vendor/assets/javascripts/slickgrid/controls/columnpicker.js +221 -0
  50. data/vendor/assets/javascripts/slickgrid/controls/gridmenu.js +429 -0
  51. data/vendor/assets/javascripts/slickgrid/controls/pager.js +154 -0
  52. data/vendor/assets/javascripts/slickgrid/core.js +493 -0
  53. data/vendor/assets/javascripts/slickgrid/dataview.js +1220 -0
  54. data/vendor/assets/javascripts/slickgrid/editors.js +640 -0
  55. data/vendor/assets/javascripts/slickgrid/formatters.js +65 -0
  56. data/vendor/assets/javascripts/slickgrid/grid.js +3990 -0
  57. data/vendor/assets/javascripts/slickgrid/groupitemmetadataprovider.js +172 -0
  58. data/vendor/assets/javascripts/slickgrid/plugins/autotooltips.js +83 -0
  59. data/vendor/assets/javascripts/slickgrid/plugins/cellcopymanager.js +88 -0
  60. data/vendor/assets/javascripts/slickgrid/plugins/cellexternalcopymanager.js +452 -0
  61. data/vendor/assets/javascripts/slickgrid/plugins/cellrangedecorator.js +72 -0
  62. data/vendor/assets/javascripts/slickgrid/plugins/cellrangeselector.js +123 -0
  63. data/vendor/assets/javascripts/slickgrid/plugins/cellselectionmodel.js +168 -0
  64. data/vendor/assets/javascripts/slickgrid/plugins/checkboxselectcolumn.js +202 -0
  65. data/vendor/assets/javascripts/slickgrid/plugins/draggablegrouping.js +207 -0
  66. data/vendor/assets/javascripts/slickgrid/plugins/headerbuttons.js +177 -0
  67. data/vendor/assets/javascripts/slickgrid/plugins/headermenu.js +296 -0
  68. data/vendor/assets/javascripts/slickgrid/plugins/rowdetailview.js +455 -0
  69. data/vendor/assets/javascripts/slickgrid/plugins/rowmovemanager.js +138 -0
  70. data/vendor/assets/javascripts/slickgrid/plugins/rowselectionmodel.js +191 -0
  71. data/vendor/assets/javascripts/slickgrid/remotemodel.js +169 -0
  72. data/vendor/assets/stylesheets/slickgrid.scss +1 -0
  73. data/vendor/assets/stylesheets/slickgrid/controls/columnpicker.css +46 -0
  74. data/vendor/assets/stylesheets/slickgrid/controls/gridmenu.css +113 -0
  75. data/vendor/assets/stylesheets/slickgrid/controls/pager.css +41 -0
  76. data/vendor/assets/stylesheets/slickgrid/default-theme.css +132 -0
  77. data/vendor/assets/stylesheets/slickgrid/grid.css +189 -0
  78. data/vendor/assets/stylesheets/slickgrid/plugins/headerbuttons.css +39 -0
  79. data/vendor/assets/stylesheets/slickgrid/plugins/headermenu.css +59 -0
  80. data/vendor/assets/stylesheets/slickgrid/plugins/rowdetailview.css +39 -0
  81. metadata +165 -0
@@ -0,0 +1,640 @@
1
+ /***
2
+ * Contains basic SlickGrid editors.
3
+ * @module Editors
4
+ * @namespace Slick
5
+ */
6
+
7
+ (function ($) {
8
+ // register namespace
9
+ $.extend(true, window, {
10
+ "Slick": {
11
+ "Editors": {
12
+ "Text": TextEditor,
13
+ "Integer": IntegerEditor,
14
+ "Float": FloatEditor,
15
+ "Date": DateEditor,
16
+ "YesNoSelect": YesNoSelectEditor,
17
+ "Checkbox": CheckboxEditor,
18
+ "PercentComplete": PercentCompleteEditor,
19
+ "LongText": LongTextEditor
20
+ }
21
+ }
22
+ });
23
+
24
+ function TextEditor(args) {
25
+ var $input;
26
+ var defaultValue;
27
+ var scope = this;
28
+
29
+ this.init = function () {
30
+ $input = $("<INPUT type=text class='editor-text' />")
31
+ .appendTo(args.container)
32
+ .on("keydown.nav", function (e) {
33
+ if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
34
+ e.stopImmediatePropagation();
35
+ }
36
+ })
37
+ .focus()
38
+ .select();
39
+ };
40
+
41
+ this.destroy = function () {
42
+ $input.remove();
43
+ };
44
+
45
+ this.focus = function () {
46
+ $input.focus();
47
+ };
48
+
49
+ this.getValue = function () {
50
+ return $input.val();
51
+ };
52
+
53
+ this.setValue = function (val) {
54
+ $input.val(val);
55
+ };
56
+
57
+ this.loadValue = function (item) {
58
+ defaultValue = item[args.column.field] || "";
59
+ $input.val(defaultValue);
60
+ $input[0].defaultValue = defaultValue;
61
+ $input.select();
62
+ };
63
+
64
+ this.serializeValue = function () {
65
+ return $input.val();
66
+ };
67
+
68
+ this.applyValue = function (item, state) {
69
+ item[args.column.field] = state;
70
+ };
71
+
72
+ this.isValueChanged = function () {
73
+ return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
74
+ };
75
+
76
+ this.validate = function () {
77
+ if (args.column.validator) {
78
+ var validationResults = args.column.validator($input.val());
79
+ if (!validationResults.valid) {
80
+ return validationResults;
81
+ }
82
+ }
83
+
84
+ return {
85
+ valid: true,
86
+ msg: null
87
+ };
88
+ };
89
+
90
+ this.init();
91
+ }
92
+
93
+ function IntegerEditor(args) {
94
+ var $input;
95
+ var defaultValue;
96
+ var scope = this;
97
+
98
+ this.init = function () {
99
+ $input = $("<INPUT type=text class='editor-text' />");
100
+
101
+ $input.on("keydown.nav", function (e) {
102
+ if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
103
+ e.stopImmediatePropagation();
104
+ }
105
+ });
106
+
107
+ $input.appendTo(args.container);
108
+ $input.focus().select();
109
+ };
110
+
111
+ this.destroy = function () {
112
+ $input.remove();
113
+ };
114
+
115
+ this.focus = function () {
116
+ $input.focus();
117
+ };
118
+
119
+ this.loadValue = function (item) {
120
+ defaultValue = item[args.column.field];
121
+ $input.val(defaultValue);
122
+ $input[0].defaultValue = defaultValue;
123
+ $input.select();
124
+ };
125
+
126
+ this.serializeValue = function () {
127
+ return parseInt($input.val(), 10) || 0;
128
+ };
129
+
130
+ this.applyValue = function (item, state) {
131
+ item[args.column.field] = state;
132
+ };
133
+
134
+ this.isValueChanged = function () {
135
+ return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
136
+ };
137
+
138
+ this.validate = function () {
139
+ if (isNaN($input.val())) {
140
+ return {
141
+ valid: false,
142
+ msg: "Please enter a valid integer"
143
+ };
144
+ }
145
+
146
+ if (args.column.validator) {
147
+ var validationResults = args.column.validator($input.val());
148
+ if (!validationResults.valid) {
149
+ return validationResults;
150
+ }
151
+ }
152
+
153
+ return {
154
+ valid: true,
155
+ msg: null
156
+ };
157
+ };
158
+
159
+ this.init();
160
+ }
161
+
162
+ function FloatEditor(args) {
163
+ var $input;
164
+ var defaultValue;
165
+ var scope = this;
166
+
167
+ this.init = function () {
168
+ $input = $("<INPUT type=text class='editor-text' />");
169
+
170
+ $input.on("keydown.nav", function (e) {
171
+ if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
172
+ e.stopImmediatePropagation();
173
+ }
174
+ });
175
+
176
+ $input.appendTo(args.container);
177
+ $input.focus().select();
178
+ };
179
+
180
+ this.destroy = function () {
181
+ $input.remove();
182
+ };
183
+
184
+ this.focus = function () {
185
+ $input.focus();
186
+ };
187
+
188
+ function getDecimalPlaces() {
189
+ // returns the number of fixed decimal places or null
190
+ var rtn = args.column.editorFixedDecimalPlaces;
191
+ if (typeof rtn == 'undefined') {
192
+ rtn = FloatEditor.DefaultDecimalPlaces;
193
+ }
194
+ return (!rtn && rtn!==0 ? null : rtn);
195
+ }
196
+
197
+ this.loadValue = function (item) {
198
+ defaultValue = item[args.column.field];
199
+
200
+ var decPlaces = getDecimalPlaces();
201
+ if (decPlaces !== null
202
+ && (defaultValue || defaultValue===0)
203
+ && defaultValue.toFixed) {
204
+ defaultValue = defaultValue.toFixed(decPlaces);
205
+ }
206
+
207
+ $input.val(defaultValue);
208
+ $input[0].defaultValue = defaultValue;
209
+ $input.select();
210
+ };
211
+
212
+ this.serializeValue = function () {
213
+ var rtn = parseFloat($input.val());
214
+ if (FloatEditor.AllowEmptyValue) {
215
+ if (!rtn && rtn !==0) { rtn = ''; }
216
+ } else {
217
+ rtn = rtn || 0;
218
+ }
219
+
220
+ var decPlaces = getDecimalPlaces();
221
+ if (decPlaces !== null
222
+ && (rtn || rtn===0)
223
+ && rtn.toFixed) {
224
+ rtn = parseFloat(rtn.toFixed(decPlaces));
225
+ }
226
+
227
+ return rtn;
228
+ };
229
+
230
+ this.applyValue = function (item, state) {
231
+ item[args.column.field] = state;
232
+ };
233
+
234
+ this.isValueChanged = function () {
235
+ return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
236
+ };
237
+
238
+ this.validate = function () {
239
+ if (isNaN($input.val())) {
240
+ return {
241
+ valid: false,
242
+ msg: "Please enter a valid number"
243
+ };
244
+ }
245
+
246
+ if (args.column.validator) {
247
+ var validationResults = args.column.validator($input.val());
248
+ if (!validationResults.valid) {
249
+ return validationResults;
250
+ }
251
+ }
252
+
253
+ return {
254
+ valid: true,
255
+ msg: null
256
+ };
257
+ };
258
+
259
+ this.init();
260
+ }
261
+
262
+ FloatEditor.DefaultDecimalPlaces = null;
263
+ FloatEditor.AllowEmptyValue = false;
264
+
265
+ function DateEditor(args) {
266
+ var $input;
267
+ var defaultValue;
268
+ var scope = this;
269
+ var calendarOpen = false;
270
+
271
+ this.init = function () {
272
+ $input = $("<INPUT type=text class='editor-text' />");
273
+ $input.appendTo(args.container);
274
+ $input.focus().select();
275
+ $input.datepicker({
276
+ showOn: "button",
277
+ buttonImageOnly: true,
278
+ beforeShow: function () {
279
+ calendarOpen = true
280
+ },
281
+ onClose: function () {
282
+ calendarOpen = false
283
+ }
284
+ });
285
+ $input.width($input.width() - 18);
286
+ };
287
+
288
+ this.destroy = function () {
289
+ $.datepicker.dpDiv.stop(true, true);
290
+ $input.datepicker("hide");
291
+ $input.datepicker("destroy");
292
+ $input.remove();
293
+ };
294
+
295
+ this.show = function () {
296
+ if (calendarOpen) {
297
+ $.datepicker.dpDiv.stop(true, true).show();
298
+ }
299
+ };
300
+
301
+ this.hide = function () {
302
+ if (calendarOpen) {
303
+ $.datepicker.dpDiv.stop(true, true).hide();
304
+ }
305
+ };
306
+
307
+ this.position = function (position) {
308
+ if (!calendarOpen) {
309
+ return;
310
+ }
311
+ $.datepicker.dpDiv
312
+ .css("top", position.top + 30)
313
+ .css("left", position.left);
314
+ };
315
+
316
+ this.focus = function () {
317
+ $input.focus();
318
+ };
319
+
320
+ this.loadValue = function (item) {
321
+ defaultValue = item[args.column.field];
322
+ $input.val(defaultValue);
323
+ $input[0].defaultValue = defaultValue;
324
+ $input.select();
325
+ };
326
+
327
+ this.serializeValue = function () {
328
+ return $input.val();
329
+ };
330
+
331
+ this.applyValue = function (item, state) {
332
+ item[args.column.field] = state;
333
+ };
334
+
335
+ this.isValueChanged = function () {
336
+ return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
337
+ };
338
+
339
+ this.validate = function () {
340
+ if (args.column.validator) {
341
+ var validationResults = args.column.validator($input.val());
342
+ if (!validationResults.valid) {
343
+ return validationResults;
344
+ }
345
+ }
346
+
347
+ return {
348
+ valid: true,
349
+ msg: null
350
+ };
351
+ };
352
+
353
+ this.init();
354
+ }
355
+
356
+ function YesNoSelectEditor(args) {
357
+ var $select;
358
+ var defaultValue;
359
+ var scope = this;
360
+
361
+ this.init = function () {
362
+ $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");
363
+ $select.appendTo(args.container);
364
+ $select.focus();
365
+ };
366
+
367
+ this.destroy = function () {
368
+ $select.remove();
369
+ };
370
+
371
+ this.focus = function () {
372
+ $select.focus();
373
+ };
374
+
375
+ this.loadValue = function (item) {
376
+ $select.val((defaultValue = item[args.column.field]) ? "yes" : "no");
377
+ $select.select();
378
+ };
379
+
380
+ this.serializeValue = function () {
381
+ return ($select.val() == "yes");
382
+ };
383
+
384
+ this.applyValue = function (item, state) {
385
+ item[args.column.field] = state;
386
+ };
387
+
388
+ this.isValueChanged = function () {
389
+ return ($select.val() != defaultValue);
390
+ };
391
+
392
+ this.validate = function () {
393
+ return {
394
+ valid: true,
395
+ msg: null
396
+ };
397
+ };
398
+
399
+ this.init();
400
+ }
401
+
402
+ function CheckboxEditor(args) {
403
+ var $select;
404
+ var defaultValue;
405
+ var scope = this;
406
+
407
+ this.init = function () {
408
+ $select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus>");
409
+ $select.appendTo(args.container);
410
+ $select.focus();
411
+ };
412
+
413
+ this.destroy = function () {
414
+ $select.remove();
415
+ };
416
+
417
+ this.focus = function () {
418
+ $select.focus();
419
+ };
420
+
421
+ this.loadValue = function (item) {
422
+ defaultValue = !!item[args.column.field];
423
+ if (defaultValue) {
424
+ $select.prop('checked', true);
425
+ } else {
426
+ $select.prop('checked', false);
427
+ }
428
+ };
429
+
430
+ this.preClick = function () {
431
+ $select.prop('checked', !$select.prop('checked'));
432
+ };
433
+
434
+ this.serializeValue = function () {
435
+ return $select.prop('checked');
436
+ };
437
+
438
+ this.applyValue = function (item, state) {
439
+ item[args.column.field] = state;
440
+ };
441
+
442
+ this.isValueChanged = function () {
443
+ return (this.serializeValue() !== defaultValue);
444
+ };
445
+
446
+ this.validate = function () {
447
+ return {
448
+ valid: true,
449
+ msg: null
450
+ };
451
+ };
452
+
453
+ this.init();
454
+ }
455
+
456
+ function PercentCompleteEditor(args) {
457
+ var $input, $picker;
458
+ var defaultValue;
459
+ var scope = this;
460
+
461
+ this.init = function () {
462
+ $input = $("<INPUT type=text class='editor-percentcomplete' />");
463
+ $input.width($(args.container).innerWidth() - 25);
464
+ $input.appendTo(args.container);
465
+
466
+ $picker = $("<div class='editor-percentcomplete-picker' />").appendTo(args.container);
467
+ $picker.append("<div class='editor-percentcomplete-helper'><div class='editor-percentcomplete-wrapper'><div class='editor-percentcomplete-slider' /><div class='editor-percentcomplete-buttons' /></div></div>");
468
+
469
+ $picker.find(".editor-percentcomplete-buttons").append("<button val=0>Not started</button><br/><button val=50>In Progress</button><br/><button val=100>Complete</button>");
470
+
471
+ $input.focus().select();
472
+
473
+ $picker.find(".editor-percentcomplete-slider").slider({
474
+ orientation: "vertical",
475
+ range: "min",
476
+ value: defaultValue,
477
+ slide: function (event, ui) {
478
+ $input.val(ui.value)
479
+ }
480
+ });
481
+
482
+ $picker.find(".editor-percentcomplete-buttons button").on("click", function (e) {
483
+ $input.val($(this).attr("val"));
484
+ $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
485
+ })
486
+ };
487
+
488
+ this.destroy = function () {
489
+ $input.remove();
490
+ $picker.remove();
491
+ };
492
+
493
+ this.focus = function () {
494
+ $input.focus();
495
+ };
496
+
497
+ this.loadValue = function (item) {
498
+ $input.val(defaultValue = item[args.column.field]);
499
+ $input.select();
500
+ };
501
+
502
+ this.serializeValue = function () {
503
+ return parseInt($input.val(), 10) || 0;
504
+ };
505
+
506
+ this.applyValue = function (item, state) {
507
+ item[args.column.field] = state;
508
+ };
509
+
510
+ this.isValueChanged = function () {
511
+ return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
512
+ };
513
+
514
+ this.validate = function () {
515
+ if (isNaN(parseInt($input.val(), 10))) {
516
+ return {
517
+ valid: false,
518
+ msg: "Please enter a valid positive number"
519
+ };
520
+ }
521
+
522
+ return {
523
+ valid: true,
524
+ msg: null
525
+ };
526
+ };
527
+
528
+ this.init();
529
+ }
530
+
531
+ /*
532
+ * An example of a "detached" editor.
533
+ * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.
534
+ * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
535
+ */
536
+ function LongTextEditor(args) {
537
+ var $input, $wrapper;
538
+ var defaultValue;
539
+ var scope = this;
540
+
541
+ this.init = function () {
542
+ var $container = $("body");
543
+
544
+ $wrapper = $("<DIV style='z-index:10000;position:absolute;background:white;padding:5px;border:3px solid gray; -moz-border-radius:10px; border-radius:10px;'/>")
545
+ .appendTo($container);
546
+
547
+ $input = $("<TEXTAREA hidefocus rows=5 style='background:white;width:250px;height:80px;border:0;outline:0'>")
548
+ .appendTo($wrapper);
549
+
550
+ $("<DIV style='text-align:right'><BUTTON>Save</BUTTON><BUTTON>Cancel</BUTTON></DIV>")
551
+ .appendTo($wrapper);
552
+
553
+ $wrapper.find("button:first").on("click", this.save);
554
+ $wrapper.find("button:last").on("click", this.cancel);
555
+ $input.on("keydown", this.handleKeyDown);
556
+
557
+ scope.position(args.position);
558
+ $input.focus().select();
559
+ };
560
+
561
+ this.handleKeyDown = function (e) {
562
+ if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
563
+ scope.save();
564
+ } else if (e.which == $.ui.keyCode.ESCAPE) {
565
+ e.preventDefault();
566
+ scope.cancel();
567
+ } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
568
+ e.preventDefault();
569
+ args.grid.navigatePrev();
570
+ } else if (e.which == $.ui.keyCode.TAB) {
571
+ e.preventDefault();
572
+ args.grid.navigateNext();
573
+ }
574
+ };
575
+
576
+ this.save = function () {
577
+ args.commitChanges();
578
+ };
579
+
580
+ this.cancel = function () {
581
+ $input.val(defaultValue);
582
+ args.cancelChanges();
583
+ };
584
+
585
+ this.hide = function () {
586
+ $wrapper.hide();
587
+ };
588
+
589
+ this.show = function () {
590
+ $wrapper.show();
591
+ };
592
+
593
+ this.position = function (position) {
594
+ $wrapper
595
+ .css("top", position.top - 5)
596
+ .css("left", position.left - 5)
597
+ };
598
+
599
+ this.destroy = function () {
600
+ $wrapper.remove();
601
+ };
602
+
603
+ this.focus = function () {
604
+ $input.focus();
605
+ };
606
+
607
+ this.loadValue = function (item) {
608
+ $input.val(defaultValue = item[args.column.field]);
609
+ $input.select();
610
+ };
611
+
612
+ this.serializeValue = function () {
613
+ return $input.val();
614
+ };
615
+
616
+ this.applyValue = function (item, state) {
617
+ item[args.column.field] = state;
618
+ };
619
+
620
+ this.isValueChanged = function () {
621
+ return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
622
+ };
623
+
624
+ this.validate = function () {
625
+ if (args.column.validator) {
626
+ var validationResults = args.column.validator($input.val());
627
+ if (!validationResults.valid) {
628
+ return validationResults;
629
+ }
630
+ }
631
+
632
+ return {
633
+ valid: true,
634
+ msg: null
635
+ };
636
+ };
637
+
638
+ this.init();
639
+ }
640
+ })(jQuery);