How do I add 'Select All' feature in a multi select | Laravel | Voyager - v1.6.0

331 Views Asked by At

Started learing Laravel and Voyager, I have a 'users' table wita a 'belongs to many' relationship with 'department' table. When creating a user, there is multi-select dropdown that save which departments the user belongs to. Voyager automatically handles the add and edit using its default formfileds. I wanted to add a button that selects all the options in the multi select on the user creation form.

And thats where i am Stuck, How do I do that.

Users Creation Form

                                    <label for="department">{{ __('Department') }}</label>
                                    @php
                                        
                                        $row = $dataTypeRows->where('field', 'user_belongsto_department_relationship')->first();
                                        $options = $row->details;
                                    @endphp
                                    @include('voyager::formfields.relationship')
                                </div>

FormField that handles the Multi Select in Voyager:

@elseif($options->type == 'belongsToMany')
            @if (isset($view) && ($view == 'browse' || $view == 'read'))

                @php
                    $relationshipData = isset($data) ? $data : $dataTypeContent;
                    
                    $selected_values = isset($relationshipData)
                        ? $relationshipData
                            ->belongsToMany($options->model, $options->pivot_table, $options->foreign_pivot_key ?? null, $options->related_pivot_key ?? null, $options->parent_key ?? null, $options->key)
                            ->get()
                            ->map(function ($item, $key) use ($options) {
                                return $item->{$options->label};
                            })
                            ->all()
                        : [];
                @endphp

                @if ($view == 'browse')
                    @php
                        $string_values = implode(', ', $selected_values);
                        if (mb_strlen($string_values) > 25) {
                            $string_values = mb_substr($string_values, 0, 25) . '...';
                        }
                    @endphp
                    @if (empty($selected_values))
                        <p>{{ __('voyager::generic.no_results') }}</p>
                    @else
                        <p>{{ $string_values }}</p>
                    @endif
                @else
                    @if (empty($selected_values))
                        <p>{{ __('voyager::generic.no_results') }}</p>
                    @else
                        <ul>
                            @foreach ($selected_values as $selected_value)
                                <li>{{ $selected_value }}</li>
                            @endforeach
                        </ul>
                    @endif
                @endif
            @else 
                <select id={{ $relationshipField }}
                    class="form-control select2-ajax @if (isset($options->taggable) && $options->taggable === 'on') taggable @endif"
                    name="{{ $relationshipField }}[]" multiple
                    data-get-items-route="{{ route('voyager.' . $dataType->slug . '.relation') }}"
                    data-get-items-field="{{ $row->field }}"
                    @if (!is_null($dataTypeContent->getKey()))
                        data-id="{{ $dataTypeContent->getKey() }}"
                    @endif
                    data-method="{{ !is_null($dataTypeContent->getKey()) ? 'edit' : 'add' }}"
                    @if (isset($options->taggable) && $options->taggable === 'on') data-route="{{ route('voyager.' . \Illuminate\Support\Str::slug($options->table) . '.store') }}"
                        data-label="{{ $options->label }}"
                        data-error-message="{{ __('voyager::bread.error_tagging') }}" @endif
                    @if ($row->required == 1) required @endif>

                    @php
                        $selected_keys = [];
                        
                        if (!is_null($dataTypeContent->getKey())) {
                            $selected_keys = $dataTypeContent->belongsToMany($options->model, $options->pivot_table, $options->foreign_pivot_key ?? null, $options->related_pivot_key ?? null, $options->parent_key ?? null, $options->key)->pluck($options->table . '.' . $options->key);
                        }
                        $selected_keys = old($relationshipField, $selected_keys);
                        $selected_values = app($options->model)
                            ->whereIn($options->key, $selected_keys)
                            ->pluck($options->label, $options->key);
                    @endphp

                    @if (!$row->required)
                        <option value="">{{ __('voyager::generic.none') }}</option>
                    @endif

                    @foreach ($selected_values as $key => $value)
                        <option value="{{ $key }}" selected="selected">"{{ $value }}"</option>
                    @endforeach

                </select>

            @endif

        @endif
1

There are 1 best solutions below

2
Ahmed Essam On

if you need to select more options because user belong to many departments you can do like this

    function selectAllOptions(){
        document.querySelectorAll('#departments option').forEach(option =>{
            option.selected = true
        })
    }
  <label for="departments">Choose a department:</label>
  <select name="departments" id="departments" multiple>
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    <option value="d">d</option>
  </select>

 <button onclick="selectAllOptions()">select all</button>

in your case, you will do this like saw

FormField that handles the Multi Select in Voyager:
  
<select name="departments" id="departments" multiple>
@foreach
<option value="{{$key}}">{{$value}}</option>
@endforeach
</select>
<button onclick="selectAllOptions()">select all</button>

<script>
function selectAllOptions(){
document.querySelectorAll('#departments option').forEach(option =>{
    option.selected= true
})
}
</script>

and you can make same function in different ways like using jquery I hope to understand your question right :)