4

Using the jQuery datatable editor plug-in, the following code works as intended. It performs specified validations (some of the fields have been omitted for brevity).

Editor::inst( $db, 'file_upload' )
    ->fields(
        Field::inst( 'id' )->validator( 'Validate::notEmpty' ),

        Field::inst( 'name' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            return $length > 30 ? 'Length must be 30 characters or less' : true;
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        }),

        Field::inst( 'document_title' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            return $length > 50 ? 'Length must be 50 characters or less' : true;
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        }),

        Field::inst( 'email_address' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            return $length > 60 ? 'Length must be 60 characters or less' : true;
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        })
    )->where( function ( $q ) {
        $q->where( 'file_type', "('jpg', 'jpeg', 'gif', 'png')", 'IN', false );
    })->process( $_POST )
    ->json();

But when the validation logic is slightly modified like the following,

Editor::inst( $db, 'file_upload' )
    ->fields(
        Field::inst( 'id' )->validator( 'Validate::notEmpty' ),

        Field::inst( 'name' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            // The following line has been modified
            return $length === 0 ? 'This field is required' : ($length > 30 ? 'Length must be 30 characters or less' : true);
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        }),

        Field::inst( 'document_title' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            // The following line has been modified
            return $length === 0 ? 'This field is required' : ($length > 50 ? 'Length must be 50 characters or less' : true);
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        }),

        Field::inst( 'email_address' )->validator( 'Validate::notEmpty' )
        ->validator( function ($val, $data, $opts) {
            $length = strlen(trim(preg_replace('/\s+/', ' ', $val)));
            // The following line has been modified
            return $length === 0 ? 'This field is required' : ($length > 60 ? 'Length must be 60 characters or less' : true);
        })->getFormatter( function ( $val, $data, $opts ) {
            return htmlspecialchars($val, ENT_QUOTES, "UTF-8");
        })->setFormatter( function ( $val, $data, $opts ) {
            return trim(preg_replace('/\s+/', ' ', $val));
        })
    )->where( function ( $q ) {
        $q->where( 'file_type', "('jpg', 'jpeg', 'gif', 'png')", 'IN', false );
    })->process( $_POST )
    ->json();

In this case, validations are performed as they should but values are not submitted (and concurrently the datatable is not updated) to the database. The inline editing textbox remains open after the enter key is pressed.

What could be the reason and how to fix it? Possibly, I am missing something very basic about PHP.

I will post the corresponding client script, if needed.


It appears that other validators are triggered, when extra conditions are enforced preventing input values from being submitted to the abstract layer, database. This should not happen in case of inline cell editing.

What is the remedy?

Tiny
  • 27,221
  • 105
  • 339
  • 599

1 Answers1

1

If the only changes to your code are those lines you highlighted with your comments, I would suspect the problem is your use of the nested ternary operator. These two separate questions in the PHP tag may clear some things up, but basically the quick version is that the PHP ternary operator has some strange behavior, and so it is not recommended to use them nested. I'd recommend you try switching to a standard if/else statement to see if that solves your problem, so

if($length === 0){
    return 'This field is required';
}
else if($length > 50){
    return 'Length must be 50 characters or less';
}
else{
    return true;
}

While this may be longer, it will likely be much easier to debug and I suspect based on your question that if this was all that was changed your issue comes down to the left-associative ternary operator nesting; whereas in nearly every other language ternary operators are right-associative.

Here's one more link recommending against nested ternary operators in PHP.

The text box remaining open after hitting submit is standard for a DataTables JavaScript form error, which is common when a CRUD operation serverside does not return the expected value to the client (examine your browser developer console to ensure you aren't getting a JS error, I recommend getting Firebug for Firefox if you want a really robust one). If after modifying your code to use the if/else block instead of the ternary operators you still have the error, then I would look into your clientside code to ensure that nothing else has changed (mabye you could post it in the question if this doesn't resolve your issue).

Community
  • 1
  • 1
Chris H.
  • 2,544
  • 19
  • 32