Я делаю приложение Laravel 8 с сообщения и категории постов. Сейчас я работаю над формой Редактировать пост, и мне нужно предварительно заполнить ее текущими данными сообщения.
Столбец id
в таблице catergories
является внешним ключом category_id
в таблице posts
.
В Модель постов у меня есть:
class Posts extends Model {
use HasFactory;
protected $fillable = [
'title',
'category_id',
'description',
'body'
];
}
Маршрут Route::get('/dashboard/posts/edit/{id}', [PostsController::class, 'editPost'])
.
Метод editPost
в контроллере:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Posts;
class PostsController extends Controller {
// More code
public function editPost($id) {
$post = Posts::select (
"posts.id",
"posts.title",
"posts.description",
"posts.body",
"catergories.name as category_name"
)
->leftJoin("catergories", "posts.category_id", " = ", "catergories.id")
->where('posts.id', $id)
->first();
echo $post->title . '<br>';
echo $post->category_name . '<br>';
}
}
В виде:
<input type = "hidden" id = "post_id" value = "">
<div class = "form-group mb-2 @error('title') has-error @enderror">
<label for = "title" class = "text-muted">Title</label>
<input id = "title" type = "text" name = "title" placeholder = "Title" value = "{{ old('title', $post->title) }}" class = "form-control @error('title') is-invalid @enderror" autofocus>
@error('title')<span class = "error-msg">{{ $message }}</span>@enderror
</div>
<div class = "form-group mb-2 @error('category_id') has-error @enderror">
<label for = "category" class = "text-muted">Category</label>
<select name = "category_id" id = "category" class = "form-control @error('category_id') is-invalid @enderror">
<option value = "0">Select a category</option>
@foreach($categorys as $category)
<option value = "{{ $category->id }}" {{ $category->id == $post->category_id ? 'selected' : '' }}>
{{ $category->name }}
</option>
@endforeach
</select>
</div>
Форма помещена в модальное окно Bootstrap 5, а это значит, что я не могу получить доступ к https://myapp.test/dashboard/posts/edit/1
для получения необходимых данных. Я должен сделать это через AJAX.
Для этого у меня есть следующая функция JavaScript
function populateEditForm(event, entity) {
var id = event.currentTarget.dataset.id;
var url = `/dashboard/${entity}/edit/${id}`;
console.info(url);
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
console.info(xmlhttp.responseURL);
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
который я вызываю в шаблоне Blade:
<a onclick = "populateEditForm(event, 'posts')" href = "#" data-id = "{{ $post->id }}" title = "Edit post" data-bs-toggle = "modal" data-bs-target = "#edit_post_modal">
<i class = "fa fa-edit"></i>
</a>
В консоли правильно отображается путь к методу редактирования в контроллере: https://myapp.test/dashboard/posts/edit/1
(для поста с id равным 1), но я не знаю, как этим воспользоваться, чтобы получить нужные данные ( $post->title
, $post->category_name
и т.д.) и пройти это к форме.
Вам нужно вернуть ответ в формате JSON и повторно заполнить форму.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Posts;
class PostsController extends Controller {
// More code
public function editPost($id) {
$post = Posts::select (
"posts.id",
"posts.title",
"posts.description",
"posts.body",
"catergories.name as category_name"
)
->leftJoin("catergories", "posts.category_id", " = ", "catergories.id")
->where('posts.id', $id)
->first();
return response()->json(['post' => $post]);
}
}
В вашем JavaScript
function populateEditForm(event, entity) {
var id = event.currentTarget.dataset.id;
var url = `/dashboard/${entity}/edit/${id}`;
console.info(url);
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
console.info(xmlhttp.response);
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
Вам нужно изменить значение каждого ввода с желаемыми данными, например, document.querySelector("#name").value = 'John Doe'. Это обновит значение этого ввода по его идентификатору, предполагая, что элемент с идентификатором имени является вход.
В вашем случае ваш ответ есть, вам просто нужно выяснить, что куда поставить. Вы также можете использовать xmlhttp.responseText вместо xmlhttp.response, проверьте этот developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…
Как насчет формы, как заполнить ее данными?