Sending arrays to Blade component (Laravel 8)

Viewed 3652

I am attempting to create a x-select component where I can pass an array of options as one of the attributes.

Here is create.blade.php:

<?php $list = ['Received', 'In Process', 'Repaired', 'Completed', 'Shipped', 'Waiting on Boards', 'In Route'];?>
<x-select id="progress" class="block mt-1 w-full" name="progress" :value="old('progress')" :list="$list" />

Here is the component select.blade.php

@props(['disabled' => false])

<select {{ $disabled ? 'disabled' : '' }} {!! $attributes->merge(['class' => 'rounded-md shadow-sm border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50']) !!}>
    @foreach ($list as $item)
        <option @if($item == $value) selected @endif>{{ $item }}</option>
    @endforeach
</select>

The problem is that it's attempting to parse/print the :list when it runs the $attributes->merge(). This doesn't seem like it should be the case, as according to the Laravel 8 Blade docs it appears you can add an :attribute that doesn't get printed when running $attributes->merge(). See: https://laravel.com/docs/8.x/blade#default-merged-attributes

If I change the value of :list to a normal string it will print the string when running $attributes->merge() which is contrary to those docs and makes it so that I cannot pass an array because it attempts to trim the array and fails with this error:

trim() expects parameter 1 to be string, array given
2 Answers

You can stringify the array first using json_encode:

<?php $list = json_encode(['Received', 'In Process', 'Repaired', 'Completed', 'Shipped', 'Waiting on Boards', 'In Route']); ?>

Then you can turn it back into array using json_decode:

@foreach(json_decode($list, true) as $item)
{{-- your code here --}}
@endforeach

Hello everyone, First read this. I created little bit tricky logic, here you can pass nested array to laravel8 component.

This is dynamic radio buttons where you update $data array and component will create radio input according to array, you can create more then 1 to many inputs.

Create nested array in controller and pass to view so it render dynamic component.

$data = [
        'type' => 'radio',
        'lagend' => 'some bold headline',
        'name' => 'gender',
        'title' => 'Gender',
        'class' => '',
        'id' => '',
        'horizontal' => false,
        'radio' =>[
            [
                'id' => 'td1',
                'label' => 'male',
                'checked' => true,
            ],
            [
                'id' => 'td2',
                'label' => 'male',
                'checked' => false,
            ],
            [
                'id' => 'td3',
                'label' => 'other',
                'checked' => false,
            ]
         ]
         ];
    
        //  return $data['radio'];

    return view('test.inputs', ['radio'=>$data]);

Now Create Component Radioinput.

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class RadioInput extends Component
{
    /**
     * Create a new component instance.
     *
     * @return void
     */

    public $title;
    public $lagend;
    public $name;
    public $class;
    public $id;
    public $horizontal;
    public $radios;


    public function __construct($title, $lagend, $name, $class, $id, $horizontal, $radios)
    {
        //
        $this->title = $title;
        $this->lagend = $lagend;
        $this->class = $class;
        $this->id = $id;
        $this->name = $name;
        $this->horizontal = $horizontal;
        $this->radios = $radios;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.radio-input');
    }
}

Now go to App\Http\view\components RadioInput and update like this.

<div>
    <!-- Simplicity is the ultimate sophistication. - Leonardo da Vinci -->
    @if ($lagend)
        <legend>{{$lagend}}</legend>
    @endif

    <div class="form-group">
        <label class="d-block">{{$title}}</label>
        
        @foreach ($radios as $key=> $item)
            <div class="custom-control {!! $horizontal ? 'custom-control-inline' : '' !!} custom-radio" >
                <input  type="radio" class="custom-control-input {{ $class }}" {!! $item['checked'] ? 'Checked' : '' !!}  name="{{$name}}" id="{!! $name.'-'.$key !!}"> 
                <label class="custom-control-label"  for="{!! $name.'-'.$key !!}">{{$item['label']}}</label>
            </div>
        @endforeach
    </div>
</div>

Now Call x-radio-input in you view.

<x-radio-input title="Titel" lagend="" class="" id="" horizontal="true" :name="'gender'" :radios="$radio['radio']"/>

Resutl

enter image description here

Related