2016-08-29 09:47:01 -05:00
|
|
|
/***
|
|
|
|
* Contains JSON SlickGrid editors.
|
|
|
|
* @module Editors
|
|
|
|
* @namespace Slick
|
|
|
|
*/
|
|
|
|
|
|
|
|
(function ($) {
|
|
|
|
// register namespace
|
|
|
|
$.extend(true, window, {
|
|
|
|
"Slick": {
|
|
|
|
"Editors": {
|
|
|
|
"pgText": pgTextEditor,
|
2016-09-12 06:39:40 -05:00
|
|
|
"JsonText": JsonTextEditor,
|
2017-05-27 13:51:02 -05:00
|
|
|
"CustomNumber": CustomNumberEditor,
|
2017-11-21 11:22:25 -06:00
|
|
|
"Checkbox": pgCheckboxEditor,
|
2016-09-12 06:39:40 -05:00
|
|
|
// Below editor will read only editors, Just to display data
|
|
|
|
"ReadOnlyText": ReadOnlyTextEditor,
|
|
|
|
"ReadOnlyCheckbox": ReadOnlyCheckboxEditor,
|
|
|
|
"ReadOnlypgText": ReadOnlypgTextEditor,
|
2017-05-27 13:51:02 -05:00
|
|
|
"ReadOnlyJsonText": ReadOnlyJsonTextEditor
|
2016-08-29 09:47:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
// return wrapper element
|
|
|
|
function getWrapper() {
|
|
|
|
return $("<div class='pg_text_editor' />");
|
|
|
|
}
|
|
|
|
|
|
|
|
// return textarea element
|
|
|
|
function getTextArea() {
|
|
|
|
return $("<textarea class='pg_textarea text-12' hidefocus rows=5'>");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate and return editor buttons
|
|
|
|
function getButtons(editable) {
|
|
|
|
var $buttons = $("<div class='pg_buttons' />"),
|
2017-07-18 09:13:16 -05:00
|
|
|
label = editable ? 'Cancel': 'OK',
|
2017-06-14 06:18:27 -05:00
|
|
|
button_type = editable ? 'btn-danger' : 'btn-primary';
|
|
|
|
|
|
|
|
if (editable) {
|
|
|
|
var $save_button = $("<button class='btn btn-primary fa fa-lg fa-save long_text_editor pg-alertify-button'>Save</button>")
|
|
|
|
.appendTo($buttons);
|
|
|
|
}
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
var $cancel_button = $("<button class='btn " + button_type + " fa fa-lg fa-times long_text_editor pg-alertify-button'>"+ label +"</button>")
|
2017-06-14 06:18:27 -05:00
|
|
|
.appendTo($buttons);
|
|
|
|
return $buttons;
|
|
|
|
}
|
|
|
|
|
2017-09-18 01:37:15 -05:00
|
|
|
function is_valid_array(val) {
|
|
|
|
val = $.trim(val)
|
|
|
|
return !(val != "" && (val.charAt(0) != '{' || val.charAt(val.length - 1) != '}'));
|
|
|
|
}
|
2017-05-27 13:51:02 -05:00
|
|
|
/*
|
|
|
|
* This function handles the [default] and [null] values for cells
|
|
|
|
* if row is copied, otherwise returns the editor value.
|
|
|
|
* @param {args} editor object
|
|
|
|
* @param {item} row cell values
|
|
|
|
* @param {state} entered value
|
|
|
|
* @param {column_type} type of column
|
|
|
|
*/
|
|
|
|
function setValue(args, item, state, column_type) {
|
|
|
|
// declare a 2-d array which tracks the status of each updated cell
|
|
|
|
// If a cell is edited for the 1st time and state is null,
|
|
|
|
// set cell value to [default] and update its status [row][cell] to 1.
|
|
|
|
// If same cell is edited again, and kept blank, set cell value to [null]
|
|
|
|
|
|
|
|
// If a row is copied
|
|
|
|
var grid = args.grid;
|
|
|
|
if (item.is_row_copied) {
|
|
|
|
if (!grid.copied_rows) {
|
|
|
|
grid.copied_rows = [[]];
|
|
|
|
}
|
|
|
|
|
|
|
|
var active_cell = grid.getActiveCell(),
|
|
|
|
row = active_cell['row'],
|
|
|
|
cell = active_cell['cell'],
|
|
|
|
last_value = item[args.column.pos],
|
|
|
|
last_value = (column_type === 'number') ?
|
|
|
|
(_.isEmpty(last_value) || last_value) : last_value;
|
|
|
|
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = state;
|
2017-05-27 13:51:02 -05:00
|
|
|
if (last_value && _.isNull(state) &&
|
|
|
|
(_.isUndefined(grid.copied_rows[row]) ||
|
|
|
|
_.isUndefined(grid.copied_rows[row][cell]))
|
|
|
|
) {
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = undefined;
|
2017-05-27 13:51:02 -05:00
|
|
|
if (grid.copied_rows[row] == undefined) grid.copied_rows[row] = [];
|
|
|
|
grid.copied_rows[row][cell] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = state;
|
2017-05-27 13:51:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
function calculateEditorPosition(position, $wrapper) {
|
|
|
|
var $edit_grid = $wrapper.parent().find('#datagrid');
|
|
|
|
var _elem_height = $edit_grid.height(),
|
|
|
|
is_hidden, _position;
|
|
|
|
// We cannot display editor partially visible so we will lift it above select column
|
|
|
|
if(position.top > _elem_height) {
|
|
|
|
is_hidden = position.bottom - _elem_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(is_hidden) {
|
|
|
|
_position = position.top - is_hidden;
|
|
|
|
} else {
|
|
|
|
_position = position.top-7;
|
|
|
|
}
|
|
|
|
position.top = _position;
|
|
|
|
|
|
|
|
var grid_width = $edit_grid.width(),
|
|
|
|
popup_width = $wrapper.width() + 32;
|
|
|
|
popup_width += position.left;
|
|
|
|
|
|
|
|
if(popup_width > grid_width) {
|
|
|
|
position.left -= (popup_width - grid_width);
|
|
|
|
}
|
|
|
|
return position;
|
|
|
|
}
|
2017-05-27 13:51:02 -05:00
|
|
|
|
2016-08-29 09:47:01 -05:00
|
|
|
// Text data type editor
|
|
|
|
function pgTextEditor(args) {
|
2017-07-18 09:13:16 -05:00
|
|
|
var $input, $wrapper, $buttons;
|
2016-08-29 09:47:01 -05:00
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
var $container = $("body");
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$wrapper = getWrapper().appendTo($container);
|
|
|
|
$input = getTextArea().appendTo($wrapper);
|
|
|
|
$buttons = getButtons(true).appendTo($wrapper);
|
2016-08-29 09:47:01 -05:00
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$buttons.find("button:first").on("click", this.save);
|
|
|
|
$buttons.find("button:last").on("click", this.cancel);
|
2016-08-29 09:47:01 -05:00
|
|
|
$input.bind("keydown", this.handleKeyDown);
|
|
|
|
|
|
|
|
scope.position(args.position);
|
|
|
|
$input.focus().select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.handleKeyDown = function (e) {
|
|
|
|
if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
|
|
|
|
scope.save();
|
|
|
|
} else if (e.which == $.ui.keyCode.ESCAPE) {
|
|
|
|
e.preventDefault();
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigatePrev();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB) {
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigateNext();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.save = function () {
|
|
|
|
args.commitChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.cancel = function () {
|
|
|
|
$input.val(defaultValue);
|
|
|
|
args.cancelChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.hide = function () {
|
|
|
|
$wrapper.hide();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.show = function () {
|
|
|
|
$wrapper.show();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.position = function (position) {
|
2017-06-14 06:18:27 -05:00
|
|
|
calculateEditorPosition(position, $wrapper);
|
2016-08-29 09:47:01 -05:00
|
|
|
$wrapper
|
2017-06-14 06:18:27 -05:00
|
|
|
.css("top", position.top)
|
|
|
|
.css("left", position.left)
|
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$wrapper.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
2017-02-04 07:10:30 -06:00
|
|
|
// When text editor opens
|
2016-08-29 09:47:01 -05:00
|
|
|
this.loadValue = function (item) {
|
2017-05-12 04:53:57 -05:00
|
|
|
var col = args.column;
|
|
|
|
|
2017-09-18 01:37:15 -05:00
|
|
|
if (_.isUndefined(item[args.column.field]) || _.isNull(item[args.column.field])) {
|
|
|
|
$input.val(defaultValue = "");
|
|
|
|
return;
|
2017-02-04 07:10:30 -06:00
|
|
|
}
|
2017-09-18 01:37:15 -05:00
|
|
|
|
|
|
|
if (!args.column.is_array) {
|
|
|
|
if (item[args.column.field] === "") {
|
|
|
|
$input.val(defaultValue = "''");
|
|
|
|
} else if (item[args.column.field] === "''") {
|
|
|
|
$input.val(defaultValue = "\\'\\'");
|
|
|
|
} else if (item[args.column.field] === '""') {
|
|
|
|
$input.val(defaultValue = '\\"\\"');
|
|
|
|
} else {
|
|
|
|
$input.val(defaultValue = item[args.column.field]);
|
|
|
|
$input.select();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var data = [];
|
|
|
|
for (var k in item[args.column.field]) {
|
|
|
|
if (_.isUndefined(item[args.column.field][k]) || _.isNull(item[args.column.field][k])) {
|
|
|
|
data.push('');
|
|
|
|
} else if (item[args.column.field][k] === "") {
|
|
|
|
data.push("''");
|
|
|
|
} else if (item[args.column.field][k] === "''") {
|
|
|
|
data.push("\\'\\'");
|
|
|
|
} else if (item[args.column.field][k] === '""') {
|
|
|
|
data.push('\\"\\"');
|
|
|
|
} else {
|
|
|
|
data.push(item[args.column.field][k]);
|
|
|
|
$input.select();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defaultValue = data;
|
|
|
|
$input.val('{' + data.join() +'}');
|
|
|
|
|
2017-02-04 07:10:30 -06:00
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
2017-02-04 07:10:30 -06:00
|
|
|
var value = $input.val();
|
|
|
|
// If empty return null
|
|
|
|
if (value === "") {
|
|
|
|
return null;
|
|
|
|
}
|
2017-09-18 01:37:15 -05:00
|
|
|
|
|
|
|
if (!args.column.is_array) {
|
|
|
|
if (value === "''" || value === '""') {
|
|
|
|
return '';
|
|
|
|
} else if (value === "\\'\\'") {
|
|
|
|
return "''";
|
|
|
|
} else if (value === '\\"\\"') {
|
|
|
|
return '""';
|
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Remove leading { and trailing }.
|
|
|
|
// Also remove leading and trailing whitespaces.
|
|
|
|
var value = $.trim(value.slice(1, -1));
|
|
|
|
|
|
|
|
if(value == '') {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
var data = [];
|
|
|
|
value = value.split(',');
|
|
|
|
for (var k in value) {
|
|
|
|
if (value[k] == "") {
|
|
|
|
data.push(null); //empty string from editor is null value.
|
|
|
|
} else if (value[k] === "''" || value[k] === '""') {
|
|
|
|
data.push(''); // double quote from editor is blank string;
|
|
|
|
} else if (value[k] === "\\'\\'") {
|
|
|
|
data.push("''");
|
|
|
|
} else if (value[k] === '\\"\\"') {
|
|
|
|
data.push('""');
|
|
|
|
} else {
|
|
|
|
data.push(value[k]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return data;
|
2017-02-04 07:10:30 -06:00
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-05-27 13:51:02 -05:00
|
|
|
setValue(args, item, state, 'text');
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
2017-05-12 04:53:57 -05:00
|
|
|
// Use _.isNull(value) for comparison for null instead of
|
|
|
|
// defaultValue == null, because it returns true for undefined value.
|
|
|
|
if ($input.val() == "" && _.isUndefined(defaultValue)) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return (!($input.val() == "" && _.isNull(defaultValue))) &&
|
2017-09-18 01:37:15 -05:00
|
|
|
($input.val() !== defaultValue);
|
2017-05-12 04:53:57 -05:00
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator($input.val());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-18 01:37:15 -05:00
|
|
|
if (args.column.is_array && !is_valid_array($input.val())) {
|
|
|
|
return {
|
|
|
|
valid: false,
|
|
|
|
msg: "Array must start with '{' and end with '}'"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-08-29 09:47:01 -05:00
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
|
|
|
// JSON data type editor
|
|
|
|
function JsonTextEditor(args) {
|
2017-07-18 09:13:16 -05:00
|
|
|
var $input, $wrapper, $buttons;
|
2016-08-29 09:47:01 -05:00
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
var $container = $("body");
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$wrapper = getWrapper().appendTo($container);
|
|
|
|
$input = getTextArea().appendTo($wrapper);
|
|
|
|
$buttons = getButtons(true).appendTo($wrapper);
|
2016-08-29 09:47:01 -05:00
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$buttons.find("button:first").on("click", this.save);
|
|
|
|
$buttons.find("button:last").on("click", this.cancel);
|
2016-08-29 09:47:01 -05:00
|
|
|
$input.bind("keydown", this.handleKeyDown);
|
|
|
|
|
|
|
|
scope.position(args.position);
|
|
|
|
$input.focus().select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.handleKeyDown = function (e) {
|
|
|
|
if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
|
|
|
|
scope.save();
|
|
|
|
} else if (e.which == $.ui.keyCode.ESCAPE) {
|
|
|
|
e.preventDefault();
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigatePrev();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB) {
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigateNext();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.save = function () {
|
|
|
|
args.commitChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.cancel = function () {
|
|
|
|
$input.val(defaultValue);
|
|
|
|
args.cancelChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.hide = function () {
|
|
|
|
$wrapper.hide();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.show = function () {
|
|
|
|
$wrapper.show();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.position = function (position) {
|
2017-06-14 06:18:27 -05:00
|
|
|
calculateEditorPosition(position, $wrapper);
|
2016-08-29 09:47:01 -05:00
|
|
|
$wrapper
|
2017-06-14 06:18:27 -05:00
|
|
|
.css("top", position.top)
|
|
|
|
.css("left", position.left)
|
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$wrapper.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
var data = defaultValue = item[args.column.field];
|
2017-05-12 04:53:57 -05:00
|
|
|
if (data && typeof data === "object" && !Array.isArray(data)) {
|
2016-08-29 09:47:01 -05:00
|
|
|
data = JSON.stringify(data);
|
2016-09-21 07:43:27 -05:00
|
|
|
} else if (Array.isArray(data)) {
|
|
|
|
var temp = [];
|
|
|
|
$.each(data, function(i, val) {
|
|
|
|
if (typeof val === "object") {
|
|
|
|
temp.push(JSON.stringify(val));
|
|
|
|
} else {
|
|
|
|
temp.push(val)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
data = "[" + temp.join() + "]";
|
2016-08-29 09:47:01 -05:00
|
|
|
}
|
|
|
|
$input.val(data);
|
|
|
|
$input.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
2017-02-04 07:10:30 -06:00
|
|
|
if ($input.val() === "") {
|
|
|
|
return null;
|
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
return $input.val();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-05-27 13:51:02 -05:00
|
|
|
setValue(args, item, state, 'text');
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
2017-05-12 04:53:57 -05:00
|
|
|
if ($input.val() == "" && _.isUndefined(defaultValue)) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return (!($input.val() == "" && _.isNull(defaultValue))) && ($input.val() != defaultValue);
|
|
|
|
}
|
2016-08-29 09:47:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator($input.val());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
2016-09-12 06:39:40 -05:00
|
|
|
|
|
|
|
// Text data type editor
|
|
|
|
function ReadOnlypgTextEditor(args) {
|
2017-07-18 09:13:16 -05:00
|
|
|
var $input, $wrapper, $buttons;
|
2016-09-12 06:39:40 -05:00
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
var $container = $("body");
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$wrapper = getWrapper().appendTo($container);
|
|
|
|
$input = getTextArea().appendTo($wrapper);
|
|
|
|
$buttons = getButtons(false).appendTo($wrapper);
|
2016-09-12 06:39:40 -05:00
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$buttons.find("button:first").on("click", this.cancel);
|
2016-09-12 06:39:40 -05:00
|
|
|
$input.bind("keydown", this.handleKeyDown);
|
|
|
|
|
|
|
|
scope.position(args.position);
|
|
|
|
$input.focus().select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.handleKeyDown = function (e) {
|
|
|
|
if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.ESCAPE) {
|
|
|
|
e.preventDefault();
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
|
|
|
|
scope.cancel();
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigatePrev();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB) {
|
|
|
|
scope.cancel();
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigateNext();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.cancel = function () {
|
|
|
|
$input.val(defaultValue);
|
|
|
|
args.cancelChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.hide = function () {
|
|
|
|
$wrapper.hide();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.show = function () {
|
|
|
|
$wrapper.show();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.position = function (position) {
|
2017-06-14 06:18:27 -05:00
|
|
|
calculateEditorPosition(position, $wrapper);
|
2016-09-12 06:39:40 -05:00
|
|
|
$wrapper
|
2017-06-14 06:18:27 -05:00
|
|
|
.css("top", position.top)
|
|
|
|
.css("left", position.left)
|
|
|
|
}
|
2016-09-12 06:39:40 -05:00
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$wrapper.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
$input.val(defaultValue = item[args.column.field]);
|
2016-09-12 06:39:40 -05:00
|
|
|
$input.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
return $input.val();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = state;
|
2016-09-12 06:39:40 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
|
|
|
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
|
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator($input.val());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2017-02-05 04:06:48 -06:00
|
|
|
/* Override CheckboxEditor to implement checkbox with three states.
|
|
|
|
* 1) checked=true
|
|
|
|
* 2) unchecked=false
|
2017-06-06 05:29:18 -05:00
|
|
|
* 3) indeterminate=null
|
2017-02-05 04:06:48 -06:00
|
|
|
*/
|
|
|
|
function CheckboxEditor(args) {
|
|
|
|
var $select, el;
|
2017-11-21 11:22:25 -06:00
|
|
|
var defaultValue, previousState;
|
2017-02-05 04:06:48 -06:00
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
2017-06-06 05:29:18 -05:00
|
|
|
$select = $("<input type=checkbox class='editor-checkbox' hideFocus>");
|
2017-02-05 04:06:48 -06:00
|
|
|
$select.appendTo(args.container);
|
|
|
|
$select.focus();
|
|
|
|
|
|
|
|
// The following code is taken from https://css-tricks.com/indeterminate-checkboxes/
|
2017-06-06 05:29:18 -05:00
|
|
|
$select.bind("click", function (e) {
|
2017-02-05 04:06:48 -06:00
|
|
|
el = $(this);
|
2017-06-06 05:29:18 -05:00
|
|
|
el.prop('indeterminate', false);
|
|
|
|
|
|
|
|
var checkbox_status = el.data('checked');
|
|
|
|
// add new row > checkbox clicked
|
|
|
|
if (el.data('checked') == undefined) {
|
|
|
|
checkbox_status = 1;
|
|
|
|
}
|
|
|
|
switch(checkbox_status) {
|
2017-11-21 11:22:25 -06:00
|
|
|
// State 0 will come when we had indeterminate state
|
2017-02-05 04:06:48 -06:00
|
|
|
case 0:
|
2017-11-21 11:22:25 -06:00
|
|
|
// We will check now
|
|
|
|
el.prop('checked', true);
|
|
|
|
el.data('checked', 1);
|
2017-02-05 04:06:48 -06:00
|
|
|
break;
|
|
|
|
|
2017-11-21 11:22:25 -06:00
|
|
|
// State 1 will come when we had checked state
|
2017-02-05 04:06:48 -06:00
|
|
|
case 1:
|
2017-11-21 11:22:25 -06:00
|
|
|
// We will uncheck now
|
|
|
|
el.prop('checked', false);
|
|
|
|
el.data('checked', 2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// State 2 will come when we had unchecked state
|
|
|
|
case 2:
|
|
|
|
// We will set to indeterminate state
|
|
|
|
el.prop('indeterminate', true);
|
2017-06-06 05:29:18 -05:00
|
|
|
el.data('checked', 0);
|
2017-02-05 04:06:48 -06:00
|
|
|
break;
|
|
|
|
|
2017-11-21 11:22:25 -06:00
|
|
|
// Default, Set to indeterminate state
|
2017-02-05 04:06:48 -06:00
|
|
|
default:
|
2017-11-21 11:22:25 -06:00
|
|
|
el.prop('indeterminate', true);
|
|
|
|
el.data('checked', 0);
|
2017-02-05 04:06:48 -06:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$select.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$select.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
defaultValue = item[args.column.field];
|
2017-11-21 11:22:25 -06:00
|
|
|
previousState = 0;
|
2017-06-27 08:03:04 -05:00
|
|
|
if (_.isNull(defaultValue)||_.isUndefined(defaultValue)) {
|
2017-02-05 04:06:48 -06:00
|
|
|
$select.prop('indeterminate', true);
|
2017-11-21 11:22:25 -06:00
|
|
|
$select.data('checked', 0);
|
2017-02-05 04:06:48 -06:00
|
|
|
}
|
|
|
|
else {
|
2017-06-27 08:03:04 -05:00
|
|
|
defaultValue = !!item[args.column.field];
|
2017-02-05 04:06:48 -06:00
|
|
|
if (defaultValue) {
|
|
|
|
$select.prop('checked', true);
|
2017-11-21 11:22:25 -06:00
|
|
|
$select.data('checked', 1);
|
|
|
|
previousState = 1;
|
2017-02-05 04:06:48 -06:00
|
|
|
} else {
|
|
|
|
$select.prop('checked', false);
|
2017-11-21 11:22:25 -06:00
|
|
|
$select.data('checked', 2);
|
|
|
|
previousState = 2;
|
2017-02-05 04:06:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
if ($select.prop('indeterminate')) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $select.prop('checked');
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = state;
|
2017-02-05 04:06:48 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
2017-11-21 11:22:25 -06:00
|
|
|
var currentState = $select.data('checked');
|
|
|
|
return currentState !== previousState;
|
2017-02-05 04:06:48 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
2017-05-12 04:53:57 -05:00
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator(this.serializeValue());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
2017-02-05 04:06:48 -06:00
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2016-09-12 06:39:40 -05:00
|
|
|
// JSON data type editor
|
|
|
|
function ReadOnlyJsonTextEditor(args) {
|
2017-07-18 09:13:16 -05:00
|
|
|
var $input, $wrapper, $buttons;
|
2016-09-12 06:39:40 -05:00
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
var $container = $("body");
|
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$wrapper = getWrapper().appendTo($container);
|
|
|
|
$input = getTextArea().appendTo($wrapper);
|
|
|
|
$buttons = getButtons(false).appendTo($wrapper);
|
2016-09-12 06:39:40 -05:00
|
|
|
|
2017-06-14 06:18:27 -05:00
|
|
|
$buttons.find("button:first").on("click", this.cancel);
|
2016-09-12 06:39:40 -05:00
|
|
|
$input.bind("keydown", this.handleKeyDown);
|
|
|
|
|
|
|
|
scope.position(args.position);
|
|
|
|
$input.focus().select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.handleKeyDown = function (e) {
|
|
|
|
if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.ESCAPE) {
|
|
|
|
e.preventDefault();
|
|
|
|
scope.cancel();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
|
|
|
|
scope.cancel();
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigatePrev();
|
|
|
|
} else if (e.which == $.ui.keyCode.TAB) {
|
|
|
|
scope.cancel();
|
|
|
|
e.preventDefault();
|
|
|
|
args.grid.navigateNext();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.cancel = function () {
|
|
|
|
$input.val(defaultValue);
|
|
|
|
args.cancelChanges();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.hide = function () {
|
|
|
|
$wrapper.hide();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.show = function () {
|
|
|
|
$wrapper.show();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.position = function (position) {
|
2017-06-14 06:18:27 -05:00
|
|
|
calculateEditorPosition(position, $wrapper);
|
2016-09-12 06:39:40 -05:00
|
|
|
$wrapper
|
2017-06-14 06:18:27 -05:00
|
|
|
.css("top", position.top)
|
|
|
|
.css("left", position.left)
|
|
|
|
}
|
2016-09-12 06:39:40 -05:00
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$wrapper.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
var data = defaultValue = item[args.column.field];
|
2016-09-12 06:39:40 -05:00
|
|
|
if (typeof data === "object" && !Array.isArray(data)) {
|
|
|
|
data = JSON.stringify(data);
|
2016-09-21 07:43:27 -05:00
|
|
|
} else if (Array.isArray(data)) {
|
|
|
|
var temp = [];
|
|
|
|
$.each(data, function(i, val) {
|
|
|
|
if (typeof val === "object") {
|
|
|
|
temp.push(JSON.stringify(val));
|
|
|
|
} else {
|
|
|
|
temp.push(val)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
data = "[" + temp.join() + "]";
|
2016-09-12 06:39:40 -05:00
|
|
|
}
|
|
|
|
$input.val(data);
|
|
|
|
$input.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
return $input.val();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-06-27 08:03:04 -05:00
|
|
|
item[args.column.field] = state;
|
2016-09-12 06:39:40 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
|
|
|
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
|
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator($input.val());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
|
|
|
function ReadOnlyTextEditor(args) {
|
|
|
|
var $input;
|
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
$input = $("<INPUT type=text class='editor-text' readonly/>")
|
|
|
|
.appendTo(args.container)
|
|
|
|
.bind("keydown.nav", function (e) {
|
|
|
|
if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
|
|
|
|
e.stopImmediatePropagation();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.focus()
|
|
|
|
.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$input.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.getValue = function () {
|
|
|
|
return $input.val();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
var value = item[args.column.field];
|
2017-02-01 07:48:46 -06:00
|
|
|
|
|
|
|
// Check if value is null or undefined
|
|
|
|
if (value === undefined && typeof value === "undefined") {
|
|
|
|
value = ""
|
|
|
|
}
|
|
|
|
defaultValue = value;
|
2016-09-12 06:39:40 -05:00
|
|
|
$input.val(defaultValue);
|
|
|
|
$input[0].defaultValue = defaultValue;
|
|
|
|
$input.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
return $input.val();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
|
|
|
item[args.column.field] = state;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
|
|
|
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
|
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator($input.val());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
|
|
|
function ReadOnlyCheckboxEditor(args) {
|
2017-02-24 07:47:37 -06:00
|
|
|
var $select, el;
|
2016-09-12 06:39:40 -05:00
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
2017-02-24 07:47:37 -06:00
|
|
|
$select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus disabled>");
|
2016-09-12 06:39:40 -05:00
|
|
|
$select.appendTo(args.container);
|
|
|
|
$select.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$select.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$select.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-06 05:29:18 -05:00
|
|
|
defaultValue = item[args.column.pos];
|
|
|
|
if (_.isNull(defaultValue)|| _.isUndefined(defaultValue)) {
|
2017-02-24 07:47:37 -06:00
|
|
|
$select.prop('indeterminate', true);
|
2017-06-06 05:29:18 -05:00
|
|
|
$select.data('checked', 2);
|
2017-02-24 07:47:37 -06:00
|
|
|
}
|
|
|
|
else {
|
2017-06-06 05:29:18 -05:00
|
|
|
defaultValue = !!item[args.column.pos];
|
2017-02-24 07:47:37 -06:00
|
|
|
if (defaultValue) {
|
|
|
|
$select.prop('checked', true);
|
2017-06-06 05:29:18 -05:00
|
|
|
$select.data('checked', 0);
|
2017-02-24 07:47:37 -06:00
|
|
|
} else {
|
|
|
|
$select.prop('checked', false);
|
2017-06-06 05:29:18 -05:00
|
|
|
$select.data('checked', 1);
|
2017-02-24 07:47:37 -06:00
|
|
|
}
|
2016-09-12 06:39:40 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
2017-02-24 07:47:37 -06:00
|
|
|
if ($select.prop('indeterminate')) {
|
|
|
|
return null;
|
|
|
|
}
|
2016-09-12 06:39:40 -05:00
|
|
|
return $select.prop('checked');
|
|
|
|
};
|
|
|
|
|
2017-02-24 07:47:37 -06:00
|
|
|
this.applyValue = function (item, state) {
|
2017-06-06 05:29:18 -05:00
|
|
|
item[args.column.pos] = state;
|
2017-02-24 07:47:37 -06:00
|
|
|
};
|
|
|
|
|
2016-09-12 06:39:40 -05:00
|
|
|
this.isValueChanged = function () {
|
2017-06-06 05:29:18 -05:00
|
|
|
// var select_value = this.serializeValue();
|
|
|
|
var select_value = $select.data('checked');
|
|
|
|
return (!(select_value === 2 && (defaultValue == null || defaultValue == undefined))) &&
|
|
|
|
(select_value !== defaultValue);
|
2016-09-12 06:39:40 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2017-02-04 07:10:30 -06:00
|
|
|
function CustomNumberEditor(args) {
|
|
|
|
var $input;
|
|
|
|
var defaultValue;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
$input = $("<INPUT type=text class='editor-text' />");
|
|
|
|
|
|
|
|
$input.bind("keydown.nav", function (e) {
|
|
|
|
if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
|
|
|
|
e.stopImmediatePropagation();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$input.appendTo(args.container);
|
|
|
|
$input.focus().select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$input.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$input.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
2017-06-27 08:03:04 -05:00
|
|
|
defaultValue = item[args.column.field];
|
2017-09-18 01:37:15 -05:00
|
|
|
|
|
|
|
if(args.column.is_array && !_.isNull(defaultValue) && !_.isUndefined(defaultValue)) {
|
|
|
|
$input.val('{' + defaultValue.join() +'}');
|
|
|
|
} else {
|
|
|
|
$input.val(defaultValue);
|
|
|
|
}
|
|
|
|
|
2017-02-04 07:10:30 -06:00
|
|
|
$input[0].defaultValue = defaultValue;
|
|
|
|
$input.select();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
if ($input.val() === "") {
|
|
|
|
return null;
|
|
|
|
}
|
2017-09-18 01:37:15 -05:00
|
|
|
|
|
|
|
if(args.column.is_array) {
|
|
|
|
// Remove leading { and trailing }.
|
|
|
|
// Also remove leading and trailing whitespaces.
|
|
|
|
var val = $.trim($input.val().slice(1, -1));
|
|
|
|
|
|
|
|
if(val == '') {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
val = val.split(',');
|
|
|
|
for (var k in val) {
|
|
|
|
if (val[k] == "") {
|
|
|
|
val[k] = null; //empty string from editor is null value.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2017-02-24 07:39:40 -06:00
|
|
|
return $input.val();
|
2017-02-04 07:10:30 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
2017-05-27 13:51:02 -05:00
|
|
|
setValue(args, item, state, 'number');
|
2017-02-04 07:10:30 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
2017-05-12 04:53:57 -05:00
|
|
|
if ($input.val() == "" && _.isUndefined(defaultValue)) {
|
|
|
|
return false;
|
|
|
|
} else if ($input.val() == "" && defaultValue == "") {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return (!($input.val() == "" && _.isNull(defaultValue ))) &&
|
|
|
|
($input.val() != defaultValue);
|
|
|
|
}
|
2017-02-04 07:10:30 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
2017-09-18 01:37:15 -05:00
|
|
|
var value = $input.val();
|
|
|
|
if (!args.column.is_array && isNaN(value)) {
|
2017-02-04 07:10:30 -06:00
|
|
|
return {
|
|
|
|
valid: false,
|
2017-09-18 01:37:15 -05:00
|
|
|
msg: "Please enter a valid number"
|
2017-02-04 07:10:30 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
if (args.column.validator) {
|
2017-09-18 01:37:15 -05:00
|
|
|
var validationResults = args.column.validator(value);
|
2017-02-04 07:10:30 -06:00
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-18 01:37:15 -05:00
|
|
|
if (args.column.is_array) {
|
|
|
|
if (!is_valid_array(value)) {
|
|
|
|
return {
|
|
|
|
valid: false,
|
|
|
|
msg: "Array must start with '{' and end with '}'"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
var val = $.trim(value.slice(1, -1)),
|
|
|
|
arr;
|
|
|
|
|
|
|
|
if(val == '') {
|
|
|
|
arr = [];
|
|
|
|
} else {
|
|
|
|
var arr = val.split(',');
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var k in arr) {
|
|
|
|
if (isNaN(arr[k])) {
|
|
|
|
return {
|
|
|
|
valid: false,
|
|
|
|
msg: "Please enter a valid numbers"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-04 07:10:30 -06:00
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2017-11-21 11:22:25 -06:00
|
|
|
// Custom checkbox editor, We need it for runtime as it does not render
|
|
|
|
// indeterminate checkbox state
|
|
|
|
function pgCheckboxEditor(args) {
|
|
|
|
var $select, el;
|
|
|
|
var defaultValue, previousState;
|
|
|
|
var scope = this;
|
|
|
|
|
|
|
|
this.init = function () {
|
|
|
|
$select = $("<div class='multi-checkbox'><span class='check' hideFocus></span></div>");
|
|
|
|
$select.appendTo(args.container);
|
|
|
|
$select.focus();
|
|
|
|
|
|
|
|
// The following code is taken from https://css-tricks.com/indeterminate-checkboxes/
|
|
|
|
$select.bind("click", function (e) {
|
|
|
|
el = $(this);
|
|
|
|
var states = ["unchecked", "partial", "checked"];
|
|
|
|
var curState = el.find(".check").data("state");
|
|
|
|
curState++;
|
|
|
|
el.find(".check")
|
|
|
|
.removeClass("unchecked partial checked")
|
|
|
|
.addClass(states[curState % states.length])
|
|
|
|
.data("state", curState % states.length);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
this.destroy = function () {
|
|
|
|
$select.remove();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.focus = function () {
|
|
|
|
$select.focus();
|
|
|
|
};
|
|
|
|
|
|
|
|
this.loadValue = function (item) {
|
|
|
|
defaultValue = item[args.column.field];
|
|
|
|
previousState = 1;
|
|
|
|
if (_.isNull(defaultValue)||_.isUndefined(defaultValue)) {
|
|
|
|
$select.find(".check").data("state", 1).addClass("partial");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
defaultValue = !!item[args.column.field];
|
|
|
|
if (defaultValue) {
|
|
|
|
$select.find(".check").data("state", 2).addClass("checked");
|
|
|
|
previousState = 2;
|
|
|
|
} else {
|
|
|
|
$select.find(".check").data("state", 0).addClass("unchecked");
|
|
|
|
previousState = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.serializeValue = function () {
|
|
|
|
if ($select.find(".check").data("state") == 1) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $select.find(".check").data("state") == 2 ? true : false;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.applyValue = function (item, state) {
|
|
|
|
item[args.column.field] = state;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.isValueChanged = function () {
|
|
|
|
var currentState = $select.find(".check").data("state");
|
|
|
|
return currentState !== previousState;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.validate = function () {
|
|
|
|
if (args.column.validator) {
|
|
|
|
var validationResults = args.column.validator(this.serializeValue());
|
|
|
|
if (!validationResults.valid) {
|
|
|
|
return validationResults;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
valid: true,
|
|
|
|
msg: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
this.init();
|
|
|
|
}
|
|
|
|
|
2016-08-29 09:47:01 -05:00
|
|
|
})(jQuery);
|