Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hasMany form validation not working on single submit click #5816

Open
Sivan4562 opened this issue Sep 13, 2023 · 4 comments
Open

hasMany form validation not working on single submit click #5816

Sivan4562 opened this issue Sep 13, 2023 · 4 comments

Comments

@Sivan4562
Copy link

  • Laravel Version: ^10.10
  • PHP Version: 8.1
  • Laravel-admin: ^1.8

Description:

Hi Team,
I am using the hasMany form and I use the ->rules('required') for the form required field when I click the submit button the first time the validation error does not throw the error message when I click the second time it shows the error. Do you know how I can fix this? I attached my code as below.

This is form data

$form->hasMany('customer_experience','Experience Info',function (Form\NestedForm $form) {
   $form->text('title', 'Title')->rules('required');
   $form->text('company', 'Company')->rules('required');
   $form->text('location', 'Location')->rules('required');
   $form->date('start_date', 'Start Date')->rules('required');
   $form->date('end_date', 'End Date')->rules('required');
});

And model

public function customer_experience(){
       return $this->hasMany(CustomerExperience::class, 'customer_id');
}

Can anyone help me to fix this bug?

@alexoleynik0
Copy link

  1. Can you check DevTools to see if after first Submit click the request is being sent?
  2. Does it happen for a specific field or for any?
  3. Does it happen for a new hasMany entry or only when updating existing?
  4. Does the form has Tabs or other non-typical field that can "steal" focus?

@Sivan4562
Copy link
Author

Sivan4562 commented Sep 14, 2023

Hi @alexoleynik0, Good morning

  1. Yes when I submit the form the network shows the response call. I will be attached the screenshot below.
  2. The validation does not work only for hasMany at the first time.
  3. The hasMany does not throw an error when a new form is submitted and edits the existing form.

This is the form structure I have created:
image

During the First submission form it does not show an error
image

After clicking the submit button a second time it shows the error
image

Here the dev tool network response
image

@alexoleynik0
Copy link

Ok, now I see the issue on my side too.. Strangely, but I'm not sure we can fix it easily.
It seems that it's tied / similar to #2097 and #4612 issues.

In the PR #4976 it almost fixed by @shacky , so you can create your custom HasMany field based on this PR like so:

<?php

namespace App\Admin\Extensions\Form;

use Encore\Admin\Form\Field\HasMany;
use Encore\Admin\Form\NestedForm;
use Exception;
use Illuminate\Database\Eloquent\Relations\HasMany as Relation;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Arr;

class HasManyCustom extends HasMany
{
    /**
     * Build Nested form for related data.
     *
     * @return array
     *
     * @throws Exception
     */
    protected function buildRelatedForms()
    {
        if (is_null($this->form)) {
            return [];
        }

        $model = $this->form->model();

        $relation = call_user_func([$model, $this->relationName]);

        if (! $relation instanceof Relation && ! $relation instanceof MorphMany) {
            throw new Exception('hasMany field must be a HasMany or MorphMany relation.');
        }

        $forms = [];

        /*
         * If redirect from `exception` or `validation error` page.
         *
         * Then get form data from session flash.
         *
         * Else get data from database.
         */
        if ($values = old($this->column)) {
            foreach ($values as $key => $data) {
                if (1 == $data[NestedForm::REMOVE_FLAG_NAME]) {
                    continue;
                }

                $model = $relation->getRelated()->replicate()->forceFill($data);

                $forms[$key] = $this->buildNestedForm($this->column, function ($form) use ($key) {
                    $form->setKey($key);
                    call_user_func($this->builder, $form);
                }, $model)
                    ->fill($data)
                ;
            }
        } else {
            if (empty($this->value)) {
                return [];
            }

            foreach ($this->value as $data) {
                $key = Arr::get($data, $relation->getRelated()->getKeyName());

                $model = $relation->getRelated()->replicate()->forceFill($data);

                $forms[$key] = $this->buildNestedForm($this->column, $this->builder, $model)
                    ->fill($data)
                ;
            }
        }

        return $forms;
    }
}

Then declare it's use in app/Admin/bootstrap.php like so:

\Encore\Admin\Form::extend('hasManyCustom', \App\Admin\Extensions\Form\HasManyCustom::class);

And use it instead of default hasMany in your Forms:

$form->hasManyCustom('orders', __('Orders'), function (Form\NestedForm $nestedForm) {
    $nestedForm->text('active', 'active')->rules('required');
});

@alexoleynik0
Copy link

Unfortunately, that does not fix the issue with wrong new_{index} that happens after the form has been submitted and you try to add new items to HasMany field - it creates them starting with new_1 key and so on, that could be already used, so unpredictable bugs can occur -- you will get only one new Item where you expect to get two+ etc.

But that is a separate issue to yours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants