3
votes

I have a DataGrid component with remote CRUD operations.

I have a problem with the validation of its grid fields.

When I click "Add new Record", a new empty line is added to the datagrid.

Without filling in any values, and clicking on "Save Changes" button, the create operation is processed even if no required values are filled.

For example name:

name: {
      editable: true,
      nullable: false,
      validation: {
      required: {
      message: "Please enter a First name"
      }
      }
 },

Validation Message is displayed only when I click into the name cell.

Is there any way to solve this issue?

I tried enable/ disable batch editing, etc... but without luck.

2

2 Answers

2
votes

I recently bumped into this issue as well, it gave me plenty of head scratching, but there are two options.

  1. Use inline editing
  2. Force validation on new cells

I did not go with option 1 for numerous reasons including the fact that you now need to have an edit, update, and cancel button per row before it would do any validation.

Option 2

Got the idea from Brian Roth @ the Telerik forums, see here. I used his solution but optimized it a little bit.

In the saveChanges event, implement this:

saveChanges: function (e) {
    if (!checkCells(this)) {
        e.preventDefault();       //prevents save if validation fails
    }
}

checkForInvalidCells will basically go through every new row's cells, open for edit and attempt to close (and in the process, firing the validation). If validation was not successful, then prevent the save.

function checkCells(grid)
{
    var rows = grid.tbody.find("tr");                   //get rows
    for (var i = 0; i < rows.length; i++) {

        var rowModel = grid.dataItem(rows[i]);          //get row data
        if (rowModel && rowModel.isNew()) {

            var colCells = $(rows[i]).find("td");       //get cells
            for (var j = 0; j < colCells.length; j++) {
                if ($(colCells[j]).hasClass('k-group-cell')) 
                    continue;                           //grouping enabled will add extra td columns that aren't actual columns
                grid.editCell($(colCells[j]));          //open for edit
                if (!grid.editable.end()) {             //trigger validation
                    return false;                       //if fail, return false
                }
                else {
                    grid.closeCell();                   //if success, keep checking
                }
            }
        }
    }
    return true;                                        //all cells are valid
}

In case you are comparing my implementation and his, the difference is:

  • Made it cleaner without the need for break statement and bool flag
  • Kept save event variable e logic in the event itself
  • Utilized isNew() method to check for a new row, a new row's ID/Key may not always be 0, especially if it is an editable field and you have already put info in that field
  • I account for grouping enabled, grouping will introduce extra td columns that shouldn't be checked for saving

Overall, I hate doing hacks like this, but sometimes it's what you gotta do. Be aware that if you are adding a LOT of new rows at a time, the check will take substantially longer.

Also, each check will move the grid's scroll view to the cell that was last checked (since you are opening the cells for editing, programmatically). If all your new rows are visible at the top of the grid, this is no problem for you, but if you are appending new rows at the bottom, the user may find it strange that the grid has scrolled after saving.

0
votes

This was a huge help. Thank you very much, @gitsitgo.

I needed to make minor changes to get this to work in my grid, so I thought I'd post it here.

    var checkCells = (grid: any): boolean => {
        var rows = grid.tbody.find("tr");                   //get rows
        for (var i = 0; i < rows.length; i++) {

            var rowModel = grid.dataItem(rows[i]);          //get row data
            if (rowModel && rowModel.isNew() || rowModel.IsUpdated) {

                var colCells = $(rows[i]).find("td");       //get cells
                for (var j = 0; j < colCells.length; j++) {
                    if ($(colCells[j]).hasClass('k-group-cell'))
                        continue;                           //grouping enabled will add extra td columns that aren't actual columns
                    if ($(colCells[j]).hasClass('k-hierarchy-cell'))
                        continue;                           //hierarchy cell is not actual column             
                    grid.editCell($(colCells[j]));          //open for edit
                    if (grid.editable) {                    //check if editable
                        if (!grid.editable.end()) {         //trigger validation
                            return false;                   //if fail, return false
                        }
                        else {
                            grid.closeCell();               //if success, keep checking
                        }
                    }
                }
            }
        }
        return true;                                        //all cells are valid
    }

The differences are:

  • Checks grid.editable is not null before calling grid.editable.end(). This was the main change that I needed as I have cells that are not editable.
  • Runs validation for both new and updated rows. Note that IsNew() is a function whereas IsUpdated is a boolean.
  • Skips cells with class k-hierarchy-cell. This is only needed in hierarchical grids (which is what I'm using this for).