Friday, January 28, 2022

[FIXED] Form only edits the first Id in Laravel in submit

Issue

I was making a todo application using Laravel 8. Below is my blade template for editing data.

   <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                <thead>
                    <tr>
                        <th class="text-center">#</th>
                        <th style="display: none;"></th>
                        <th class="text-center">Tasks</th>
                        <th class="text-center">Action</th>

                    </tr>
                </thead>
                <tbody>
                    @php
                        $i = 1;
                    @endphp 
                     @foreach ($tasks as $task)
                        <tr>
                            <td class="text-center">{{ $i }}</td>
                            <td style="display: none;">{{ $task->taskId }}</td>
                            <td class="text-center">{{ $task->taskName }}</td>
                            <td>
                                <div class="row">
                                    <div class="col-md-3">
                                        <form method="POST">
                                            <input type="hidden" name="taskId" value="{{ $task->taskId }}">
                                            <button class="btn btn-primary" type="submit" name="deleteTask">Delete</button>
                                        </form>
                                    </div>
                                    <div class="col-md-3">
                                        <form method="POST">
                                            <input type="hidden" name="taskId" value="{{ $task->taskId }}">
                                            <button class="btn btn-primary editTaskButton" type="button" name="editTask" data-toggle="modal" data-target="#editTask">Edit</button>
                                        </form>
                                        <div class="modal fade" id="editTask" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
                                            <div class="modal-dialog" role="document">
                                                <div class="modal-content">
                                                    <div class="modal-header">
                                                        <h5 class="modal-title" id="editTask">Edit Tasks</h5>
                                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                                            <span aria-hidden="true">&times;</span>
                                                        </button>
                                                    </div>
                                                    <div class="modal-body">
                                                        <div class="card ">
                                                            <div class="card-body">
                                                                <form method="POST" action="/tasks/{{ $task->taskId }}">
                                                                    @csrf
                                                                    @method('PUT')
                                                                    <input type="hidden" name="taskId" id="taskId" value="{{ $task->taskId }}">
                                                                    <div class="form-group">
                                                                        <label>Enter Task</label>
                                                                        <input type="text" class="form-control" id="taskName" name="taskName">
                                                                    </div>
                                                                    <button type="submit" class="btn btn-primary" name="updateTask">Update Task</button>
                                                                </form>
                                                            </div>
                                                        </div>
                                                    </div>
                                                    <div class="modal-footer">
                                                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    @php $i++; @endphp 
                    @endforeach
                </tbody>
            </table>

The blade template is basically a datatable that is using modal for editing the data. When I click the edit button the edit form appears and bring that data which is to be edited. But once I press update button the data of only first row gets updated. Below is my script for retrieving data

<script>
$(document).ready(function() {
    $('.editTaskButton').on('click', function() {
        $('#editTask').modal('show');
        $tr = $(this).closest('tr');

        var data = $tr.children("td").map(function() {
            return $(this).text();
        }).get();
        $('#taskId').val(data[1]);
        $('#taskName').val(data[2]);
    });
});
The script is fetching the data correctly but is updating only first record of table. I am using resource controller and router. Below are the codes for controller and route
 public function update(Request $request, $id)
{

    $tasks = Task::where('taskId',$id)
            ->update([
                'taskName'=>$request->input('taskName')
    ]);
   
    
    return redirect('/tasks');
}

Route:

Route::resource('/tasks', TasksController::class);

So I want a bit guidance on where I am making mistake. This whole thing is one page application.


Solution

If I understand the question correctly, You want to mass-edit all the taskName fields in the DOM and then save the changes to the database.

There are several issues with your code but you could try replacing the relevant snippet with this:

<div class="modal-body">
    <div class="card ">
        <div class="card-body">
            <form method="PUT" action="/tasks/update">
                @csrf                                                                    
                <input type="hidden" name="taskId[]" id="taskId-{{$i}}" value="{{ $task->taskId }}">
                <div class="form-group">
                    <label>Enter Task</label>
                    <input type="text" class="form-control" id="taskName" name="taskName[]">
                </div>
                <button type="submit" class="btn btn-primary" name="updateTask">Update Task</button>
            </form>
        </div>
    </div>
</div>

Since you are sending the IDs in a loop, you need to send an array of taskId and TaskName. Right now, you are sending many inputs with the same name and the form receives only the first one. Notice that the id of each element needs to be unique to the DOM. That's why I added the $i variable that you are already using, in the id attribute. Lastly, change the endpoint of the form to a generic /update since you will be iterating through the ids in the controller.

Then in the controller, you will need to receive these arrays and update accordingly:

public function update(Request $request)
{

    $ids[] = $request->taskId;
    $taskNames[] = $request->taskName;
    $i = 0;

    foreach($ids as $id)
    {
        $tasks = Task::where('taskId',$id)
                ->update([
                    'taskName'=>$taskNames[$i]
        ]);
        $i++;
    }   
    
    return redirect('/tasks');
}

Try this and see if it works for you.



Answered By - m33ts4k0z

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.