MrScf
MrScf

Reputation: 2497

AG Grid: Better way for validation row - valueSetter?

Is there a better way to validate a row in ag-grid than with valueSetter?

I can achieve the validation with that but I am not sure, if there is a better way.

https://www.ag-grid.com/javascript-grid-value-setters/#properties-for-setters-and-parsers

I want to validate two fields in the row. DateFrom and DateUntil (they are not allow to be null and DateFrom must be lower than DateUntil).

Upvotes: 1

Views: 18332

Answers (3)

Bob
Bob

Reputation: 570

You could override the valueSetter and call the grid api transaction update instead.

Here is pseudo-code that shows how you could implement this.

valueSetter: params => {
  validate(params.newValue, onSuccess, onFail);
  return false;
};

validate = (newvalue, success, fail) => {
  if (isValid(newValue)) {
    success();
  } else {
    fail();
  }
};

onSuccess = () => {
  // do transaction update to update the cell with the new value
};

onFail = () => {
  // update some meta data property that highlights the cell signalling that the value has failed to validate
};

This way you can also do asynchronous validation. Here is a real example of an async value setter that has success, failure, and while validating handlers that do transaction updates when validation is done.

const asyncValidator = (
  newValue,
  validateFn,
  onWhileValidating,
  onSuccess,
  _onFail
) => {
  onWhileValidating();
  setTimeout(function() {
    if (validateFn(newValue)) {
      onSuccess();
    } else {
      _onFail();
    }
  }, 1000);
};

const _onWhileValidating = params => () => {
  let data = params.data;
  let field = params.colDef.field;

  data[field] = {
    ...data[field],
    isValidating: true
  };
  params.api.applyTransaction({ update: [data] });
};

const _onSuccess = params => () => {
  let data = params.data;
  let field = params.colDef.field;

  data[field] = {
    ...data[field],
    isValidating: false,
    lastValidation: true,
    value: params.newValue
  };
  params.api.applyTransaction({ update: [data] });
};

const _onFail = params => () => {
  let data = params.data;
  let field = params.colDef.field;

  data[field] = {
    ...data[field],
    isValidating: false,
    lastValidation: params.newValue
  };
  params.api.applyTransaction({ update: [data] });
};

const asyncValidateValueSetter = validateFn => params => {
  asyncValidator(
    params.newValue,
    validateFn,
    _onWhileValidating(params),
    _onSuccess(params),
    _onFail(params)
  );
  return false;
};

Here is a code runner example showing this in action: https://stackblitz.com/edit/async-validation-ag-grid-final

Upvotes: 5

Alberto Gutierrez
Alberto Gutierrez

Reputation: 1588

Have a look at this two snippets, these come from our internal knowledge base (accessible to customers)

When editing a value in column 'A (Required)', you will see that it does not allow you to leave it empty. If you leave it empty and return the edit, it will be cancelled.

//Force Cell to require a value when finished editing

https://plnkr.co/edit/GFgb4v7P8YCW1PxJwGTx?p=preview

In this example, we are using a Custom Cell Editor that will also validate the values against a 6 character length rule. While editing, if the value is modified outside of 6 characters, it will appear in red, and when you stop editing the row, the value would be reset, so it only accepts a complete edit if the value is valid.

//Inline Validation while editing a cell 

https://plnkr.co/edit/dAAU8yLMnR8dm4vNEa9T?p=preview

Upvotes: 3

un.spike
un.spike

Reputation: 5113

There are two ways of possible validation handling:

First: via ValueSetter function

and

Second: via custom cellEditor component

I suggest that it would be better to split the logic between custom components, but as you said you need to validate two cell-values between themselves.

On this case from UI perspective you could try to combine them inside one cell and it would be easily to work with values via one component only.

Upvotes: 7

Related Questions