Data validation in rowCallBack instead of validating in 'preSubmit'.

Data validation in rowCallBack instead of validating in 'preSubmit'.

d052057d052057 Posts: 38Questions: 3Answers: 0

I am not sure this is the right way or not but this is what I am trying to accomplish - validate data in rowCallBack.
let says col_a is TotalCount, col_b is Length, col_c is Width, Col_d is Height and Col_e is for 'edit/delete' functions.
In rowCallBack function:
i check totalCount (sum of col_a) > 28 and then it throws error to row, col_a.
I check col_b, col_c, col_d to make sure they are all have values. If one of them is empty then it throws error to the column that is empty.
I tried to trigger click on 'edit/delete', but it doesn't work (row.cells[4].firstChild.click();).

Any suggestion?

rowCallback: function (row, data) {
            var totalCount = 0;
            $("#PalletDetails_CountList").val($(pltTable).DataTable().column(1).data().join(vm));
            $("#PalletDetails_LengthList").val($(pltTable).DataTable().column(2).data().join(vm));
            $("#PalletDetails_WidthList").val($(pltTable).DataTable().column(3).data().join(vm));
            $("#PalletDetails_HeightList").val($(pltTable).DataTable().column(4).data().join(vm));
            $.each($(pltTable).DataTable().column(1).data(), function (index, value) {
                totalCount = parseInt(totalCount) + parseInt(value);                
            });
            if (totalCount > 28) {
                row.cells[0].error = "Count must be less then 29";
                row.cells[4].firstChild.click();
            };
            if (!(data.pltLength == '' && data.pltWidth == '' && data.pltHeight == '')) {
                if (data.pltWidth == '') {
                    row.cells[2].error = "Width is required";
                    // click on edit a.editor_edit
                    row.cells[4].firstChild.click();
                }
                if (data.pltLength == '') {
                    row.cells[1].error = "Length is required";
                    row.cells[4].firstChild.click();
                }
                if (data.pltHeight == '') {
                    row.cells[3].error = "Height is required";
                    row.cells[4].firstChild.click();
                }
            }
            
        },

Replies

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Hi @d052057 ,

    We're happy to take a look. As per the forum rules, if you could link to a running test case showing the issue we can offer some help. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • d052057d052057 Posts: 38Questions: 3Answers: 0

    The application I have written is not small and it is not easy to modify and it is not just HTML and Javascript. Of cause it is MVC5 environment. I will try it create a small app but I can't assure it will work because it links to datatables.net and editor purchased and installed locally here.
    The logic of this validation is this:
    1. In preSubmit, I can validate each cell but I can not validate the other cells at the same times (for example, col_b, col_c, cod_d (all of them) must have values or all of them must be empty and the sum of col_a must be less 29).
    2. I can do this in the rowCallBack but I don't know the way to do it.
    3. If the condition isn't met in #1, then it will trigger the editor screen (motal Editor screen shows up) so that user can make correction (I tried to do click on firstChild of edit/delete column link but it doesn't work).

    Thanks.

  • d052057d052057 Posts: 38Questions: 3Answers: 0
    edited November 2018

    This is the code...

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="Scripts/jquery-3.3.1.min.js"></script>
        <script src="Scripts/respond.min.js"></script>
        <script src="Datatables/datatables.js"></script>
        <script src="Datatables/Buttons-1.5.4/js/buttons.bootstrap4.js"></script>
        <script src="Scripts/bootstrap.js"></script>
    
        <link href="Content/bootstrap.css" rel="stylesheet" />
        <link href="Datatables/datatables.css" rel="stylesheet" />
        <link href="Datatables/Select-1.2.6/css/select.bootstrap4.min.css" rel="stylesheet" />
        <link href="Datatables/Editor-1.8.0/css/editor.bootstrap4.min.css" rel="stylesheet" />
        <link href="Datatables/Buttons-1.5.4/css/buttons.bootstrap4.min.css" rel="stylesheet" />
        <script type="text/javascript">
            var plt_editor; // use a global for the submit and return data rendering in the examples
    
            var pltTable = '#palletTable';
    
            $(document).ready(function () {
                var DataTable = $.fn.dataTable;
                // Pallet Table
                plt_editor = new $.fn.dataTable.Editor({
                    table: pltTable,
                    fields: [
                        {
                            label: "Pallet Count:",
                            name: "pltCount",
                        },
                        {
                            label: "Length",
                            name: "pltLength"
    
                        },
                        {
                            label: "Width",
                            name: "pltWidth"
                        },
                        {
                            label: "Height",
                            name: "pltHeight"
                        }
                    ]
    
                });
                $(pltTable).DataTable({
                    dom: 'rBt',
                    display: 'envelope',
                    rowCallback: function (row, data) {
                        var totalCount = 0;
                        $.each($(pltTable).DataTable().column(0).data(), function (index, value) {
                            totalCount = parseInt(totalCount) + parseInt(value);
                        });
                        if (totalCount > 28) {
                            row.cells[0].error = "Count must be less then 29";
                            row.cells[4].firstChild.click();
                            // to do how to trigger 'Edit' to edit data -- CODE?
                        };
                        if (!(data.pltLength == '' && data.pltWidth == '' && data.pltHeight == '')) {
                            if (data.pltLength == '') {
                                row.cells[1].error = "Length is required";
                                row.cells[4].firstChild.click();
                                // to do how to trigger 'Edit' to edit data -- CODE?
                            }
                            if (data.pltWidth == '') {
                                row.cells[2].error = "Width is required";
                                // click on edit a.editor_edit
                                row.cells[4].firstChild.click();
                                // to do how to trigger 'Edit' to edit data -- CODE?
                            }                        
                            if (data.pltHeight == '') {
                                row.cells[3].error = "Height is required";
                                row.cells[4].firstChild.click();
                                // to do how to trigger 'Edit' to edit data -- CODE?
                            }
                        }
    
                    },
                    columns: [
                        { data: "pltCount", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                        { data: "pltLength", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                        { data: "pltWidth", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                        { data: "pltHeight", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                        {
                            data: null,
                            className: "center",
                            defaultContent: '<a href="" class="editor_edit">Edit</a> / <a href="" class="editor_remove">Delete</a>'
                        }
                    ],
                    select: true,
                    buttons: [
                        {
                            extend: "create",
                            editor: plt_editor,
                            title: "this is a create",
                            className: "btn btn-primary"
                        }]
                });
                $(pltTable).on('click', 'a.editor_edit', function (e) {
                    e.preventDefault();
                    plt_editor
                        .title('Edit record')
                        .buttons({ "label": "Update", "fn": function () { plt_editor.submit() } })
                        .edit($(this).closest('tr'));
                });
    
                // Delete a record
                $(pltTable).on('click', 'a.editor_remove', function (e) {
                    e.preventDefault();
    
                    plt_editor
                        .title('Edit record')
                        .message("Are you sure you wish to delete this row?")
                        .buttons({ "label": "Delete", "fn": function () { plt_editor.submit() } })
                        .remove($(this).closest('tr'));
                });
    
                plt_editor.on('preSubmit', function (e, data, action) {
                    if (action == "create" || action == 'edit') {
                        var plt_length = this.field('pltLength');
                        if (isNaN(plt_length.val())) {
                            plt_length.error('Pallet Length Must be Number.');
                        };
                        var plt_width = this.field('pltWidth');
                        if (isNaN(plt_width.val())) {
                            plt_width.error('Pallet Width Must be Number.');
                        };
                        var plt_height = this.field('pltHeight');
                        if (isNaN(plt_height.val())) {
                            plt_height.error('Pallet Height Must be Number.');
                        };
                        var plt_count = this.field('pltCount');
                        if (isNaN(plt_count.val())) {
                            plt_count.error('Pallet Count Must be Number.');
                        };
                        if (plt_count.val().length == 0) {
                            plt_count.error('Pallet Count is required.');
                        };
                        // validat total
                        var total = 0;
                        var pltCount = $(pltTable).DataTable().column(0).data();
                        $(pltCount).each(function (index, element) {
                            total = total + parseInt(element);
                        });
    
                        switch (action) {
                            case "create":
                                total = total + parseInt(plt_count.val());
                        }
                        if (total > 28) {
                            plt_count.error('Total Pallet Count must be less than 29.');
                        }
    
                    }
                    if (this.inError()) {
                        return false;
                    }
                    return true;
                });
                $(pltTable).on('click', 'tbody td:not(:nth-child(4))', function (e) {
                    //to do add logic to prevent user clicks on empty table after initializing, 'no data in Table', what is the code?
                        plt_editor.inline(this, {
                            onBlur: 'submit'
                        });
                });
            });
    
        </script>
    </head>
    <body>
        <div class="row">
                <div Class="col-md-12" id="pltDiv">
                    <div Class="container pb-2 pt-2">
                        <Table id="palletTable" class="table table-sm table-bordered table-hover" style="width: 100%;">
                            <thead>
                                <tr>
                                    <th>Plt Count</th>
                                    <th>Length</th>
                                    <th>Width</th>
                                    <th>Heigth</th>
                                    <th>Edit/Delete</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                            <tfoot>
                            </tfoot>
                        </Table>
                    </div>
                </div>
            </div>
    
    </body>
    </html>
    
  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    row.cells[4].firstChild.click();

    You are mixing DOM methods and jQuery there. I think $(row.cells[4].firstChild).click() might have more success.

    That said, rowCallback is too late to do validation. The invalidate data is already in the data set. Where I can see this being useful is if you wanted to allow the end user to enter information in a cell that makes the row as a whole invalid, then changing another cell making it valid. Adding an "invalid" class or similar might be useful to the row, highlighting that it has duff data until it is fixed.

    What might be useful here is local table editing - so you get all the changes for the row locally before submitting them to be saved in the database (since the database should never contain invalid data).

    Allan

  • d052057d052057 Posts: 38Questions: 3Answers: 0

    Thank for your input. You're right (I come from DOM environment). I will try it later. RowCallback is the only option in my thinking since I can trigger edit click to ask user to make correction. Until they make correction then they can pass the rowCallback function.
    I still can not figure out how the 'invalid' class which you've sugested (I am new to this). The logic for each row are:
    1. All 3 columns (length, width, height) must be empty or all having values.
    2. The sum of Ptl Count column must be less than 29 (in this case).

    If I add an 'Invalid' class to a row, how am I going to add 'Invalid error message' below the row (is there a link about this method) ?

    Line 163: I would like to know a way to detect datatables empty or not (I see discussion but not solution). The issue is that user click on a row contains "no data available in Table..."

    if $(pltTable).empty() {
    // add row
    }
    else {
    plt_editor.inline(this, {
    onBlur: 'submit'
    });
    }

    Thank you again for your help.

  • d052057d052057 Posts: 38Questions: 3Answers: 0

    $(row.cells[4].firstChild).click() works to back motal Editor Screen popup. However, it fails validation when 'X' is clicked. The 'X' doesn't do anything except closing the motal screen. Then I have bad data in the tables.

    Is there any suggestion?

    Thanks.

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    Line 163: I would like to know a way to detect datatables empty or not

    Use page.info().

    I still can not figure out how the 'invalid' class which you've sugested (I am new to this).

    rowCallback: function ( tr, data ) {
      if ( ... invalid data ... ) {
        $(tr).addClass('invalid');
      }
      else {
        $(tr).removeClass('invalid');
      }
    }
    

    However, it fails validation when 'X' is clicked. The 'X' doesn't do anything except closing the motal screen. Then I have bad data in the tables.

    The X should mean "close the current edit and don't save changes - returning the data to the previous state".

    As I said before, you need to consider that you are allowing users to enter invalid data. I don't know if you want to allow that or not.

    Allan

  • d052057d052057 Posts: 38Questions: 3Answers: 0

    Finally, I've figured it out to do this in 'preSubmit' event, but the rowCallBack. The inline edit doesn't work either but I can disable the inline edit mode for now (it will pass the validation if i do it from the Inline Edit mode.
    Here is the code if any interested to see what I have done.
    ```

    <!DOCTYPE html>
    <html>
    <head>
    <title></title>
    <meta charset="utf-8" />
    <script src="Scripts/jquery-3.3.1.min.js"></script>
    <script src="Scripts/respond.min.js"></script>
    <script src="Datatables/datatables.js"></script>
    <script src="Datatables/Buttons-1.5.4/js/buttons.bootstrap4.js"></script>
    <script src="Scripts/bootstrap.js"></script>

    <link href="Content/bootstrap.css" rel="stylesheet" />
    <link href="Datatables/datatables.css" rel="stylesheet" />
    <link href="Datatables/Select-1.2.6/css/select.bootstrap4.min.css" rel="stylesheet" />
    <link href="Datatables/Editor-1.8.0/css/editor.bootstrap4.min.css" rel="stylesheet" />
    <link href="Datatables/Buttons-1.5.4/css/buttons.bootstrap4.min.css" rel="stylesheet" />
    <script type="text/javascript">
        var plt_editor; // use a global for the submit and return data rendering in the examples
    
        var pltTable = '#palletTable';
    
        $(document).ready(function () {
            var DataTable = $.fn.dataTable;
            // Pallet Table
            plt_editor = new $.fn.dataTable.Editor({
                table: pltTable,
                fields: [
                    {
                        label: "Pallet Count:",
                        name: "pltCount",
                    },
                    {
                        label: "Length",
                        name: "pltLength"
    
                    },
                    {
                        label: "Width",
                        name: "pltWidth"
                    },
                    {
                        label: "Height",
                        name: "pltHeight"
                    }
                ]
    
            });
            $(pltTable).DataTable({
                dom: 'rBt',
                display: 'envelope',
                rowCallback: function (row, data) {
                    //if (!(data.pltLength == '' && data.pltHeight == '' && data.pltWidth == '')) {
                    //    $(row).addClass('invalid');
                    //}
                },
                columns: [
                    { data: "pltCount", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                    { data: "pltLength", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                    { data: "pltWidth", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                    { data: "pltHeight", render: $.fn.dataTable.render.number(',', '.', 0, '') },
                    {
                        data: null,
                        className: "center",
                        defaultContent: '<a href="" class="editor_edit">Edit</a> / <a href="" class="editor_remove">Delete</a>'
                    }
                ],
                select: true,
                buttons: [
                    {
                        extend: "create",
                        editor: plt_editor,
                        title: "this is a create",
                        className: "btn btn-primary"
                    }]
            });
            $(pltTable).on('click', 'a.editor_edit', function (e) {
                e.preventDefault();
                plt_editor
                    .title('Edit record')
                    .buttons({ "label": "Update", "fn": function () { plt_editor.submit() } })
                    .edit($(this).closest('tr'));
            });
    
            // Delete a record
            $(pltTable).on('click', 'a.editor_remove', function (e) {
                e.preventDefault();
                plt_editor
                    .title('Remove record')
                    .message("Are you sure you wish to delete this row?")
                    .buttons({ "label": "Delete", "fn": function () { plt_editor.submit() } })
                    .remove($(this).closest('tr'));
            });
    
            plt_editor.on('preSubmit', function (e, data, action) {
    
                if (action == "create" || action == 'edit') {
                    var plt_length = this.field('pltLength');
                    if (isNaN(plt_length.val())) {
                        plt_length.error('Pallet Length Must be Number.');
                    };
                    var plt_width = this.field('pltWidth');
                    if (isNaN(plt_width.val())) {
                        plt_width.error('Pallet Width Must be Number.');
                    };
                    var plt_height = this.field('pltHeight');
                    if (isNaN(plt_height.val())) {
                        plt_height.error('Pallet Height Must be Number.');
                    };
                    var plt_count = this.field('pltCount');
                    if (isNaN(plt_count.val())) {
                        plt_count.error('Pallet Count Must be Number.');
                    };
                    if (plt_count.val().length == 0) {
                        plt_count.error('Pallet Count is required.');
                    };
                    if (this.inError()) {
                        return false;
                    }
    
                    // validate Column all empty or all values
                    if (!(plt_length.val() == '' && plt_width.val() == '' && plt_height.val() == '')) {
                        if (plt_width.val() == '') {
                            plt_width.error('Pallet Width Is Required.');
                        }
                        if (plt_length.val() == '') {
                            plt_length.error('Pallet Length Is Required.');
                        }
                        if (plt_height.val() == '') {
                            plt_height.error('Pallet Height Is Required.');
                        }
                    }
                    // validat total
                    var total = 0;
                    var pltCount = $(pltTable).DataTable().column(0).data();
                    $(pltCount).each(function (index, element) {
                        total = total + parseInt(element);
                    });
    
                    switch (action) {
                        case "edit":
                            var originalData = this.s.mode === 'main' ?
                            this._dataSource('fields', this.modifier()) :
                            this._dataSource('individual', this.modifier());
                            $.each(data.data, function (key, vals) {
                                var origValue = originalData[key].data.pltCount;
                                total = total + parseInt(plt_count.val()) - parseInt(origValue)
                            });
                        case "create":
                            total = total + parseInt(plt_count.val());
                    }
                    if (total > 28) {
                        plt_count.error('Total Pallet Count must be less than 29.');
                    }
    
                }
                if (this.inError()) {
                    return false;
                }
                return true;
            });
            $(pltTable).on('click', 'tbody td:not(:nth-child(5))', function (e) {
                plt_editor.inline(this, {
                    onBlur: 'submit'
                });
            });
        });
    
    </script>
    

    </head>
    <body>
    <div class="row">
    <div Class="col-md-12" id="pltDiv">
    <div Class="container pb-2 pt-2">
    <Table id="palletTable" class="table table-sm table-bordered table-hover" style="width: 100%;">
    <thead>
    <tr>
    <th>Plt Count</th>
    <th>Length</th>
    <th>Width</th>
    <th>Heigth</th>
    <th>Edit/Delete</th>
    </tr>
    </thead>
    <tbody></tbody>
    <tfoot>
    </tfoot>
    </Table>
    </div>
    </div>
    </div>

    </body>
    </html>

This discussion has been closed.