Laravel custom validation not working as intended

60 views Asked by At

So I've been having a problem in my custom validation. It only works to the Commodity Dropdown but in other textboxes, there is no error message. By the way, I am using alpinejs to add more rows.

input-components.blade.php:

<div x-data="eLinkageAddRow()">
    <template x-for="(row,index) in rows" :key="row.id">
        <div class="row">
            <div class="col-md-4 mb-2">
                <label for="associationName" class="form-label label-style">Association Name</label>
                <input type="text" class="form-control" name="associationName[]" id="associationName" autocomplete="off"
                    value="{{ $associationProfile->association }}" readonly>
            </div>

            <div class="col-md-3 mb-2">
                <label for="commodity" class="form-label label-style">Commodity</label>
                <select id="commodity" name="commodity[]" class="form-select">
                    <option selected disabled>Select Commodity</option>
                    @foreach ($commodityValues as $id => $value)
                        <option value="{{ $id }}">{{ $value }}</option>
                    @endforeach
                </select>
                @error('commodity')
                    <span class="fs-6 text-danger">{{ $message }}</span>
                @enderror
            </div>

            <div class="col-md-2 mb-2">
                <label for="Variety" class="form-label label-style">Variety</label>
                <input type="text" class="form-control" name="variety[]" id="variety" autocomplete="off">
                @error('variety')
                    <span class="fs-6 text-danger">{{ $message }}</span>
                @enderror
            </div>

            <div class="col-md-2 mb-2">
                <label for="end_Date" class="form-label label-style">Volume (Kg)</label>
                <input type="text" class="form-control" name="volume[]" id="volume" autocomplete="off">
                @error('volume')
                    <span class="fs-6 text-danger">{{ $message }}</span>
                @enderror
            </div>

            <div class="row">
                <div class="col-md-3 mb-2">
                    <label for="startDate" class="form-label label-style">Estimated
                        Time of Harvest <br> (Start Date)</label>
                    <input type="date" class="form-control" name="startDate[]" id="startDate">
                    @error('startDate')
                        <span class="fs-6 text-danger">{{ $message }}</span>
                    @enderror
                </div>

                <div class="col-md-3 mb-2">
                    <label for="endDate" class="form-label label-style">Estimated
                        Time of Harvest <br> (End Date)</label>
                    <input type="Date" class="form-control" name="endDate[]" id="endDate">
                    @error('endDate')
                        <span class="fs-6 text-danger">{{ $message }}</span>
                    @enderror
                </div>
            </div>
            <div x-show="index > 0">
                <div class="col-md-2 mb-2 d-flex mt-auto">
                    <button x-on:click="removeRow(index)" type="button" class="btn btn-danger">Remove</button>
                </div>
            </div>
            <hr>
        </div>
    </template>

    <div class="col-md-1 mb-2 d-flex mt-auto">
        <button x-on:click="addRow()" type="button" class="btn btn-success">Add more</button>
    </div>
</div>

StoreELinkageRequest.php:

public function rules(): array
    {
        return [
            'commodity' => 'required',
            'variety' => 'required',
            'volume' => 'required',
            'startDate' => 'required|date',
            'endDate' => 'required|date',
        ];
    }

    public function messages()
    {
        return [
            'commodity' => 'Please select a commodity.',
            'variety' => 'Please enter the variety.',
            'volume' => 'Please enter the volume.',
            'startDate' => 'Please select the start date.',
            'endDate' => 'Please select the end date.',
        ];
    }

ELinkageController.php

public function store(StoreELinkageRequest $request)
    {
        $user = $request->user();

        foreach ($request->input('associationName') as $key => $associationName) {
            $data = [
                'association' => $associationName,
                'commodity' => $request->input('commodity')[$key],
                'variety' => $request->input('variety')[$key],
                'volume' => $request->input('volume')[$key],
                'startDate' => $request->input('startDate')[$key],
                'endDate' => $request->input('endDate')[$key],
                'userId' => $user->id,
            ];
            ELinkage::create($data);
        }
        return redirect()->route('e-linkage')->with('success', 'Data saved successfully!');
    }

I tried removing the commodity dropdown to see if it will work for the other inputs but the error message is still not showing. It only shows an error for the dropdown.

1

There are 1 answers

3
MrK On

I recommend that you create an entire entry on say, items for each row you want to represent, this will make it easier - and group the data in the request that is sent.

Each form element's name should have a prefix of items[], for example:

<input name="items[][commodity]"/>
<input name="items[][variety]"/>
<input name="items[][volume]"/>
<!-- ... and the rest --!>

In your controller, you then simply do:

foreach($request->input('items') as $item){
   ELinkage::create([
       'userId' => $user->id,
       ...Arr::only($item, ['commodity', 'variety', 'volume', /**Add the rest here...**/]),
   ];
}

For your rules (this is the important part, Laravel validates using field.*.key to scope it onto a wildcard(*) of array elements with its children columns.:

return [
   'items.*.commodity' => 'required',
   'items.*.variety' => 'required',
   'items.*.volume' => 'required',
   //...
];