Fire only one button in buttons list using jQuery

Viewed 218

I'm struggling trying to figure out a weird issue. I have a table with several rows, each row has a column with action buttons, the code to draw the buttons group is the following:

<td>
    <div class="button-list">
    <button type="button" class="btn btn-xs btn-info waves-effect waves-light edit-base"><i class="mdi mdi-pencil"></i></button>
    <button type="button" class="btn btn-xs btn-danger waves-effect waves-light remove-base"><i class="mdi mdi-close"></i></button>
    </div>
</td>

If user click on edit buton I want to start a Javascript ( jQuery) function, otherwise I start the remove function. Below the code to get the button click:

$("body").on("click",".button-list",function(e){
    console.log('Clicked action button list');
    var id = $(this).parents('td').data('id');
    console.log('Row data id is ' + id);
    if(id != null) {
        e.preventDefault();
        if($(this).find("button").hasClass("edit-base")) {
            console.log('you want to edit base with id ' + id);
            editBase(id);
        }
        if($(this).find("button").hasClass("remove-base")) {
            console.log('you want to remove base with id ' + id);
            deleteBase(id);
        }
    }
});

The weird issue that I don't understand is that even if I click just one button boths functions are started. Any hint or suggestion to fix the issue? What's wrong with the code above?

I have added some console.log row to check what happens...of course. Thanks a lot

2 Answers

Both conditions are true since you have buttons with each of those classes inside the list element

Change the target selector to the buttons instead and check the class of the current button the event occurs on

$("body").on("click",".button-list .btn",function(e){
                                 // ^^^ add button class in selector
    var $btn = $(this)// button event occurs on
    console.log('Clicked action button');
    var id = $btn.parents('td').data('id');
    console.log('Row data id is ' + id);
    if(id != null) {
        e.preventDefault();
        // check class of current button
        if($btn.hasClass("edit-base")) {
            console.log('you want to edit base with id ' + id);
            editBase(id);
        }else  if($btn.hasClass("remove-base")) {
            console.log('you want to remove base with id ' + id);
            deleteBase(id);
        }
    }
});

Ah, Charlie's answer was faster. I'll post mine anyway since I now have it finished (choose Charlie's as the correct answer instead, please). The only thing to note in my answer is how you can use .closest() instead of .parent() - .closest() goes up the tree as far as necessary until it finds the requested element.

As Charlie noted, the thing you were doing incorrectly was trapping the click on the td instead of trapping the click on one of the buttons.

$("body").on("click",".button-list button",function(e){
    var id = $(this).closest('td').data('id');
    console.log('Row data id is ' + id);
    if(id != null) {
        e.preventDefault();
        if($(this).hasClass("edit-base")) {
            console.log('you want to edit base with id ' + id);
            editBase(id);
        }
        if($(this).hasClass("remove-base")) {
            console.log('you want to remove base with id ' + id);
            deleteBase(id);
        }
    }
});
function editBase(id){
  console.log(`running EDITBASE for ${id}`);
}
function deleteBase(id){
  console.log(`running deletebase for ${id}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table><tr>
<td data-id="bob">
    <div class="button-list">
    <button type="button" class="btn btn-xs btn-info waves-effect waves-light edit-base"><i class="mdi mdi-pencil">Pencil icon</i></button>
    <button type="button" class="btn btn-xs btn-danger waves-effect waves-light remove-base"><i class="mdi mdi-close">Close icon</i></button>
    </div>
</td>
</tr>
</table>

Related