I have the following code:
<input id="id">
<button data-action="bea" ng-click="Create($('#id1')[0].value);" class="btn">Insert ID</button>
<button data-action="bea" ng-click="Create($('#id2')[0].value);" class="btn">Insert ID</button>
In the JS I have:
$scope.Create = function (id){
if (id === undefined) {
$scope.data = "You must specify an id";
} else {
$scope.data = data;
console.log(data);
});
}
};
When the call gets into the Create function the value of the id is undefined.
If I add the following line at the beginging of the Create function everything works ok:
id = $('#id')[0].value;
If I send a constant value it works:
<button data-action="bea" ng-click="Create('SomeID');" class="btn">Insert ID</button>
Why is this happening and how can I do that without putting the line of value into the method?
Thanks
This is just an extension of comments and other answers, You could achieve this in many ways using angular, one simple example could be:-
<!-- Add a controller -->
<div ng-controller="MainCtrl">
<!-- Give a model binding to your text input -->
<input ng-model="userEntry" type="text"/>
<!-- ng-click pass which ever argument you need to pass, provided it is an expression that can be evaluated against the scope or any constants -->
<button data-action="bea" ng-click="Create(userEntry);" class="btn">Insert ID</button>
<!-- Some simple data binding using interpolation -->
{{data}}
<!-- Just for demo on repeater on a list of items on the scope -->
<div ng-repeat="item in items track by $index">{{item}}</div>
</div>
Example Demo
My 2 cents on the lines of what were originally trying to do:-
Use angular bindings instead of accessing DOM directly for getting the data, it really helps you deal with just the data without worrying about how to access or render it in DOM. If you think you need to access DOM for implementing business logic re-think on the design, if you really need to do it, do it in a directive. Angular is very opinionated on the design and when where you do DOM access.
ng-model
ng-binding
controller
all about ngmodel controller
This is not the way you should do in AngularJS. You should really think in Angular if you want to use AngularJS. Refer this post ("Thinking in AngularJS" if I have a jQuery background?)
All DOM manipulation should be done in Directive. Refer this page that I found really clear.
(http://ng-learn.org/2014/01/Dom-Manipulations/)
My guess is that $ is not bound to the jQuery function when the ng-click value is evaluated, because it is not exposed in the Angular scope.
Solutions to adress this:
expose the jQuery function in scope somewhere, e.g $scope.$ = $; in a controller.
make the Create function parameterless as you suggested, with a var id = $('#id')[0].value; at the beginning
my favorite : avoid using jQuery. If you put some data in the #id element, there's probably a more natural and AngularJS-idiomatic way of retrieving it than querying the DOM (e.g an Angular service).
In particular, if the element you're targeting is an <input> element, then use the ngModel directive to link the value to a $scopeproperty that will be accessible in the controller :
<input ng-model="inputData"/>
The JavaScript you are trying to pass as a parameter of the create function is not available in the scope of the Create function.
Try to target the element a different way.
Does that help?
Is it possible to pass angular js data available on a cshtml page to a button click event?
the angular js object is referenced as item.property. {{item.property}} works well between the html tags.
The function is:
function ShowFileDialog(ProjectID)
{
alert(ProjectID);
}
The cshtml that I would like to do is something like this, but clearly is very wrong.
<button id="button-view" onclick="ShowFileDialog({{item.projectId}})"></button>
I already have a work around - so others are not needed.
In your controller,
$scope.project= {"Id": 1, "name":"project1"};
$scope.ShowFileDialog = function(ProjectID)
{
alert(ProjectID);
}
then in your html,
<button id="button-view" ng-click="ShowFileDialog(project.Id)">show dialog</button>
If you have a list of projects as such,
$scope.projects= [{"Id": 1, "name":"project1"},{"Id": 2, "name":"project2"}];
then in your html use ng-repeat as,
<ul>
<li ng-repeat="proj in projects>
{{proj.name}} <button ng-click="ShowFileDialog(proj.Id)">show dialog</button>
</li>
</ul>
see more here
From my POV these type of mixes shouldn't be done. The closest correct approach should be:
Setting your view with a value in the way angular was meant to be used:
<input type="text" ng-model="myVariable" id="myVar" />
and if you want to you get or use this value get it from the view like:
<script type="text/javascript">
var param1 = document.getElementById("myVal").value;
samplefunction( param1 );
</script>
Online Demo
Note:
In this example I used an input but you could use a data-myVar attribute and get the value from there as well.
I have been ploughing into AngularJS and am trying to get my head around how everything links together but I've become a bit stuck.
How can I pass a variable to change the JSON that is loaded and shown on the page?
I thought it would be a button click and the directive would talk to the controller, but how I'm not so sure.
If i have my JSON as something like this as in controller...
var id = 'peter';
var person = $resource('http://myjson.com/'+id+'.json')
I can't figure out how I would change the id based on button clicks for example.
Any help is greatly appreciated
I'll try to explain as simple as possible, you can pass data as argument to a function from HTML to controller using the ngClick directive.
The function inside the controller will be invoked because it has a binding to the ngClick directive using the $scope.
Example:
html:
<div ng-app="App" ng-controller="ctrl">
<div ng-repeat="itemId in items">
<button ng-click="myClickFunc(itemId)">click {{itemId}}</button>
</div>
</div>
js:
var app=angular.module('App', ['ngResource']);
function ctrl($scope,$resource){
$scope.items=[1,2,3,4];
$scope.myClickFunc=function(itemId){
var person = $resource('http://myjson.com/get/:id');
person.get({id: itemId}).$promise.then(function(data) {
// success
$scope.myData = data;
}, function(errResponse) {
// fail
});
}
Live example: http://jsfiddle.net/choroshin/zJ5G6/
I am using ng-click and it fires twice when I apply it to SPAN tag.
HTML
<div ng-app="regApp" ng-controller="RegistrationCtrl" data-ng-init="GetEventDetail()" ng-show="data.EventName">
<h2>Registration for {{data.EventName}}</h2>
<span class="btn" id="btnSave" ng-click="PostRegistration()">Save </span>
</div>
CONTROLLER
var app = angular.module('regApp', ['ui']);
app.controller('RegistrationCtrl', function ($scope, $http) {
$scope.PostRegistration = function () {
alert('click '); <--- fires twice
/// some code here --
};
It should only fire once. How I can find why this is happening and how to fix it?
The code you've provided does not fire the event twice:
http://jsfiddle.net/kNL6E/ (click Save)
Perhaps you included Angular twice? If you do that, you'll get two alerts, demonstrated here:
http://jsfiddle.net/kNL6E/1/
I had a similar problem, but could not find where I included Angular twice in my files.
I was using an ajax calls to load specific form layouts, so I need to use $compile to activate Angular on the inserted DOM. However, I was using $compile on my directive $element which has a controller attached. Turns out this "includes" the controller twice, causing two triggers with ng-click or ng-submit.
I fixed this by using $compile directly on the inserted DOM instead of my directive $element.
Same problem using
<a ng-click="fn()"></a>
fn was called twice
Using a button fixed it :
<button ng-click="fn()"></button>
This is probably obscure, but I had ng-click firing twice because I had BrowserSync running, which would mirror my inputs into a tab that I had open in another window, thus doubling up all my clicks. To resolve, I disabled “ghostMode”: https://www.browsersync.io/docs/options/
I solved this by removing my ngsubmit handler as I don't have a need for it. I'm monitoring on change events and using SignalR to update the screen in near real-time.
I was also in a form and the AngularJS docs for ngSubmit states:
Warning: Be careful not to cause "double-submission" by using both the ngClick and ngSubmit handlers together. See the form directive documentation for a detailed discussion of when ngSubmit may be triggered.
In case of somebody having the same issue:
This was my problem:
<a type="submit" ng-click="login()">submit login<a>
Both, the type="submit" and the ng-click="login()"triggered the login()-method in my controller.
So just use either the type=submit or the ng-click directive
If other answers don't help, make sure that AngularJS profiling is disabled in Batarang (if you have it installed of course).
This was making ng-click to fire twice for me.
elements wrapped one another, and this can cause trigger event twice or more.
So i used a simple CSS trick for this solution :
.off{
pointer-events:none;
}
and apply it to an element correspond to click event.
You might have a ng-click inside a form container using a ng-submit. In that case, add type="button" to all your using ng-click.
I got it when I accidently called $compile for the dynamically added elements several times in the cycle, instead of just once. Compiling just once removed this effect.
was facing same issue.
Find out they were using https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js version and i switch it to latest 1.4.5 version and it just worked.
https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js
var app = angular.module('regApp', []);
app.controller('RegistrationCtrl', ['$scope','$http',function($scope,$http ) {
$scope.PostRegistration = function() {
alert('click '); // <--- fires twice
/// some code here --
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="regApp" ng-controller="RegistrationCtrl">
<h2 >Registration for {{data.EventName}}</h2>
<span ng-click="PostRegistration()" class="btn" id="btnSave">Save </span>
</div>
I have changed <button ng-click='clickHandler()'> to <a ng-click='clickHandler()'> and now event fires only once
I've had the same issue when dynamically injecting partial views in my SPA(Single Page Applications).The way I solved it was to store the content of my div in a local variable like this:
var html = $("#leftContainer").html();
Then empty out the div and reset its content like this:
$("#leftContainer").empty();
$("#leftContainer").append(html);
Now you can add any additional html you have received from an AJAX call or dynamically constructed and lastly remember to re-compile your HTML to make it bound to angular:
var entities = $("#entitiesContainer");
var entity = "<div><a href='#' ng-click='Left(" + entityId + ")'> " + entityName + "</a><div>"
entities.append(entity);
var leftContainer = angular.element(document.getElementById("entitiesContainer"));
$compile(leftContainer)($scope);
I'm a bit of a dummy and had this:
<li data-shape="amethyst" ng-click="toggleGem('amethyst')">
<label></label>
<i class="amethyst"></i>Amethyst
<input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>
The click event was triggering twice. I moved the ng-click to the label element and it's working as expected.
<li data-shape="amethyst">
<label ng-click="toggleGem('amethyst')"></label>
<i class="amethyst"></i>Amethyst
<input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>
This situation may be caused by lacking the ngTouch in Angular.
Event if the ngTouch is loaded, the bug in ngTouch and ngClick before Angular 1.5.0 may occur. It results from the ngClick being triggered by pointerup and mouseUp in Chrome for Desktop on device toolbar or mobile device.
I had a problem like this as well.
<button style="width: 100%;" class="btn btn-danger" ng-click="'{{vm.delete()}}'">
Thats not how you call ng-click, but no errors were thrown and the function calls still worked.
<button style="width: 100%;" class="btn btn-danger" ng-click="vm.delete()">
Is correct and will then only be called once.
I don't know what was the reason this happened, but I had to use event.stopPropagation(); inner my JavaScript function.
HTML
<button class="button" ng-click="save($event)">Save</button>
JAVASCRIPT
function save(event) {
event.stopPropagation();
}
I have handled it by following code
HTML :
<div>
<ui>
<li>
<button class="Button" ng-disabled="self.desableSubmitButton" ng-
click="self.SubmitClick($event)">Submit</button>
</li>
</ui>
</div>
Angular 1.0 Controller :
_self.SubmitClick = function(event){
_self.desableSubmitButton = true; //disable submit button
event.preventDefault();
event.stopPropagation();
setTimeout(funtion() {
_self.desableSubmitButton = false; //enable submit button after timeout
if(_self.$scope.$$phase != '$apply' || _self.$scope.$$phase != '$digest'){
_self.$scope.$digest();
}
}, 1000);//other Code logic
}
My case: I used ng-click event on my custom custom angular checkbox component. So just providing a method binding for custom component did the trick.
Before:
<mono-checkbox-ng ng-click="vm.onSelectAllClicked()">
After:
<mono-checkbox-ng on-changed="vm.onSelectAllClicked()">
The two way binding in AngularJs is great in updating the view anytime the model changes. I was wondering if there was some way to pass the model to a function defined in the controller before being displayed. And not with a button click but live.
So for example, the p element would be updated automatically
<input data-ng-model='myModel'>
<p>{{myModel}}</p>
Is there any way to do the following?
<div data-ng-controller='myController'>
<input data-ng-model='myModel'>
<p>{{increment(myModel)}}</p>
</div>
where increment is a function defined in myController
Most definitely you can. Just define the function in the same controller. For instance
Controller:
app.controller('myCtrl', function($scope) {
$scope.increment = function() {
return $scope.myModel;
}
});
HTML
<div data-ng-controller='myController'>
<input data-ng-model='myModel'>
<p>{{increment()}}</p>
</div>
That returns the exact same thing as {{myModel}}