0
votes

I've slightly customised the code at http://mleibman.github.io/SlickGrid/examples/example3a-compound-editors.html to provide me with a custom editor that takes a numerator and denominator and displays the percentage once the values are updated (custom formatter code below):-

function NumericRangeFormatter(row, cell, value, columnDef, dataContext) {
      return isNaN(dataContext.from/dataContext.to) ? "" : ((dataContext.from/dataContext.to) * 100).toFixed(2) + "%";
  }

This works as expected, but I've found that if I have more than one column identified as using the custom editor / formatter there appears to be a glitch in that, if I edit a cell in a row, the rest of the cells that utilise that editor update to the same value.

My columns are defined as below:-

  var columns = [
    {id: "indicator", name: "Indicator", field: "indicator", width:300},
    { id: "apr", name: "April", field: "apr", width: 100,  formatter: NumericRangeFormatter, editor: NumericRangeEditor },
    { id: "may", name: "May", field: "may", width: 100, formatter: NumericRangeFormatter, editor: NumericRangeEditor },
    { id: "jun", name: "June", field: "jun", width: 100,formatter: NumericRangeFormatter, editor: NumericRangeEditor }
  ];

So, basically, if I edit a cell in the 'April' column, the cells for both 'May' and 'June' update to the same value. I don't want this behaviour.

I can't see anything obviously wrong in the code that handles values in the editor, and I've read the guidance at https://github.com/mleibman/SlickGrid/wiki/Writing-custom-cell-editors.

Is there something obvious I am missing? Code for the editor is below:-

  function NumericRangeEditor(args) {
      var $from, $to;
      var scope = this;
      this.init = function () {
          $from = $("<INPUT type=text style='width:40px' />")
              .appendTo(args.container)
              .bind("keydown", scope.handleKeyDown);
          $(args.container).append("&nbsp;/&nbsp;");
          $to = $("<INPUT type=text style='width:40px' />")
              .appendTo(args.container)
              .bind("keydown", scope.handleKeyDown);
          scope.focus();
      };

      this.handleKeyDown = function (e) {
          if (e.keyCode == $.ui.keyCode.LEFT || e.keyCode == $.ui.keyCode.RIGHT || e.keyCode == $.ui.keyCode.TAB) {
              e.stopImmediatePropagation();
          }
      };

      this.destroy = function () {
          $(args.container).empty();
      };

      this.focus = function () {
          $from.focus();
      };

      this.serializeValue = function () {
          return { from: parseInt($from.val(), 10), to: parseInt($to.val(), 10) };
      };

      this.applyValue = function (item, state) {
          item.from = state.from;
          item.to = state.to;
      };

      this.loadValue = function (item) {
          $from.val(item.from);
          $to.val(item.to);
      };

      this.isValueChanged = function () {
          return args.item.from != parseInt($from.val(), 10) || args.item.to != parseInt($from.val(), 10);
      };

      this.validate = function () {
          if (isNaN(parseInt($from.val(), 10)) || isNaN(parseInt($to.val(), 10))) {
              return { valid: false, msg: "Please type in valid numbers." };
          }
          if (parseInt($from.val(), 10) > parseInt($to.val(), 10)) {
              return { valid: false, msg: "'from' cannot be greater than 'to'" };
          }
          return { valid: true, msg: null };
      };
      this.init();
  }
1

1 Answers

0
votes

You have columns namely [apr,may,jun] that use the same formatter/editor.

The problem is you are referencing the same fields within the dataContext which are to and from. If you open an editor on any of the columns [apr,may,jun], you are overwriting the fields to and from. Thus, any changes reflects to other columns too as the formatter use the same fields as reference

To resolve this, you have to add new fields on dataContext to store the values for each month e.g. aprilTo,aprilFrom, mayTo,mayFrom,junTo,junFrom. Then, change your editor to

this.applyValue = function (item, state) {
      item[args.column.field + 'From'] = state.from;
      item[args.column.field + 'To'] = state.to;
};`

Formatter to :

function NumericRangeFormatter(row, cell, value, columnDef, dataContext) {
      return isNaN(dataContext[columnDef.field + 'From'] /  dataContext[columnDef.field + 'To']) ? "" : ((dataContext[columnDef.field + 'From'] /dataContext[columnDef.field + 'To']) * 100).toFixed(2) + "%";   
}