Reputation: 79
I am new to Angular JS and I've set up a basic HTML page with a table of items. I want to be able to delete each item separately, so I added a column containing a delete button for each row of my HTML table. This is what this column looks like.
<td headers="deleteRoleHeader" class="cell-texte">
<span class="glyphicon glyphicon-trash" ng-click="deleteRole();"></span>
</td>
And my Angular JS function:
$scope.deleteRole = function(){
var data = {
codeRole: $scope.code_role,
descRole : $scope.desc_role
};
console.log(data);
};
My problem is each time I click on my delete button, my function gets called once more than the previous time. To clarify: first time I click, function is called once, second time I click, function is called twice, etc.
I would like my function to be called only once when I click on my delete button.
Has anyone faced a similar issue ? I have read a lot of stackoverflow questions about functions being called multiple times but I haven't been able to fix my issue.
Thanks in advance for your help.
EDIT: here's my console output after two clicks
EDIT 2: I figured out what what causing the problem: I had a modal set up, acting as a confirmation and if I remove it my code behaves as it should (only one call is made to the function) Here is a fiddle that reproduces the problem: https://jsfiddle.net/w6edum0f/12/.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.roles = [
{
"codeRole": "test",
"descRole": "test desc"
},
{"codeRole": "test2",
"descRole": "test desc1"
}
];
$scope.selectRole = function(role) {
$scope.code_role = role.codeRole;
$scope.desc_role = role.descRole;
};
$scope.deleteRole = function(){
$('#deleteModal').show();
$('#deleteBtn').click(function(){
$('#deleteModal').hide();
var data = {
codeRole: $scope.code_role,
descRole : $scope.desc_role
};
console.log(data);
});
};
});
Upvotes: 2
Views: 101
Reputation: 48968
first time I click, function is called once, second time I click, function is called twice, etc.
That happens because the code is adding another click handler on each call:
ERRONEOUS
$scope.deleteRole = function(){ $('#deleteModal').show(); $('#deleteBtn').click(function(){ $('#deleteModal').hide(); var data = { codeRole: $scope.code_role, descRole : $scope.desc_role }; console.log(data); }); };
One solution is to remove the click handler once called:
$scope.deleteRole = function(){
$('#deleteModal').show();
$('#deleteBtn').on("click", hideModal);
};
function hideModal(){
$('#deleteModal').hide();
$('#deleteBtn').off("click", hideModal);
var data = {
codeRole: $scope.code_role,
descRole : $scope.desc_role
};
console.log(data);
};
Upvotes: 2
Reputation: 7769
okay, guys, I try to make a small angular app and try to run this same code, so that we will be in same context:
link to jsfiddle https://jsfiddle.net/dupinderdhiman/nd8wm5pg/1/
REASON: Reason is the bubbling, when we click on okay
button from the dialog, which opens after clicking delete
, then bubbling starts, so to handle bubling, i try following trick, you can try another if you want :P
$scope.deleteRole = function(){
$('#deleteModal').show();
var isDeleteBtnClicked = false;
$('#deleteBtn').click(function($event){
if(!isDeleteBtnClicked)
{
$('#deleteModal').hide();
var data = {
codeRole: $scope.code_role,
descRole : $scope.desc_role
};
console.log(data);
isDeleteBtnClicked = true;
}
});
};
And following is the running code snippet:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<thead>
<tr>deleteRole
<th><span>Code</span>
</th>
<th><span>Description</span>
</th>
<th>
Suppression
</th>
</tr>
</thead>
<tbody>
<div>
<div>
<tr ng-repeat="role in roles"
ng-click="selectRole(role);">
<td>{{ role.codeRole }}</td>
<td>{{ role.descRole }}</td>
<td>
<span title="Supprimer le rôle"
ng-click="deleteRole();">Delete</span>
</td>
</tr>
</div>
</div>
</tbody>
</table>
<div id="deleteModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title">Confirmation</h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Voulez-vous supprimer l'élément ?</p>
</div>
<div class="modal-footer">
<button type="button" id="deleteBtn" class="btn btn-primary">Supprimer</button>
<button type="button" id="cancelDeleteBtn" class="btn btn-secondary" data-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.roles = [
{
"codeRole": "test",
"descRole": "test desc"
},
{"codeRole": "test2",
"descRole": "test desc1"
}
];
$scope.selectRole = function(role) {
$scope.code_role = role.codeRole;
$scope.desc_role = role.descRole;
};
$scope.deleteRole = function(){
$('#deleteModal').show();
var isDeleteBtnClicked = false;
$('#deleteBtn').click(function($event){
if(!isDeleteBtnClicked)
{
$('#deleteModal').hide();
var data = {
codeRole: $scope.code_role,
descRole : $scope.desc_role
};
console.log(data);
isDeleteBtnClicked = true;
}
});
};
});
</script>
</body>
</html>
if still have doubt, please let me know
Upvotes: 0