如何通过 AJAX 将数据发送到此 Laravel 表单?

How can I send data to this Laravel form via AJAX?

我正在制作一个 Laravel 8 应用,其中包含 postspost 类别。我现在正在处理 Edit post 表单,我需要用 post 的当前数据预先填充它。

catergoriestable中的id列是poststable中的category_id外键。

帖子模型中我有:

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.log(url);

    var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == XMLHttpRequest.DONE) { 
                if (xmlhttp.status == 200) {
                    console.log(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),但是我不知道如何使用它来获取必要的数据( $post->title$post->category_name 等)并将其传递给表单。

缺少什么?

您需要 return 回复 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.log(url);

    var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == XMLHttpRequest.DONE) { 
                if (xmlhttp.status == 200) {
                    console.log(xmlhttp.response);
                }
            }
    };

    xmlhttp.open("GET", url, true);
    xmlhttp.send();
}