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

Time:03-18

I am making a Laravel 8 app with posts and post categories. I am now working on the Edit post form, and I need to prepopulate it with the post's current data.

The id column in the catergories table is the category_id foreign key in the posts table.

In the Posts model I have:

class Posts extends Model {
   use HasFactory;
    
    protected $fillable = [
        'title',
        'category_id',
        'description',
        'body'
    ];
}

The route is Route::get('/dashboard/posts/edit/{id}', [PostsController::class, 'editPost']).

The editPost method in the controller:

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>';
    }
}

In the form:

<input type="hidden" id="post_id" value="">

<div > 
        <label for="title" >Title</label>       
        <input id="title" type="text" name="title" placeholder="Title" value="{{ old('title', $post->title) }}"  autofocus>

        @error('title')<span >{{ $message }}</span>@enderror
    </div>

    <div >
        <label for="category" >Category</label>
        <select name="category_id" id="category" >
            <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>

The goal

The form is placed in a Bootstrap 5 modal, which means that I can not access https://myapp.test/dashboard/posts/edit/1 to get the necessary data. I have to do this via AJAX.

For this purpose, I have the following JavaScript function

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();
}

that I call in a Blade template:

<a onclick="populateEditForm(event, 'posts')" href="#" data-id="{{ $post->id }}" title="Edit post" data-bs-toggle="modal" data-bs-target="#edit_post_modal">
        <i ></i>
</a>

The problem

The console corectly displays the path to the edit method in the controller: https://myapp.test/dashboard/posts/edit/1 (for the post with id equal to 1), but I don't know how to use this to get the necessary data ( $post->title, $post->category_name, etc) and pass it to the form.

What is missing?

CodePudding user response:

You need to return the response as JSON and repopulate the form.

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]);
    }
}

In your 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();
}
  • Related