Grid - Column validationRules different settings for every row.

Hi,

I have situation when I need to manage validationRules inside Grid (cell edit) not for Column definition but in case of every row differently.

When user will select accountCode (first edited column) - based on this information I need to set required=true 

for validation for specific columns list and I want to show information for user that selected field are required (as standard validationRules for columns works). List of columns for every row could be different.

I have tried to do this as below:
I have grid definition with some columns and batch edit mode (without declaration of 'validationRules').

Then if user will select element in first column - based on this value I have update 'validationRules' inside cellEdit for the other of columns list. Values has been save correctly but as I understand it is not working becase Grid is no re-rendered / row refreshing - that this updated rules do not work.

Do we have some option to refresh row without loosing actual editing data and to run this new validationRules?

Or do we have some other option to manual validate field value or run validation inside edit?

    const validRequiredField = { required: true, minLength: 2 }

    const cellEditSettings = (args) => {
        if (args.columnName === "lineNo_" || args.columnName === "accountName") { args.cancel = true; }

        //set focus to next column at new line created
        if (batchAddFocus) {
            batchAddFocus = false;
            const rowIndex = args.cell.parentElement.rowIndex;
            const column = gridInstanceRef.current.getColumnByIndex(parseInt(args.cell.nextElementSibling.getAttribute('data-colindex'), 10));
            gridInstanceRef.current.editCell(rowIndex, column.field);
        }

        if (args.rowData.accountCode !== null && args.rowData.accountCode !== undefined) {
            dimSettingsTempArray.map(accItem => {
                if (accItem.account === args.rowData.accountCode) {
                    if (args.columnName === 'dim1' && accItem.dimSettings[0] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim2' && accItem.dimSettings[1] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim3' && accItem.dimSettings[2] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim4' && accItem.dimSettings[3] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim5' && accItem.dimSettings[4] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim6' && accItem.dimSettings[5] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim7' && accItem.dimSettings[6] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim8' && accItem.dimSettings[7] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim9' && accItem.dimSettings[8] === '0') { args.cancel = true; }
                    else if (args.columnName === 'dim1' && accItem.dimSettings[0] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim2' && accItem.dimSettings[1] === '1') { args.validationRules = { required: false, minLength: 2 } }
                    else if (args.columnName === 'dim3' && accItem.dimSettings[2] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim4' && accItem.dimSettings[3] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim5' && accItem.dimSettings[4] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim6' && accItem.dimSettings[5] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim7' && accItem.dimSettings[6] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim8' && accItem.dimSettings[7] === '1') { args.validationRules = validRequiredField; }
                    else if (args.columnName === 'dim9' && accItem.dimSettings[8] === '1') { args.validationRules = validRequiredField; }
                    else { args.cancel = false; }
                }
            }
            );

        }
    };

   <GridComponent
            dataSource={props.sourceData}
            ref={grid => gridInstance = grid}
            toolbar={props.toolbarOptions}
            allowPaging={false}
            editSettings={editSettings}
            locale={props.lang}
            cellEdit={cellEditSettings}
            beforeBatchAdd={beforeBatchAdd.bind(this)}
            beforeBatchDelete={beforeBatchDelete.bind()}
            beforeBatchSave={beforeBatchSave.bind()}
            batchCancel={onBatchCancel.bind()}
            gridLines='Both'
            statelessTemplates={['directiveTemplates']}
            toolbarClick={toolbarClick}
            allowPdfExport={true}
            allowExcelExport={true}
            rowSelecting={onRowSelecting.bind(this)}

        >
            <ColumnsDirective>
                <ColumnDirective
                    field="lineNo_"
                    width="30"
                    textAlign="Center"
                    headerText={intl.formatMessage({ id: "txtNr" })}
                    isPrimaryKey={true}
                    customAttributes={disabledEditingGridCellStyle}
                />
                <ColumnDirective
                    field="accountCode"
                    width="180"
                    textAlign="Left"
                    headerText={intl.formatMessage({ id: "txtKonto" })}
                    defaultValue={selectedAccNoValue}
                    edit={syncFusionAutoComplete}
                    validationRules={validRequiredField}
                />

                {props.erpDimDef.map(dim => (
                    <ColumnDirective
                        key={`dim${dim.segmentID}`}
                        field={`dim${dim.segmentID}`}
                        width="80"
                        textAlign="Left"
                        headerText={dim.shortName}
                        defaultValue={selectedDimValues[dim.segmentID]}
                        edit={syncFusionAutoCompleteDim}
                    />
                ))}


                <ColumnDirective
                    id="transAmtOri"
                    field="transAmtOri"
                    width="120"
                    format="N2"
                    textAlign="Right"
                    headerText={intl.formatMessage({ id: "txtKwota" })}
                    edit={editBookingAmt}
                    editType="numericEdit"
                    validationRules={netAmtValidRules}
                    defaultValue="0.00"


                />
                <ColumnDirective
                    field="transDescription"
                    width="100"
                    textAlign="Left"
                    headerText={intl.formatMessage({ id: "txtOpis" })}
                    defaultValue=""
                />
            </ColumnsDirective>
            <AggregatesDirective>
                <AggregateDirective>
                    <AggregateColumnsDirective>
                        <AggregateColumnDirective field='transAmtOri' type='Sum' format='N2' footerTemplate={footerSum} />
                    </AggregateColumnsDirective>
                </AggregateDirective>
            </AggregatesDirective>
            <Inject services={[Edit, Toolbar, Aggregate, PdfExport, ExcelExport]} />
        </GridComponent >


5 Replies

KS Karol Statek September 26, 2023 12:35 PM UTC

Does anyone have any suggestions on the above topic? I cannot find any solution for that.



DM Dineshnarasimman Muthu Syncfusion Team September 27, 2023 05:11 PM UTC

Hi Karol Statek,


Sorry for the inconvenience caused.


We have reviewed your query about adding validation rules for each row based on the edited value of another column.


  • Can you please ensure whether do you need to add validation rules when the cell value changed in the edit state or after the value of the cell is edit state.


  • In the below image, when the first row of ShipCountry field is edited to Brazil, a validationRules is set to CustomerName field. If the first row of ShipCountry column value changed to France from Brazil, do you expect to clear the validationRules that is previously set as the previous validationRules persist even after changing the value.


Image:


Can you please provide the above information which will be very helpful for us to provide better solution.


Regards,

Dineshnarasimman



KS Karol Statek September 28, 2023 12:22 PM UTC

testsdf



KS Karol Statek September 28, 2023 12:24 PM UTC

Hi Dineshnarasimman,


Ad 1. After selecting my 'main' column value, I received from api details of which element/grid column should be required and which not. It would be perfect if user will not be able to save edited row/cancel cell edit - with the same way as default grid and required column works.

Ad 2. Based on your example at the begining I don't have any validation rules for column Customer Name (not required).


Then if I will select ShipCountry to Brazil - I would like to set required row element in Customer Name column (only for actual editing row). So if user will select Brazil, he cannot save row/grid without entering Customer Name value for this row.

In other ases if user will select ShipCountry to France - Customer Name will not be required - could be empty.

In my case my "main" (ShipCountry) column is at begining of columns list - but as I supposed column order doesn't matter to show main issue.

I have tried to refresh grid columns but updated validationRules doesn't work.

I would be gratefull for some suggestions.



SI Santhosh Iruthayaraj Syncfusion Team October 19, 2023 01:49 PM UTC

Hi Karol Statek,


Based on your query, we understand that you want to prevent the submission of empty values for a particular column based on the value of another column. This can be achieved by using the Custom Validation feature of the Grid. We have developed the validation logic that will help you achieve the desired outcome. Please find the code snippet and sample below for your reference:


[index.js]

 

// custom validation function

 function customerNameValidationFunc(args) {

    let rowIndex = args.element.closest('.e-row').rowIndex;

    let rowObject = grid.getRowsObject()[rowIndex];

    let rowBatchData = rowObject.changes ?? rowObject.data;

 

    // includes the countries which requires name

    let customerNameRequiredCountries = ['Brazil''Germany'];

 

    // check row data with particular country has empty name

    let required = !(

      args.element.value === '' &&

      customerNameRequiredCountries.includes(rowBatchData.ShipCountry)

    );

 

    return required;

  }

 

  // validation rule

  const customerNameValidationRule = {

    required: [customerNameValidationFunc'Customer Name required !'],

  };

 

.  .  .  .  .

 

  <ColumnDirective

    field="CustomerName

    headerText="Customer Name"

    width="150"

    validationRules={customerNameValidationRule}

  ></ColumnDirective>

 

 


Sample: https://stackblitz.com/edit/react-grid-custom-validation


In the sample, we have implemented logic to make the “CustomerName” column required for the “ShipCountry” values “Brazil” and “Germany” based on your explanation. For other “ShipCountry” values, the “CustomerName” column could be empty.


You can find more information about Custom Validation in the documentation:


Documentation: https://ej2.syncfusion.com/react/documentation/grid/editing/validation#custom-validation


Note: We have prepared this logic based on the explanation provided in your last response. You can modify the logic based on your requirements if necessary.


Please feel free to reach out if you have any further queries or require additional assistance.


Regards,

Santhosh I


Loader.
Up arrow icon