I am working on a blogging application in Laravel 8.
In the form I use for editing articles, I have a multiple-select element.
I want the form to show the tags that have been selected. For this purpose, I did the following in the view:
<label for="tags" class="col-md-12">{{ __('Tags') }}</label>
@php
$selected = explode(",", $tags);
@endphp
<select name="tags[]" id="tags" class="form-control" multiple="multiple">
@foreach ($tags as $tag)
<option value="{{ $tag->id }}" {{ (in_array($tag->id, $selected)) ? 'selected' : '' }}>{{ $tag->name }}</option>
@endforeach
</select>
In the controller, I have:
public function edit($id)
{
$article = Article::find($id);
return view(
'dashboard/edit-article',
[
'categories' => $this->categories(),
'tags' => $this->tags(),
'article' => $article
]
);
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), $this->rules, $this->messages);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator->errors())->withInput();
}
$fields = $validator->validated();
$article = Article::find($id);
// If a new image is uploaded, set it as the article image
// Otherwise, set the old image...
if (isset($request->image)) {
$imageName = md5(time()) . Auth::user()->id . '.' . $request->image->extension();
$request->image->move(public_path('images/articles'), $imageName);
} else {
$imageName = $article->image;
}
$article->title = $request->get('title');
$article->short_description = $request->get('short_description');
$article->category_id = $request->get('category_id');
$article->featured = $request->has('featured');
$article->image = $request->get('image') == 'default.jpg' ? 'default.jpg' : $imageName;
$article->content = $request->get('content');
// Save changes to the article
$article->save();
//Attach tags to article
if ($request->has('tags')) {
$article->tags()->attach($request->tags);
}
return redirect()->route('dashboard.articles')->with('success', 'The article titled "' . $article->title . '" was updated');
}
For a reason I have not been able to spot, this does not work. That means the article's tags are not selected in the <select>
element.
Where is my mistake?
According to your code, I can deduce that tags variable is a collection of objects. As such, you cannot explode on it like that in your blade file within the php block statement. The php explode function takes in a "seperator" and "string" as arguements according to its documentation here. If your aim is to return the ids of the selected tags, you can pluck the id column on tags collection and return it as an array as shown below. That is of course if "tags" is indeed a collection, otherwise you can make it one.
$selected = $this->tags->pluck('id')->toArray(); // If tags is a collection
But if not a collection,
$tagsCollection = collect($this->tags);
$selected = $tagsCollection->pluck('id')->toArray();
Afterwhich, you can pass it along to the view with the rest of the data in the edit method in your controller. Therefore, you wont have a need for the php block any longer in your blade file and the selected tags should now be visible.