Reputation: 1402
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
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
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