Noob Coder Noob Coder - 3 months ago 9
Javascript Question

Laravel simple crud with jquery ajax

I am trying to delete a row from a table using jquery ajax. After couple of trying I cant figure out why my code (deleting part) is not working as I am new with ajax and javascript. Loading data with ajax from server works fine and the script has no console error. When I press delete, I see nothing on network tab. Here is my code:

routes.php

Route::delete('users/{id}','AjaxController@destroy');


AjaxController.php

public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
}


view:

<table id="users" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody id="abc">

</tbody>
</table>


script:

$(document).ready(function(){
var $tbody = $('#abc');

// getting data from server
$.ajax({
type : 'GET',
url : 'api/users',
success: function(users) {
$.each(users, function(i, user){
$tbody.append('<tr id="user_' + user.id + '"><td>'+user.name+'</td><td>'+user.phone+'</td><td><button type="button" class="btn btn-xs btn-danger" id="delete" value="'+user.id+'" name="button">Delete</button></td></tr>');
});
},
error: function(){
alert('error loading data');
}
});

// deleting data
$('#delete').on('click', function(e){
var user_id = $(this).val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
})
e.preventDefault();
var user = {
id : user_id
};
$.ajax({
type: 'DELETE',
url : '/user/'+user.id,
success : function(deleteUser)
{
$("#user_" + user_id).remove();
},
error : function()
{
alert('error deleting data');
}
});
}); // deleting block ends
});
});

Answer

The problem here is that you're using the same id over and over. However this issue is further compounded by the fact that you are dynamically inserting the content, but your event binding is only observing elements available at page load. Let's fix all of this. First, we need to do-away with the ID.

class="btn btn-xs btn-danger" id="delete" value="'+user.id+'"

Needs to be changed to

class="btn btn-xs btn-danger btn-delete" value="'+user.id+'"

Great. We've used btn-delete. This isn't specific to this particular user functionality. The way that CRUD works, you should be able to re-use this code for every single Model that you interact with through the CRUD Controller.

Now we need to delegate our event binding, and we'll also make the button more generic as discussed in the previous paragraph. For the sake of post length, I'll only show what you -should- have your javascript set up like.

$('table').on('click', '.btn-delete', function(e){
    e.preventDefault();

    var $btn = $(this),
        $table = $btn.closest('table');

    $.ajax({
        url: $table.data('resource') . '/' . $btn.val(),
        type: 'delete' 
    }).done(function(response){
        console.log(response);
    }).error(function(x,t,m){
        console.warn(x,t,m);
    });
});

The token can be moved to the top of the file, it does not need to be nested:

$.ajaxSetup({
     headers: {
         'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
     }
});

Finally, we need to attach our data-resource property to our table:

<table ... data-resource="users"

Now you've got a reusable model and only need to attach a data-resource="model" property to your table, and a button with a class of btn-delete a value with the id of the entity.

Comments