ng-click not firing on a button click - javascript

I am facing weird error where I am not able to call a function on ng-click when button is clicked.
This is the block of code for which the ng-click is not working for delete button but working for edit button.
<table ng-table="tableParams" class="table table-striped table-bordered Pages_table">
<thead>
<td><b>Id</b></td>
<td><b>Image</b></td>
<td><b>Alt</b></td>
<td><b>Edit</b></td>
<td><b>Delete</b></td>
</thead>
<tbody>
<tr ng-repeat="dat in newData">
<td>((dat.id))</td>
<td class="clients_review_admin_item"><img src="((imagePath+'/'+dat.image))" alt="" style="height:100px;width:150px" /></td>
<td>((dat.alt))</td>
<td><button type="button" class="btn btn-info rounded-buttons" data-toggle="modal" data-target="#editWhy" ng-click="editWhy(dat)" ><i class="fa fa-pencil"></i></button></td>
<td>
<button class="btn btn-danger rounded-buttons" type="button" ng-click="deleteFooter(dat.id,dat.alt)"><i class="fa fa-close"></i></button>
</td>
</tr>
</tbody>
</table>
The Javascript function deleteFooter
$scope.deleteFooter = function(id,name){
console.log("called");
var postUrl = apiUrl+"/delfriendfooter";
var $inputs = {
id:id,
token:$scope.token,
};
var func = function(){
$http.post(postUrl, $inputs).
success(function(data, status, headers, config) {
swal("Deleted!", name+" has been deleted!", "success");
var dat = $scope.newData;
for(var i=0,len= dat.length;i<len;i++){
if(dat[i].id==id){
dat.splice(i,1);
break;
}
}
}).
error(function(data, status, headers, config) {
sweetAlert("Oops!!", "Please try again!!", "error");
});
}
$scope.deletePopUp(func,name);
};
The weird thing is that it is working for the edit functionality
<td><button class="btn btn-info rounded-buttons" data-toggle="modal" data-target="#editWhy" ng-click="editWhy(dat)" ><i class="fa fa-pencil"></i></button></td>
I have also tried to call other functions but it is just not firing.
Note: I have changed the angular braces to (()).

This is happening because of the way angular / buttons / forms work.
Specifically:
To prevent double execution of the handler, use only one of the ngSubmit or ngClick directives. This is because of the following form submission rules in the HTML specification:
If a form has only one input field then hitting enter in this field triggers form submit (ngSubmit)
If a form has 2+ input fields and no buttons or input[type=submit] then hitting enter doesn't trigger submit
If a form has one or more input fields and one or more buttons or input[type=submit] then hitting enter in any of the input fields will trigger the click handler on the first button or input[type=submit] (ngClick) and a submit handler on the enclosing form (ngSubmit)
Because of these rules, buttons can behave a little strangely.
A solution is to add type="button" to your buttons. This will basically prevent these rules from being applied:
<button type="button" class="btn btn-danger rounded-buttons" ng-click="deleteFooter(dat.id,dat.alt)"><i class="fa fa-close"></i></button>
Angular will then, instead of using the form standards to decide what function to call, simply execute the ng-click's function.

The problem is that i guess deleteFooter function and it's ng-click is called on different scopes.
Both are defined in your controllers scope, and its fine.
But i suppose, as You wrote, that you call deleteFooter in ng-repeat, which has its own scope.
Use $parent to enforce your controller scope on deleteFooter.
<button class="btn btn-danger rounded-buttons" ng-click="$parent.deleteFooter(dat.id,dat.alt)"><i class="fa fa-close"></i></button>

Ok so after so many efforts I opted for jquery ajax method and applied the changes using angular $apply to the scope variable. I am still not sure what is wrong.

Related

Calling controller AngularJS from a button in HTML

I need to call the controller deleteMember so to when the user clicks on a button, the member is deleted.
//deleting a member
Members.controller('deleteMember',['$scope','$http',function($scope, $http){
$scope.deleteMember = function(member){
$scope.deleteMember="";
console.log(member);
var deleteMember=confirm("Sure you want to delete?");
if(deleteMember){
$http.post('PHP/deleteMember.php',member).success(
function(data){
console.log(data);
if (data){
console.log("Deletion successful"); //delete worked
}else{
console.log("Deletion not successful"); //delete did not work
}
});
};
};
}]);
HTML code:
<div class="col-md-2">
<td><button type="button" class="btn btn-warning">Delete</button><td> <!--on button click, the member will be deleted-->
</div>
Is there a way that I can write the name of the controller using HTML?
Thanks for the help :)
You could add the ng-click attribute to the button:
<button type="button" ng-click="deleteMember(member)" class="btn btn-warning">Delete</button>
In this example I assume that the member variable that is passed to the deleteMember method is already in the scope of this button. This would be the case if this button is rendered inside an ng-repeat directive.
For example:
<tr ng-repeat="member in members">
...
<td>
<button type="button" ng-click="deleteMember(member)" class="btn btn-warning">
Delete
</button>
<td>
</tr>
Also you should probably not shooting yourself into the foot by replacing the deleteMember function with a string because the next time you want to call this method it simply won't work:
$scope.deleteMember = "";
You can simply just call the function deleteMember using ng-click and make sure you pass in the member you want to delete as an argument. You are passing a member in your function as an argument in the controller, so one must also be passed via the HTML. You haven't shown it in your code but I assume you are using ng-repeat to do this.
<div class="col-md-2">
<td><button type="button" class="btn btn-warning" ng-click="deleteMember(member)">Delete</button><td> <!--on button click, the member will be deleted-->
</div>
You mention calling the controller in the HTML. If you mean your page isn't initiated with the 'deleteMember' controller then you can wrap that block of code using ng-controller to give you access to the deleteMember.
<div class="col-md-2" ng-controller="deleteMember">
<td><button type="button" class="btn btn-warning" ng-click="deleteMember(member)">Delete</button><td> <!--on button click, the member will be deleted-->
</div>

Clear input in Angular with button, but same button is also used as part of ng-show

First of all, I can imagine the subject of this question is not very clear, so sorry for that.
I am using a button with ng-click to display an input (ng-show) and two other buttons(send, cancel). For hiding the input again I use the "cancel" button. But I also would like to clear the value of the input. The problem is that I dont know how to invoke the clear function as well as the hiding the input again with the same button.
Here is my code:
<button class="btn-share" ng-click="showme = !showme" clickng-class="{true: 'hideBtn', false: 'btn btn-xs btn-danger'}[showme]">
show input.
</button>
<div class="form-group" ng-show="showme">
<input id="myInput2" class="typeahead" sf-typeahead type="text" datasets="userDataset" ng-model="searchUser" >
<button ng-click="showme=false" class="btn btn-xs">Cancel</button>
<button ng-click="send()" class="btn btn-success btn-xs btn-sent">Send</button>
</div>
$scope.showme = false;
Just update your code
<button class="btn-share" ng-click="showme = !showme" clickng-class="{true: 'hideBtn', false: 'btn btn-xs btn-danger'}[showme]">
with
<button class="btn-share" ng-click="searchUser='';showme = !showme" clickng-class="{true: 'hideBtn', false: 'btn btn-xs btn-danger'}[showme]">
I have added searchUser='' in ng-click. So, when user click on it, it will first update the searchUser to empty string in scope and then update showMe in scope.
If you do not want information after cancel, you can do the same thing with ng-click of cancel button.
Here is a plunker for you - http://plnkr.co/edit/X9wbGYsBoIXxR7QmE1zP?p=preview
If you add this line to your clear() function:
$scope.showme = false;
it will invoke the function and set the showme variable to false, thus hiding the div!
So your clear function could look like this:
$scope.clear = function() {
$scope.searchUser = "";
$scope.showme = false;
}

Disable 2 buttons when one is clicked using angularjs

I am new to angularJS and am working on a form which has 2 buttons on it (submit & close).
The 'Submit' button has a type="submit" and the 'Close' button has a type="button".
I have managed to disable the 'Submit' button when clicked but I also need the 'Close' button to be disabled.
This is the bit I am stuck on.
Also to point out the 'Submit' button on my form is 'Disabled' when the form opens until all the mandatory fields are populated.
All of this currently is done in the HTML.
HTML
<button ng-disabled="enterreminder.remtype.$invalid
|| enterreminder.remother.$invalid
|| enterreminder.remarea.$invalid
|| enterreminder.remdate.$invalid
|| enterreminder.remsubject.$invalid
|| enterreminder.remnotes.$invalid"
type="submit" class="btn btn-primary" ng-click="submit()" onclick="this.disabled=true;" title="Click to set the reminder.">
Submit
</button>
<button type="button" class="btn btn-warning" ng-click="cancel()" title="Click cancel the reminder.">Close</button>
So to sum up I want the 'Submit' and 'Close' buttons to be disabled when the 'Submit' button is clicked. I'm not bothered if the 'Close' button is clicked as the 'Submit' button is already disabled.
Will I need to add code to my controller? and if so can you please help me out with it as I cant seem to find a starting point from Google.
Thanks
In a nutshell, you need to have a ViewModel property that drives the desired behavior and assign it to each button's ng-disabled directive:
<button type="submit" ng-disabled="commandButtonsDisabled"
ng-click="submit(); commandButtonsDisabled = true">Submit</button>
<button type="button" ng-disabled="commandButtonsDisabled"
ng-click="cancel()">Close</button>
This just illustrates the point, but it's not a good design to have multiple actions assigned to ng-click. The code above also doesn't show how $scope.commandButtonsDisabled is initialized (although, being undefined it would result in falsy value) and reverted back, so it's better to put this functionality in a controller:
.controller("MyCtrl", function($scope, $http){
$scope.commandButtonsDisabled = false;
$scope.submit = function(){
$scope.commandButtonsDisabled = true;
$http.post(....)
.success(...)
.finally(function(){
$scope.commandButtonsDisabled = false;
}
}
}
<button type="submit" ng-disabled="commandButtonsDisabled" ng-click="submit()">Submit</button>
<button type="button" ng-disabled="commandButtonsDisabled" ng-click="cancel()">Close</button>
Off-topic:
It seems that you have a bunch of form elements that you are also testing for validity. Instead of testing each element individually, use the validity of the form:
<div ng-form="enterreminder">
<input ng-model="remtype" ...>
<input ng-model="remother" ...>
...
<button type="submit" ng-disabled="enterreminder.$invalid || commandButtonsDisabled"...>Submit</button>
</div>
here is an example...
Put this code in .js file
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope) {
$scope.name = 'World';
$scope.disable_buttons = false;
$scope.submit = function () {
$scope.disable_buttons = true;
}
});
And in HTML
<button ng-disabled="disable_buttons"
type="submit" ng-click="submit()" title="Click to set the reminder.">
Submit
</button>
<button ng-disabled="disable_buttons" type="button" ng-click="cancel()" title="Click cancel the reminder.">Close</button>
Can't your submit and close buttons watch a single scope variable such as 'submit' below:
<button ng-disabled="submit" ng-click="submit=true">Submit</button>
<button ng-disabled="submit">close</button>

Angular: on click, add input fields text to array

First off, starting out with this so a bit confused. I have a simple table, where the contents are pulled in from a database and injected into the DOM with Angular.
The table consists of an option, and its value. I would like the user to be able to edit the values, and then click a "save" button, where I make a http call to my back-end with the details.
I've got the basics working, clicking a button and the input fields replace the table cell content:
Clicking "Edit":
When clicking "Cancel", it reverts back - so this is all working.
So this bit I can't work out, is when I press update, I want to create an array (json?), where I can send somewhere using http.
I'd need something where each object in the array/json contains the "option" and the "value", so I can match these in the database.
My HTML:
<div ng-hide="loading" class="table-responsive">
<table class="table table-striped table-compact table-bordered">
<thead>
<tr>
<th>Option</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="setting in settings">
<td><< setting.option >> <i class="fa fa-question pull-right pointer" tooltip="<< setting.description >>" ></i></td>
<td ng-switch="status">
<input ng-switch-when="editable" type="text" class="form-control" value="<< setting.value >>" />
<span ng-switch-when="uneditable"><< setting.value >></span>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-hide="loading" ng-switch="status">
<button ng-switch-when="uneditable" ng-click="edit()" class="btn btn-sm btn-info">Edit</button>
<button ng-switch-when="editable" ng-click="save()" class="btn btn-sm btn-success">Update</button>
<button ng-switch-when="editable" ng-click="cancel()" class="btn btn-sm btn-danger">Cancel</button>
</div>
And finally my ng controller:
app.controller('appSettingsController', function($scope, ApplicationSettings) {
$scope.settings = {};
$scope.loading = true;
$scope.status = 'uneditable';
// Grab data for table
ApplicationSettings.get()
.success(function(data) {
$scope.settings = data;
$scope.loading = false;
});
$scope.edit = function() {
$scope.status = 'editable';
$scope.updates = {};
};
$scope.cancel = function() {
$scope.status = 'uneditable';
};
$scope.save = function() {
// Construct Array/JSON of inputs
};
});
Anyone got any ideas? I have a feeling it's something to do with using ng-model?
Inside your table, the second column has the following input element tag when in edit mode:
<input ng-switch-when="editable" type="text" class="form-control"
value="<< setting.value >>" />
Firstly - I think the value attribute should be {{setting.value}} and not << setting.value >> - I can't imagine the latter giving the value in AngularJS.
Now, for your requirements. Instead of using the value attribute, you can use the ng-model attribute as you guessed.
With the ng-model attribute in place, the input should now be:
<input ng-switch-when="editable" type="text" class="form-control"
ng-model="setting.value" />
ng-model will take care of displaying the value for that input as well as due to two way data binding, the value entered into the input will be stored back into setting.value.
What this means is that, AngularJS automatically will update $scope.settings when you input something in the text box. You don't have to write any additional code to ensure that the value is put back. It's like the Update button was already clicked and data was saved - only that it wasn't clicked but data was still saved
The only downside to this is that when you click on cancel, the old values are no longer available (since the moment you type something into the text, the values are updated). You can store initial values of $scope.settings into another variable before switching to edit mode. That way, when you click cancel, you are still left with old values.

Customize the cancel code button of the X-editable (AngularJS)

Is that possible when the user add a new row and by clicking on the cancel button(without put any data), the row will be deleted.
Otherwise how can I change the cancel button code, because this one use the default xeditable code of angularJS.(Or maybe how can I call the delete function if the row is empty?)
This is the EXAMPLE.
HTML for the cancel button:
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
cancel
</button>
You may call your own function. To achieve this you should change your html like this:
<button type="button" ng-disabled="rowform.$waiting"
ng-click="cancelAdvice(rowform, $index)"
class="btn btn-default">
cancel
</button>
As you can see there is a new function with the form and the current index as parameter. In your controller you have to define this function:
$scope.cancelAdvice = function(rowform, index){
console.log(rowform, index);
$scope.removeUser(index);
rowform.$cancel();
}
Now you can do your own stuff and call the form $cancel if you are done.
Alternatively if you look at xeditable.js you'll see that $cancel() internally calls $oncancel() which looks for oncancel attribute on the form and calls the function supplied in it. So instead of handling the form in the controller you could have:
<form editable-form name="rowform" onbeforesave="saveRole($data, $index)" oncancel="removeIfNewRow($index)" ng-show="rowform.$visible" class="form-inline" shown="inserted == role">
<button type="submit" ng-disabled="rowform.$waiting" class="btn btn-primary">
save
</button>
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
cancel
</button>
</form>

Categories