laravel-livewire

Trying to access an array in a component


Good evening, I just wanted to convert my Project "Winecellar" to livewire 3.

I use the bootstrapDualListbox and it works fine. Bevor using Livewire i sent a form via POST and could access the array "grape_flavour" by

foreach ($request->input('grape_flavour') as $key => $value) {   
              /*$result=FlavourGrape::FirstorCreate(
                
                ['flavour_id' => $value,'grape_id'=>$grape_value],
                ['grape_id' => $grape_value,'flavour_id'=>$value],
              );  */
            $grape->flavours()->attach($value);
       
         }; 

Now that I changed to Livewire the array is not accessible.

The blade filde:

<div class="container">
    <div class="row">
        <div class="col-12">
            <div class="row">
                <div class="col text-center border border-info mb-3">

                    @foreach($this->grapes as $grape)
                    <label class="h1">Grapename : {{$grape->grapename}}</label>
                    @endforeach

                    @php
                    $result_flavour_exist = App\Models\Flavour::flavour_exist($grape->id)->get();
                    $result_flavour = App\Models\Flavour::all_flavour($grape->id)->get();
                    (session(['grape_id' => $grape->id]))
                    @endphp

                    <div class="border border-info">
                        <form id="demoform" wire:submit.prevent="save">

                            <select multiple="multiple" size="10" name="grape_flavour[]" title="grape_flavour[]">
                                @foreach ($result_flavour as $var)
                                <option value="{{ $var->id }}" selected="selected"> {{ $var->flavourname }} </option>
                                @endforeach

                                @foreach ($result_flavour_exist as $var)
                                <option value="{{ $var->id }}">{{ $var->flavourname }}</option>
                                @endforeach

                            </select>
                            <br>
                            <div class="mb-3">
                                <button type="submit" class="btn btn-success btn-block">Save Flavours</button>
                                <a href="/grapes">
                                    <button class="btn btn-secondary" type="button">
                                        Back to Grapes
                                    </button>
                                </a>
                            </div>
                        </form>
                    </div>

                    @script
                    <script>
                        $("document").ready(function(){
                        var demo1 = $('select[name="grape_flavour[]"]').bootstrapDualListbox();
                        })
                    </script>
                    @endscript

                </div>
            </div>
        </div>
    </div>
</div>

The Component where I want to access the array in the save procedure :

<?php

namespace App\Livewire\BasedataGrapes\Flavourgrapes;

use Livewire\Component;
use App\Models\Grape;
use App\Models\FlavourGrape;

class Flavourgrapeedit extends Component
{

    public $grapes;

    public $grape_flavour = [];
    public function mount($grape_id)
    {
        $this->grapes = Grape::where('id', '=', $grape_id)->get();
    }

    public function render()
    {
        return view('livewire.basedata-grapes.flavourgrapes.flavourgrapeedit');
    }

    public function save()
    {
        if (session()->has('grape_id')) {
            $grape_value = session('grape_id');
            $grape = Grape::find($grape_value);
            $grape->flavours()->detach();

            //foreach $grape_flavour[] as $key => $value {
            //$grape->flavours()->attach($value);
            //};


            session()->forget('grape_id');
            return redirect()->route('grapes')->with('success', 'Flavours have been created succesfully !');
        } else {
            return redirect()->route('grapes')->with('fail', 'Flavours could not be created, no Grape selected !');
        }
    }
}

Any suggestions ?

Best regards, Stephan


Solution

  • You must let bootstrapDualListbox manage the listbox and livewire ignore it.
    Then using a change event you can assign to the $wire object the selected values, on the frontend side:

    <div wire:ignore> <!-- ADD A wire:ignore -->
    
        <select multiple="multiple"
                size="10"
                name="grape_flavour[]"
                title="grape_flavour[]"
        >
            ....
        </select>
    
    </div>
    
    @script
    
    <script>
    
        $("document").ready(function(){
    
            var demo1 = $("select[name=\"grape_flavour[]\"]");
    
            demo1.bootstrapDualListbox();
    
            demo1.on("change", (e) => {
                $wire.grape_flavour = $(e.target).val();  // assigns the selected values
            });
        })
    
    </script>
    
    @endscript
    

    In this way the $grape_flavour property on the backend side will be filled with the selected ids of the bootstrapDualListbox