Home > front end >  Form only edits the first Id in Laravel in submit
Form only edits the first Id in Laravel in submit

Time:10-19

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 hljs-string">" type="submit" name="deleteTask">Delete</button>
                                        </form>
                                    </div>
                                    <div hljs-number">3">
                                        <form method="POST">
                                            <input type="hidden" name="taskId" value="{{ $task->taskId }}">
                                            <button hljs-string">" 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 hljs-string">">
                                                                        <label>Enter Task</label>
                                                                        <input type="text" hljs-string">" id="taskName" name="taskName">
                                                                    </div>
                                                                    <button type="submit" hljs-string">" name="updateTask">Update Task</button>
                                                                </form>
                                                            </div>
                                                        </div>
                                                    </div>
                                                    <div hljs-string">">
                                                        <button type="button" hljs-string">" 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.

CodePudding user response:

The problem here is that your modal is inside the foreach loop, and your javascript code always opens the first modal (out of x modals with same HTML id attribute) which is filled with data from your first $task. This means your form submit URL will always be your first $task->taskId.

Suggested solution: Move your modal outside foreach loop, keep your javascript code, but when opening modal also update your form submit URL (action) via your javascript.

CodePudding user response:

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 hljs-string">">
                    <label>Enter Task</label>
                    <input type="text" hljs-string">" id="taskName" name="taskName[]">
                </div>
                <button type="submit" hljs-string">" 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.

  • Related