I have a GridPanel with just two columns: names and commission percentages. The sum of all of the percentages should never exceed a predetermined maximum (say that 25% of the sale is up for grabs).
Name Commission
Bob 10%
Sally 15%
(Maximum is 25%)
Everything is fine.
I’ve attached a custom validator (see "validator") to the NumberField editor which works just great for complex logic on individual values, and I can sum up all of the values for the number column in the data store easily. But the problem is combining the two; the new value isn’t pushed to the store until after a successful validation, and the custom validator is only given the current value in question, with no context as to what row is involved (with which I could potentially subtract the old value, and use this new value in the total).
How can I get this validator to work in such a way that it makes sure that a newly entered value doesn’t push the sum over the maximum?
Name Commission
Bob 10%
Sally 16% (Invalid! Total commissions must not exceed 25%)
(Maximum is 25%)
I didn’t quite use js1568’s answer, as I wanted to block bad values as they’re being entered; even before the AfterEdit event fires and the row gets marked dirty, and long before writing to the database. But that link did inspire me through its use of the grid’s selection model. So, my quick little solution:
Because the NumberField doesn’t pass any context to the custom validator (aside from the current value), using field.originalValue
would have been awesome, but hey, life is hard.
But due to the fact that editing a row first requires selection of that row (and reinforced by the fact that this grid’s RowSelectionModel is set to SingleSelect
), I know that the row being edited must be the only element in grid.selModel.selections.items[]
. From there, it’s just a matter of
var newTotal = TotalCommissionPercentagesInGrid() – oldValue + newValue;
With oldValue
being grid.selModel.selections.items[0].data.CommissionPercentage
and newValue
being the value passed to the validator function from the NumberField.
return ( newTotal <= percentageAvailable ) ? true : "No dice.";
Very nice.