How to show validation message on row that fails a validation check?

How to show validation message on row that fails a validation check?

nsscottnsscott Posts: 24Questions: 10Answers: 0

I use inline editing on my datatable and need to introduce the validation shown below. Specifically, if a row's PP column is checked, the that row's total Qty value must be evenly divisible by that row's Pairs/Case value. Ideally I would like a pop up bubble like the one shown below to be displayed advising the error. Is there a way to do this?

Answers

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421
    edited May 2020

    Regardless of the editing style (inline, form or bubble) you can use a validator for this.
    https://editor.datatables.net/manual/php/validation#Validator-method

    In your case it will be a custom validator. Take a look at "Custom field validators" on that page.

    In your custom validator you can use other values of the same table row you are editing easily. Here is an example from my own coding which shows this: To validate the end_date of a report I need to determine its report_type.number which may not even be part of the table row. The I pass the entire "report" record and some other values into the custom validator function. In a nutshell you can do anything with those validators ...

    Field::inst( 'report.end_date' )
        ->validator( function ( $val, $data, $opts ) use ($msg, $db) {
           if ( $val <= ' ' ) {
               return $msg[0];
           }
           if ( $data['report_type']['number'] <= ' ' ) {
                $row = $db->raw()
                ->bind( ':id', $data['report']['report_type_id'] )
                ->exec('SELECT `number` FROM `report_type` WHERE id = :id')
                ->fetch(PDO::FETCH_ASSOC);
                $data['report_type']['number'] = $row["number"];
           }
           return validatorEndDate($data['report'], $val, null, true, $data['report_type']['number']);
        } )
    
  • nsscottnsscott Posts: 24Questions: 10Answers: 0

    Thank you again for the reply.

    Ths look promising. What I can't figure out is how the error is displayed to the user in an inline eidtor. Are you aware of an example out there that shows this functionality?

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Those field errors are displayed like in here in red text

    You can intercept the error message here:

    table
      .on('postSubmit', function (e, json, data, action) {
          if ( json.FieldErrors ) {
             .... take a look at json.fieldErrors
          }
    });
    
  • nsscottnsscott Posts: 24Questions: 10Answers: 0

    I. Love. That.

    Cracking on with this now. Thanks!

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Thanks and good luck. “postSubmit“ is an Editor event, not a DT event. Sorry.

  • nsscottnsscott Posts: 24Questions: 10Answers: 0

    I'm doing this client-side so followed example as best I can. It kind of works but I really want it to be triggered when the user completes the row. This gives the user the change to complete all the quantity fields. Any thoughts on how I can do that?

            mainEditor.on('preSubmit', function (e, o, action) {
                if (action == "edit") {
                    var pairsPerCaseString = this.field('PairsPerCase');
                    var totalPairsString = this.field('TotalPairs');
    
                    var pairsPerCase = parseIntSafe(pairsPerCaseString);
                    var totalPairs = parseIntSafe(totalPairsString);
    
                    if (totalPairs % pairsPerCase)
                        pairsPerCase.error('Invalid PrePack pairs');
    
                    if (this.inError()) {
                        return false;
                    }
                }
            });
    
  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    ... but I really want it to be triggered when the user completes the row.

    I am not sure I understand what that really means. I would understand it that way: The user submits the work because that is the time the user thinks she is done. But you seem to have a different understanding?! Let's assume you mean the user fills out the bottom field of the form (which would only work in a create situation, not for editing because then the bottom field will be filled already).

    Or the user fills out one of the quantity fields: You could check whether the other quantity fields contain appropriate values.

    You might want to use "dependent" for this. https://editor.datatables.net/reference/api/dependent()

    If you have multiple quantity fields that are interdependent you will need multiple "dependent"s as well. Can become fairly complex ... I personally use it to dynamically show / hide / set Editor form fields based on user entries, not for "early" validation of user entries.

  • rf1234rf1234 Posts: 2,991Questions: 87Answers: 421

    Just noticed you were debating inline editing. So you might mean inline editing the right most column of your Data Table.

    If you only want to do the validation when that happens you could also use "dependent" or you could use a separate Editor just for that one field and do the "preSubmit" validation for it.

  • nsscottnsscott Posts: 24Questions: 10Answers: 0

    Ok...still stuggling! I found adding a text message changed the column size and looked pretty terrible in my case. So I've tried to simply highlight the field toflag the issue. Unfortunately, the below isn't working. Any suggestions on how I should be approaching this?

        mainEditor.on('preSubmit', function (e, o, action) {
            if (action == "edit") {                                         //Only interested in changes
                var pairsPerCaseField = this.field('PairsPerCase');         //Get field related to PairsPerCase
                //var totalPairsField = this.field('TotalPairs');           //How do I get value of a calculated field?
    
                var pairsPerCase = parseIntSafe(pairsPerCaseField.val());   //Get int value of PairsPerCase
                //var totalPairs = parseIntSafe(totalPairsField);           //Get int value of TotalPairs
                if (totalPairs % pairsPerCase) {                            //If mod has a remainder then value is invalid
                                                                            //Try and highlight 3'rd column of problem row to flag issue.  
                                                                            //Nonsense below does not work
                    var rowIdx = mainTable.cell(this).index();                
                    $(mainTable.rows(rowIdx).column(3).nodes()).addClass('highlight');
                }
            }
        });
    

  • colincolin Posts: 15,240Questions: 1Answers: 2,599
                $(mainTable.rows(rowIdx).column(3).nodes()).addClass('highlight');
    

    I suspect you want to use cells().nodes(), or if the one cell you want highlighted, then cell().node(),

    Colin

This discussion has been closed.