2 * Contains basic SlickGrid editors.
9 $.extend(true, window, {
13 "Integer": IntegerEditor,
15 "YesNoSelect": YesNoSelectEditor,
16 "Checkbox": CheckboxEditor,
17 "PercentComplete": PercentCompleteEditor,
18 "LongText": LongTextEditor
23 function TextEditor(args) {
28 this.init = function () {
29 $input = $("<INPUT type=text class='editor-text' />")
30 .appendTo(args.container)
31 .bind("keydown.nav", function (e) {
32 if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
33 e.stopImmediatePropagation();
40 this.destroy = function () {
44 this.focus = function () {
48 this.getValue = function () {
52 this.setValue = function (val) {
56 this.loadValue = function (item) {
57 defaultValue = item[args.column.field] || "";
58 $input.val(defaultValue);
59 $input[0].defaultValue = defaultValue;
63 this.serializeValue = function () {
67 this.applyValue = function (item, state) {
68 item[args.column.field] = state;
71 this.isValueChanged = function () {
72 return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
75 this.validate = function () {
76 if (args.column.validator) {
77 var validationResults = args.column.validator($input.val());
78 if (!validationResults.valid) {
79 return validationResults;
92 function IntegerEditor(args) {
97 this.init = function () {
98 $input = $("<INPUT type=text class='editor-text' />");
100 $input.bind("keydown.nav", function (e) {
101 if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
102 e.stopImmediatePropagation();
106 $input.appendTo(args.container);
107 $input.focus().select();
110 this.destroy = function () {
114 this.focus = function () {
118 this.loadValue = function (item) {
119 defaultValue = item[args.column.field];
120 $input.val(defaultValue);
121 $input[0].defaultValue = defaultValue;
125 this.serializeValue = function () {
126 return parseInt($input.val(), 10) || 0;
129 this.applyValue = function (item, state) {
130 item[args.column.field] = state;
133 this.isValueChanged = function () {
134 return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
137 this.validate = function () {
138 if (isNaN($input.val())) {
141 msg: "Please enter a valid integer"
154 function DateEditor(args) {
158 var calendarOpen = false;
160 this.init = function () {
161 $input = $("<INPUT type=text class='editor-text' />");
162 $input.appendTo(args.container);
163 $input.focus().select();
166 buttonImageOnly: true,
167 buttonImage: "../images/calendar.gif",
168 beforeShow: function () {
171 onClose: function () {
175 $input.width($input.width() - 18);
178 this.destroy = function () {
179 $.datepicker.dpDiv.stop(true, true);
180 $input.datepicker("hide");
181 $input.datepicker("destroy");
185 this.show = function () {
187 $.datepicker.dpDiv.stop(true, true).show();
191 this.hide = function () {
193 $.datepicker.dpDiv.stop(true, true).hide();
197 this.position = function (position) {
202 .css("top", position.top + 30)
203 .css("left", position.left);
206 this.focus = function () {
210 this.loadValue = function (item) {
211 defaultValue = item[args.column.field];
212 $input.val(defaultValue);
213 $input[0].defaultValue = defaultValue;
217 this.serializeValue = function () {
221 this.applyValue = function (item, state) {
222 item[args.column.field] = state;
225 this.isValueChanged = function () {
226 return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
229 this.validate = function () {
239 function YesNoSelectEditor(args) {
244 this.init = function () {
245 $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");
246 $select.appendTo(args.container);
250 this.destroy = function () {
254 this.focus = function () {
258 this.loadValue = function (item) {
259 $select.val((defaultValue = item[args.column.field]) ? "yes" : "no");
263 this.serializeValue = function () {
264 return ($select.val() == "yes");
267 this.applyValue = function (item, state) {
268 item[args.column.field] = state;
271 this.isValueChanged = function () {
272 return ($select.val() != defaultValue);
275 this.validate = function () {
285 function CheckboxEditor(args) {
290 this.init = function () {
291 $select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus>");
292 $select.appendTo(args.container);
296 this.destroy = function () {
300 this.focus = function () {
304 this.loadValue = function (item) {
305 defaultValue = !!item[args.column.field];
307 $select.attr("checked", "checked");
309 $select.removeAttr("checked");
313 this.serializeValue = function () {
314 return !!$select.attr("checked");
317 this.applyValue = function (item, state) {
318 item[args.column.field] = state;
321 this.isValueChanged = function () {
322 return (this.serializeValue() !== defaultValue);
325 this.validate = function () {
335 function PercentCompleteEditor(args) {
340 this.init = function () {
341 $input = $("<INPUT type=text class='editor-percentcomplete' />");
342 $input.width($(args.container).innerWidth() - 25);
343 $input.appendTo(args.container);
345 $picker = $("<div class='editor-percentcomplete-picker' />").appendTo(args.container);
346 $picker.append("<div class='editor-percentcomplete-helper'><div class='editor-percentcomplete-wrapper'><div class='editor-percentcomplete-slider' /><div class='editor-percentcomplete-buttons' /></div></div>");
348 $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>");
350 $input.focus().select();
352 $picker.find(".editor-percentcomplete-slider").slider({
353 orientation: "vertical",
356 slide: function (event, ui) {
361 $picker.find(".editor-percentcomplete-buttons button").bind("click", function (e) {
362 $input.val($(this).attr("val"));
363 $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
367 this.destroy = function () {
372 this.focus = function () {
376 this.loadValue = function (item) {
377 $input.val(defaultValue = item[args.column.field]);
381 this.serializeValue = function () {
382 return parseInt($input.val(), 10) || 0;
385 this.applyValue = function (item, state) {
386 item[args.column.field] = state;
389 this.isValueChanged = function () {
390 return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
393 this.validate = function () {
394 if (isNaN(parseInt($input.val(), 10))) {
397 msg: "Please enter a valid positive number"
411 * An example of a "detached" editor.
412 * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.
413 * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
415 function LongTextEditor(args) {
416 var $input, $wrapper;
420 this.init = function () {
421 var $container = $("body");
423 $wrapper = $("<DIV style='z-index:10000;position:absolute;background:white;padding:5px;border:3px solid gray; -moz-border-radius:10px; border-radius:10px;'/>")
424 .appendTo($container);
426 $input = $("<TEXTAREA hidefocus rows=5 style='backround:white;width:250px;height:80px;border:0;outline:0'>")
429 $("<DIV style='text-align:right'><BUTTON>Save</BUTTON><BUTTON>Cancel</BUTTON></DIV>")
432 $wrapper.find("button:first").bind("click", this.save);
433 $wrapper.find("button:last").bind("click", this.cancel);
434 $input.bind("keydown", this.handleKeyDown);
436 scope.position(args.position);
437 $input.focus().select();
440 this.handleKeyDown = function (e) {
441 if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
443 } else if (e.which == $.ui.keyCode.ESCAPE) {
446 } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
448 args.grid.navigatePrev();
449 } else if (e.which == $.ui.keyCode.TAB) {
451 args.grid.navigateNext();
455 this.save = function () {
456 args.commitChanges();
459 this.cancel = function () {
460 $input.val(defaultValue);
461 args.cancelChanges();
464 this.hide = function () {
468 this.show = function () {
472 this.position = function (position) {
474 .css("top", position.top - 5)
475 .css("left", position.left - 5)
478 this.destroy = function () {
482 this.focus = function () {
486 this.loadValue = function (item) {
487 $input.val(defaultValue = item[args.column.field]);
491 this.serializeValue = function () {
495 this.applyValue = function (item, state) {
496 item[args.column.field] = state;
499 this.isValueChanged = function () {
500 return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
503 this.validate = function () {