omrakhur
omrakhur

Reputation: 1402

Laravel 5 - Modal cannot retrieve values of datatable row

I am making a CRUD to-do list. Clicking on Edit launches a modal. Once I edit and submit something within the modal, everything updates correctly, i.e. the update() method works fine. However, as $task stores the value of the last item in the array, it always shows the value of that item no matter which row's edit button I click on.

The to-do table:

<div id="tasks-chart">
            <table id="datatable-table" class="table table-striped table-hover">
                <thead>
                <tr>
                    <th>Task</th>
                    <th style="width: 40%">Description</th>
                    <th>Status</th>
                    <th>Actions</th>
                </tr>
                </thead>
                <tbody>
                @foreach($tasks as $task)
                    <tr id="task{{$task->id}}">
                        <td>{{$task->task}}</td>
                        <td style="width: 40%">{{$task->description}}</td>
                        <td>@if($task->done) Completed @else Incomplete @endif</td>
                        <td>
                            <button class="btn btn-warning btn-sm btn-detail open-modal" value="{{$task->id}}"
                                    data-toggle="modal"
                                    data-target="#myModal2"
                                    data-backdrop="static"
                                    data-task ="{{$task->task}}"
                                    data-description ="{{$task->description}}"
                                    data-done ="{{ $task->iscomplete }}">Edit</button>
                            <button class="btn btn-danger btn-sm btn-delete delete-task" value="{{$task->id}}">Delete</button>
                        </td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>

The Modal that is launched once the Edit button is clicked is also very simple:

<div id="myModal2" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">×</button>
                        <h4 class="modal-title" id="myModalLabel2">Edit Task</h4>
                    </div>
                    <div class="modal-body">
                        {{ Form::model($task, ['method' => 'PATCH', 'route' => ['tasks.update', $task->id], 'role' => 'form']) }}
                        <fieldset>
                            <label for="edit-name" class="control-label col-sm-4">Task</label>
                            <div class="col-md-8">
                                {{Form::text('task',null,['id'=>'edit-name','class'=>'form-control col-sm-8','required'=>'required'])}}
                                <p class="error text-center alert alert-danger hidden"></p>
                            </div>
                        <br><br>
                            <label for="edit-description" class="control-label col-sm-4">Description</label>
                            <div class="col-sm-8">
                                {{Form::textarea('description',null,['id'=>'edit-description','class'=>'form-control','rows'=>'5','cols'=>'45'])}}
                            </div>
                        <br><br>
                            <label for="edit-status" class="control-label col-sm-4">Status</label>
                            <div id="edit-status" class="col-sm-8">
                                {{Form::select('done', ['0'=>'Incomplete','1'=>'Completed'],null,
                                ['id'=>'edit-status','class'=>'selectpicker', 'data-style'=>'btn-success', 'data-width'=>'auto'])}}
                            </div>
                        </fieldset>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        {{ Form::submit('Submit', ['class' => 'btn btn-success']) }}
                    </div>
                    {{ Form::close() }}
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div>

routes.php:

Route::resource('tasks','TaskController');

There's only one method implemented in Controller:

 public function update(Request $request, $id)
{
    $user = Auth::user();


    // validation of the request
    $rules = array(

        'task' => 'required|string',
        'description'=>'string'

    );
    $validator = Validator::make(Input::all(), $rules);

    // return to the creation page if the request is invalid
    if ($validator->fails()) {
        return Redirect::to('/')
            ->withErrors($validator)
            ->withInput();
    }
    else{
        $task                = Task::findOrFail($id);

        $task->task          = Input::get('task');
        if(Input::get('description'))
        {
            $task->description = Input::get('description');
        }
        $task->done          = Input::get('done');
        $task->save();

        \Session::flash('flash_message','Task succesfully updated!');
        // redirect
        return redirect('/');
    }
}

The JQuery I use to populate the modal's fields using the data- attributes on my button is

$('button.open-modal').on('click', function (e) {
// Make sure the click of the button doesn't perform any action
e.preventDefault();

// Get the modal by ID
var modal = $('#myModal2');

// Set the value of the input fields
modal.find('#edit-name').val($(this).data('task'));
modal.find('#edit-description').val($(this).data('description'));
modal.find('#edit-status').val($(this).data('done'));

// Update the action of the form
modal.find('form').attr('action', 'tasks/update/' + $(this).val());

});

But it still shows the task ID, Task Description etc. for the last created task no matter which row's button I click on. How do I fix this?

Upvotes: 0

Views: 971

Answers (2)

R.K.Saini
R.K.Saini

Reputation: 2708

Your code looks fine ! May be you try to add jquery event on your target button before the button added to DOM. So you need to write your code inside $(document).ready(function (){}); block.

Try like this:

$(document).ready(function () {
    $('button.open-modal').on('click', function (e) {
        // Make sure the click of the button doesn't perform any action
        e.preventDefault();

        // Get the modal by ID
        var modal = $('#myModal2');

        // Set the value of the input fields
        modal.find('#edit-name').val($(this).data('task'));
        modal.find('#edit-description').val($(this).data('description'));
        modal.find('#edit-status').val($(this).data('done'));

        // Update the action of the form
        modal.find('form').attr('action', 'tasks/update/' + $(this).val());

    });
});

Upvotes: 2

madalinivascu
madalinivascu

Reputation: 32354

Append the values when the modal is shown, get the values relative to the clicked button

$('#myModal2').on('show.bs.modal', function (e) { 
 //get the button
 var el = $(e.relatedTarget);
 var modal = $(this);

// Set the value of the input fields
modal.find('#edit-name').val(el.data('task'));
modal.find('#edit-description').val(el.data('description'));
modal.find('#edit-status').val(el.data('done'));

// Update the action of the form
modal.find('form').attr('action', 'tasks/update/' + el.val());

Upvotes: 2

Related Questions