'Retain old values and select multiple options in laravel

Current code

<label class="form-label">Update Tags</label>
<select id="tags" name="tags[]" multiple class="form-control">
  @foreach ($tags as $tag)
    <option value="{{ $tag->id }}">{{ $tag->name }}</option>
  @endforeach
</select>
public function edit($aid, $id)
{
    $account = Account::where('id', $aid)->first();

    $friend = LineUser::where('id', $id)->first();

    $tags = Tag::where('account_id', $aid)->get();

    return view('dashboard.friends.edit', [
        'friend' => $friend,
        'account' => $account,
        'tags' => $tags,
    ]);
}
public function update(Request $request, $aid, $id)
{
    $request->validate([
        'name' => 'required',
    ]);

    // change date format
    $DOB = $request->input('dob-year') . "/" . $request->input('dob-month') . "/" . $request->input('dob-day');
    
    // sync updated tags
    $data = [];
    $data['tags'] = $request->input('tags');
    LineUser::find($id)->tags()->sync($data['tags']);

    // update records
    LineUser::where('id', $id)
        ->update([
            'name' => $request->input('name'),
            'birthday' => $DOB,
            'phone' => $request->input('phone'),
            'postcode' => $request->input('postcode'),
            'gender' => $request->input('gender'),
            'email' => $request->input('email'),
        ]);

    // session title
    Session::put('title', 'User updated');

    return redirect('accounts/' . $aid . '/' . 'friends' . '/' . $id . '/' . 'edit')
            ->with('message', 'User has been updated.');

What I want is that the options in the select tag be selected if the value is set in old records.

What I tried There were many answers on SO similar to this and I tried most of the ones I thought might work. Below are methods that did not work.

@if (old('tags')==$tag->id)
    <option value={{$tag->id}} selected>{{ $tag->name }}</option>
@else
    <option value={{$tag->id}} >{{ $tag->name }}</option>
@endif
<option value="{{ $tag->id }}" {{ in_array($tag->id, (array) old('tags', [])) ? "selected" : "" }}>{{ $tag->name }}</option>
{{ (collect(old('tags'))->contains($tag->id)) ? 'selected':'' }}

I think the old() function is not working for some reason but am not sure exactly what is wrong here. I have a tags table and a lineusers table that are connected via a pivot table. I also tried doing this in Javascript but I gave up cause Im not that able in javascript. If someone can help me with this.



Solution 1:[1]

Can we see how your validation works?

One of common reasons why old() function is not working is because you're not using ->withInput() when you are redirecting after validation.

Example validation:

public function saveData(Request $request)
{
    // Validations go here

    if (!isValid()) {
        // If validation fails, using ->withInput(),
        // redirect back to the view with the data you've sent here
        return redirect()->back()->withInput()->withErrors('Error Validation');
    }

    return redirect()->back()->with('message','Successful');
}

Then on your HTML, you can add condition on the option tag

<label class="form-label">Update Tags</label>
<select id="tags" name="tags" multiple class="form-control">
@foreach ($tags as $tag)
    <!-- Add condition here to add attribute like 'selected' -->
    <option value="{{ $tag->id }}" @if($tag->id == old('tags')) selected @endif>{{ $tag->name }}</option>
@endforeach
</select>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rhemmuuu