diff --git a/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js b/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js index 19ad11d..e7c9b9c 100644 --- a/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js +++ b/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js @@ -15,7 +15,8 @@ "ReadOnlyText": ReadOnlyTextEditor, "ReadOnlyCheckbox": ReadOnlyCheckboxEditor, "ReadOnlypgText": ReadOnlypgTextEditor, - "ReadOnlyJsonText": ReadOnlyJsonTextEditor + "ReadOnlyJsonText": ReadOnlyJsonTextEditor, + "CustomNumber": CustomNumberEditor } } }); @@ -107,11 +108,22 @@ }; this.loadValue = function (item) { - $input.val(defaultValue = item[args.column.field]); - $input.select(); + if (item[args.column.field] === "") { + $input.val("''"); + } + else { + $input.val(defaultValue = item[args.column.field]); + $input.select(); + } }; this.serializeValue = function () { + if ($input.val() === "") { + return null; + } + else if ($input.val() === "''") { + return "''"; + } return $input.val(); }; @@ -246,6 +258,9 @@ }; this.serializeValue = function () { + if ($input.val() === "") { + return null; + } return $input.val(); }; @@ -631,4 +646,76 @@ this.init(); } + function CustomNumberEditor(args) { + var $input; + var defaultValue; + var scope = this; + + this.init = function () { + $input = $(""); + + $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) { + defaultValue = item[args.column.field]; + $input.val(defaultValue); + $input[0].defaultValue = defaultValue; + $input.select(); + }; + + this.serializeValue = function () { + if ($input.val() === "") { + return null; + } + return parseInt($input.val(), 10) || 0; + }; + + 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 (isNaN($input.val())) { + return { + valid: false, + msg: "Please enter a valid integer" + }; + } + + if (args.column.validator) { + var validationResults = args.column.validator($input.val()); + if (!validationResults.valid) { + return validationResults; + } + } + + return { + valid: true, + msg: null + }; + }; + + this.init(); + } + })(jQuery); diff --git a/web/pgadmin/static/js/slickgrid/slick.pgadmin.formatters.js b/web/pgadmin/static/js/slickgrid/slick.pgadmin.formatters.js index 3b4aa3c..f44604f 100644 --- a/web/pgadmin/static/js/slickgrid/slick.pgadmin.formatters.js +++ b/web/pgadmin/static/js/slickgrid/slick.pgadmin.formatters.js @@ -12,7 +12,8 @@ "Formatters": { "JsonString": JsonFormatter, "Numbers": NumbersFormatter, - "Checkmark": CheckmarkFormatter + "Checkmark": CheckmarkFormatter, + "Text": TextFormatter, } } }); @@ -41,9 +42,13 @@ } function NumbersFormatter(row, cell, value, columnDef, dataContext) { - if (value == null || value === "") { - return ""; - } else { + if (value === null) { + return "[null]"; + } + else if (value === "") { + return ''; + } + else { return "" + value + ""; } } @@ -55,4 +60,16 @@ return value ? "true" : "false"; } + function TextFormatter(row, cell, value, columnDef, dataContext) { + if (value === null) { + return "[null]"; + } + else if (value === "''") { + return ""; + } + else { + return value; + } + } + })(jQuery); diff --git a/web/pgadmin/tools/sqleditor/command.py b/web/pgadmin/tools/sqleditor/command.py index b6aa7f5..8297bfd 100644 --- a/web/pgadmin/tools/sqleditor/command.py +++ b/web/pgadmin/tools/sqleditor/command.py @@ -440,6 +440,14 @@ class TableCommand(GridCommand): list_of_rowid.append(data.get('__temp_PK')) # Remove our unique tracking key data.pop('__temp_PK', None) + # Unescape strings with single and double quotes + temp_data = data + for idx, val in temp_data.items(): + if data_type[idx] == 'text': + temp_data[idx] = val.decode('string_escape') if val is not None else None + else: + temp_data[idx] = val + data = temp_data sql = render_template("/".join([self.sql_path, 'insert.sql']), data_to_be_saved=data, primary_keys=None, @@ -452,8 +460,16 @@ class TableCommand(GridCommand): elif of_type == 'updated': for each_row in changed_data[of_type]: data = changed_data[of_type][each_row]['data'] - pk = changed_data[of_type][each_row]['primary_keys'] data_type = changed_data[of_type][each_row]['data_type'] + # Unescape strings with single and double quotes + temp_data = data + for idx, val in temp_data.items(): + if data_type[idx] == 'text': + temp_data[idx] = val.decode('string_escape') if val is not None else None + else: + temp_data[idx] = val + data = temp_data + pk = changed_data[of_type][each_row]['primary_keys'] sql = render_template("/".join([self.sql_path, 'update.sql']), data_to_be_saved=data, primary_keys=pk, diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js index 5e400c7..33c9135 100644 --- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js @@ -630,7 +630,7 @@ define( : Slick.Editors.ReadOnlyJsonText; options['formatter'] = Slick.Formatters.JsonString; } else if(c.cell == 'number') { - options['editor'] = is_editable ? Slick.Editors.Text + options['editor'] = is_editable ? Slick.Editors.CustomNumber : Slick.Editors.ReadOnlyText; options['formatter'] = Slick.Formatters.Numbers; } else if(c.cell == 'boolean') { @@ -640,6 +640,7 @@ define( } else { options['editor'] = is_editable ? Slick.Editors.pgText : Slick.Editors.ReadOnlypgText; + options['formatter'] = Slick.Formatters.Text; } grid_columns.push(options)