yii2-dynamicform icon indicating copy to clipboard operation
yii2-dynamicform copied to clipboard

Does not work correctly with unique validator

Open igorbelikov opened this issue 9 years ago • 9 comments

Not correctly work with unique validator :(

igorbelikov avatar Apr 06 '15 22:04 igorbelikov

Please, very important for, help and fix it!

igorbelikov avatar Apr 06 '15 22:04 igorbelikov

It seems to work well for me. How is the code in your view?

wbraganca avatar Apr 09 '15 18:04 wbraganca

For example:

rules: [['content'], 'unique', 'attributes' => ['content', 'row_id']],

controller:

  1. data handling with transaction
  2. you do once multipleValidation and result is TRUE
  3. models saving and validation is not work, because in db inserting rows:
content   | row_id
text1     | 1
text1     | 1 // must be error
text2     | 1

igorbelikov avatar Apr 09 '15 18:04 igorbelikov

same issue for me. I have unique group for multi columns but instead of showing custom error, it shows PHP error of duplicate for unique.

pooreal avatar Mar 10 '16 13:03 pooreal

@pooreal, I seem to have solved this problem, I had to slightly change the mechanism for creating / updating models.

igorbelikov avatar Mar 10 '16 13:03 igorbelikov

@igorbelikov how?

pooreal avatar Mar 10 '16 17:03 pooreal

If I understand correctly, the problem is to add the same record in the form. Unique validator will not help, because the record is not added to the database

made for myself this method, unfortunately it is not universal

` private function validateMultipleAuthors($modelsAuthors) {

    $source = [];
    $duplicate = [];
    $result = [];

     // @var modelAuthor: id, initials

    $valid = Model::validateMultiple($modelsAuthors);

    // get authors from adding form
    foreach ($modelsAuthors as $key => $author)
        $source[] = $author->initials;

    // get duplicate values
    foreach (array_count_values($source) as $value => $count)
        if ($count > 1)
            $duplicate[] = $value;

    // Add error where fields repeat
    foreach ($modelsAuthors as $key => $author) {
        if (in_array($author->initials, $duplicate)) {
            $author->addError('initials', 'Author has already introduced');
            $valid = false;
        }
    }

    // return an error when Ajax validation in a separate action
    if (Yii::$app->response->format == Response::FORMAT_JSON) {
        foreach ($modelsAuthors as $i => $author)
            foreach ($author->getErrors() as $attribute => $errors)
                $result[Html::getInputId($author, "[$i]" . $attribute)] = $errors;
        return $result;
    }

    return $valid;
}`

ABariy avatar Mar 26 '16 17:03 ABariy

Hi you can use validation on client, this work for me

$('#dynamic-form').on('afterValidate', function (e) {
       var valx = document.querySelectorAll('select[id$=item_id]'); //i use select2 kartik for item_id
       var arritem = Array.from(valx);
       var result = arritem.map(function(a) {return a.value;});
       Array.from(valx).forEach(function(el){           
             var itemid = el.id;
             var itemval = el.value;
        
             var count = 0;
               for(var i = 0; i < result.length; ++i){
                   if(result[i] == itemval)
                       count++;
               }
               

               if (count > 1){
                    $('#dynamic-form').yiiActiveForm('updateAttribute', itemid, ['duplicate error...']);                       
               }

       });

   return true;
   
 }); 
 
 $('#dynamic-form').on('beforeSubmit', function () {
     var form = $(this);
     if (form.find('.has-error').length) {
         return false;
     }
     return true; // form gets submitted
 });

sciefylab avatar May 27 '17 00:05 sciefylab

@sciefylab: This is exactly what I needed! Thank you. One problem remains: the error summary doesn't get updated. I tried to do:

$('#dynamic-form').yiiActiveForm('updateMessages', { itemid, ['duplicate error...'] }, true);

But the error summary gets overridden and the message gets deleted again. Even after hours of searching I cannot figure out where exactly this happens. Any ideas how to solve this?

ThomiLee avatar Oct 05 '18 06:10 ThomiLee