david camry david camry - 6 months ago 9
jQuery Question

handle click event to remove the specific tr in table

I don't know why click event doesn't work though it works itself in

fiddle
.
I have a modal that contains categories which are have their childrens .
I get json array and convert it to php array.
I wrote functions. one of them implements to select/deselect childrens . e.g. if you select/deselect the parent category, it's children will be selected/deselected and also shown in the table below. but the problem is when users click on the
class="fa fa-times"
it doesn't remove the specific tr of the table.
I emphasize once again that all things go well except the last script.
what's wrong with it?

<div class="modal fade" id="permissionDlg" role="dialog">
<div class="modal-dialog">

<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Please click on each category/subcategory to expand it.</h4>
</div>
<div class="modal-body">
<div class="row">
<form method="post" action="index.php" class="form-horizontal">

<div class="form-group" style="margin-left: 10px;">
<input type="submit" class="btn btn-primary" value="Assign Permission" />
</div>
<div >
<div class=" tree">
<ul>
<input type="checkbox" name="category[]" value="set here from the php array">
<input type="checkbox" name="category[]" value="set here from the php array">
</form>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<td>Main Category</td>
<td>1 level </td>
<td>2 level </td>
<td>3 level </td>
<td>Delete </td>
</tr>
</thead>
<tbody id="tbl_permission">

</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){

/*this handles the tree view model*/

$('.tree li.parent_li > span').parent('li.parent_li').find(' > ul > li').hide();

$(function () {
$('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch');
$('.tree li.parent_li > span').on('click', function (e) {
var children = $(this).parent('li.parent_li').find(' > ul > li');
if (children.is(":visible")) {
children.hide('fast');
$(this).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign');
} else {
children.show('fast');
$(this).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign');
}
e.stopPropagation();
});
});
/* this hanlde easy-mode selecting category*/
$('input[type="checkbox"]').change(function(){
if($(this).is(':checked')){
var check=false;
var mainVal=$(this).val();
var tmp=mainVal.split('+');
var mainLen=tmp.length;
var $tr = $('<tr />').attr('data-val', mainVal);
if(typeof(tmp[1])==='undefined')
tmp[1]='***';

if(typeof(tmp[3])==='undefined')
tmp[3]='***';

if(typeof(tmp[5])==='undefined')
tmp[5]='***';

if(typeof(tmp[7])==='undefined')
tmp[7]='***';

var $td = $('<td>'+tmp[1]+'</td>'+'<td>'+tmp[3]+'</td>'+'<td>'+tmp[5]+'</td>'+'<td>'+tmp[7]+'</td><td><i class="fa fa-times" aria-hidden="true"></i></td>');
$tr.append($td);
$('#tbl_permission').append($tr);


$('input:checkbox').each(function(){
var val=$(this).val();
var tmpVal=val.split('+');
for(var i=0;i<mainLen;i++){
if(tmpVal.length>mainLen && $.inArray(tmp[i], tmpVal)>-1){
check=true;
}else{
check=false;
break;
}

}
if(check==true){
$(this).prop('checked',true);
var $tr = $('<tr />').attr('data-val', val);
if(typeof(tmpVal[1])==='undefined')
tmpVal[1]='***';

if(typeof(tmpVal[3])==='undefined')
tmpVal[3]='***';

if(typeof(tmpVal[5])==='undefined')
tmpVal[5]='***';

if(typeof(tmpVal[7])==='undefined')
tmpVal[7]='***';

var $td = $('<td>'+tmpVal[1]+'</td>'+'<td>'+tmpVal[3]+'</td>'+'<td>'+tmpVal[5]+'</td>'+'<td>'+tmpVal[7]+'</td><td><i class="fa fa-times" aria-hidden="true"></i></td>');
$tr.append($td);
$('#tbl_permission').append($tr);
}

});

}else{
var check=false;
var mainVal=$(this).val();
var tmp=mainVal.split('+');
var mainLen=tmp.length;
$('#tbl_permission').find("[data-val='"+ mainVal +"']").remove();

$('input:checkbox').each(function(){
var val=$(this).val();
var tmpVal=val.split('+');
for(var i=0;i<mainLen;i++){
if(tmpVal.length>mainLen && $.inArray(tmp[i], tmpVal)>-1){
check=true;
}else{
check=false;
break;
}

}
if(check==true){
$(this).prop('checked',false);
$('#tbl_permission').find("[data-val='"+ val +"']").remove();
}

});
}
});
$(document).ready(function(){
$('.fa.fa-times').click(function(){
$(this).closest('tr').remove();
});
});




</script>

Answer

I emphasize once again that all things go well except the last script. what's wrong with it?

This is because the elements come later into the DOM (dynamic elements) and they do not exist on document ready event where you try to bind events to fa fa-times. That's why the event is not even applied on those elements and hence it doesn't work.

Solution: Use event delegation

        $('table').on('click','.fa.fa-times',function(){
            $(this).closest('tr').remove(); 
        });
Comments