Проверка динамической формы Laravel Inertia

У меня есть кнопка, которая при нажатии добавляет некоторые входные данные в форму:

<a @click="addNewText()" class="items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray transition ease-in-out duration-150">
    <i class="far fa-2x fa-plus-square"></i>
</a>

Я использую Laravel 8 и Inertia и хочу проверить свою форму. Когда я пытаюсь проверить, входные данные формы не отображаются в $request-›input('texts'); если форма пуста. Если входы формы заполнены, то они появляются?

Вот мой код контроллера:

public function index()
{
    $texts = [];
    $texts = collect(
        [
            ['skill_level' => null, 'word_count' => null, 'title' => null, 'description' => null, 'category' => null]
        ]
    );
    //dd($texts->toJson());
    //return the view
    return Inertia::render('Client/OrderFormBuilder/GiantIndex', [
        "allTexts" => $texts->toJson()
    ]);
}

public function setOrderDetails(Request $request)
{
    $texts = $request->input('texts.*');
    $rules = [];
    $messages = [];

    for ($i = 0; $i < count($texts); $i++) 
    {
        $rules['texts[' . $i . '][skill_level]'] = 'required';
        $rules['texts[' . $i . '][word_count]'] = 'required';
        $rules['texts[' . $i . '][category]'] = 'required';
        //$rules['texts.' . $i . '.title'] = 'required|string|min:5|max:10000';
        //$rules['texts.' . $i . '.description'] = 'required|string|min:10|max:10000000';
    }

    for ($i = 0; $i < count($texts); $i++) 
    {
        $messages['texts[' . $i . '][skill_level].required'] = 'Please Enter Your Desired Skill Level.';
        $messages['texts[' . $i . '][word_count].required'] = 'Please Enter Your Desired Word Count.';
        $messages['texts[' . $i . '][category].required'] = 'Please Enter Your Desired Category.';
        /*
        $messages['texts.' . $i . '.title.required'] = 'A Title Is Required For Your Text.';
        $messages['texts.' . $i . '.title.string'] = 'Please Enter A Valid Title For Your Text.';
        $messages['texts.' . $i . '.title.min'] = 'Please Enter A Minimum Of 5 Characters For Your Title.';
        $messages['texts.' . $i . '.title.max'] = 'Please Enter A Maximum Of 10000 Characters For Your Title.';
        $messages['texts.' . $i . '.description.required'] = 'A Description Is Required For Your Text.';
        $messages['texts.' . $i . '.description.string'] = 'Please Enter A Valid Description For Your Text.';
        $messages['texts.' . $i . '.description.min'] = 'Please Enter A Minimum Of 10 Characters For Your Description.';
        $messages['texts.' . $i . '.description.max'] = 'Please Enter A Maximum Of 10000000 Characters For Your Description.';
        */
    }

    //dd($texts, $rules, $messages);

    Validator::make($texts, $rules, $messages)->validateWithBag('updateOrderFormBuilder');
}

А вот мой код шаблона формы Vue:

<div v-for="(singleText, index) in form.texts" v-bind:key="index" class="shadow sm:rounded-md sm:overflow-hidden mt-5">
<div class="bg-white py-6 px-4 space-y-6 sm:p-6">
    <div class="col-span-6 sm:col-span-4">
        <div>
            <label class="block font-medium text-sm text-gray-700" for="skill_level">Skill Level</label>
            <input :id="'skill_level_' + index" :name="'texts[' + index + '][skill_level]'" type="text" class="form-input rounded-md shadow-sm mt-1 block w-full" v-model="singleText.skill_level" :autocomplete="'texts[' + index + '][skill_level]'" />
            <div v-if="form.error('texts[' + index + '][skill_level]')">
            <p class="text-sm text-red-600">
                {{ form.error('texts[' + index + '][skill_level]') }}
            </p>
            </div>
            <label class="block font-medium text-sm text-gray-700" for="word_count">Word Count</label>
            <input :id="'word_count_' + index" :name="'texts[' + index + '][word_count]'" type="text" class="form-input rounded-md shadow-sm mt-1 block w-full" v-model="singleText.word_count" :autocomplete="'texts[' + index + '][word_count]'" />
            <div v-if="form.error('texts[' + index + '][word_count]')">
            <p class="text-sm text-red-600">
                {{ form.error('texts[' + index + '][word_count]') }}
            </p>
            </div>
            <label class="block font-medium text-sm text-gray-700" for="category">Category</label>
            <input :id="'category_' + index" :name="'texts[' + index + '][category]'" type="text" class="form-input rounded-md shadow-sm mt-1 block w-full" v-model="singleText.category" :autocomplete="'texts[' + index + '][category]'" />
            <div v-if="form.error('texts[' + index + '][category]')">
            <p class="text-sm text-red-600">
                {{ form.error('texts[' + index + '][category]') }}
            </p>
        </div>
    </div>
</div>

Наконец, вот мой код Vue:

props: ['allTexts'],

    data: function() {
        return {
            showingNavigationDropdown: false,
            text: {
                skill_level: null,
                word_count: null,
                title: null,
                description: null,
                category: null,
            },
            form: this.$inertia.form({
                '_method': 'POST',
                texts: [],
            }, {
                bag: 'updateOrderFormBuilder',
                resetOnSuccess: false,
            }),    
        }
    },

    mounted: function () {
        this.form.texts = JSON.parse(this.allTexts); //this.allTexts;
        console.log(this.form.texts);
    },

    methods: {
        switchToTeam(team) {
            this.$inertia.put(route('current-team.update'), {
                'team_id': team.id
            }, {
                preserveState: false
            })
        },

        logout() {
            axios.post(route('logout').url()).then(response => {
                window.location = '/';
            })
        },

        submit() {
            this.$inertia.post(route('create-new-order.set-order-details-by-form', this.form), {
                preserveScroll: true
            })
        },
        
        addNewText() {
            if(this.form.texts.length < 20)
            {
                this.form.texts.push(this.text);
                
                console.log(this.form.texts, this.text);
            }
        },

        removeText: function(index) {
            if(this.form.texts.length > 1)
            {
                this.form.texts.splice(index, 1);
            }         
        }
    }

Почему, когда я нажимаю кнопку отправки, $request-›input('texts.*'); не работа? Он всегда ничего не показывает, когда форма пуста, и показывает только входные данные, когда они были заполнены в форме?


person summer9844    schedule 17.11.2020    source источник
comment
Должно ли где-то быть определение Request::validate? inertiajs.com/forms   -  person wp78de    schedule 18.11.2020


Ответы (1)


Я думаю, вам нужно использовать и отправлять данные form.text. Обратите внимание, что ваш inertia.post() использует другой параметр

person Rasyidi Alwee    schedule 10.02.2021
comment
Добро пожаловать в Stack Overflow! Я рекомендую отказаться от риторических вопросов в ответах. Они рискуют быть неправильно понятыми как не ответ вообще. Вы пытаетесь ответить на вопрос вверху этой страницы, не так ли? В противном случае удалите этот пост. - person Yunnosch; 12.02.2021