How can I get the value of name2?
function DemoController($scope) {
$scope.name1 = 'LISA';
//How can I get the value of name2?
console.log($scope.name2) //this does not work
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="" ng-controller="DemoController">
{{ name1 }}
<input type="text" placeholder="Lisa" ng-model="name2">
</div>
This happens because your not initialize the name2 inside the controller. so there is no property called name2 in the scope at the moment of console.log . and name2 property will create on the scope right after your first change on the input. so thats why its getting undefined.
here is the Demo Plunker, check the console.
$scope.$watch('name2', function(newVal, oldVal) {
console.log("new value : " + newVal);
console.log("old value : " + oldVal);
});
i have added a $watch on name2 property (and this $watch function will execute when changing the value of name2), note that its undefined first and it will take the value of input right after you type something in the textbox.
try this
<div ng-app="" ng-controller="DemoController">
{{ name2 }}
<input type="text" placeholder="Lisa" ng-model="name2">
</div>
First, your controller is running before $scope.name2 even existed yet. You should have the console report the changes at some point AFTER. Remove that line from your code. (console.log...)
Whenever the text in name2 changes, $scope.name2 will be set to that value. You can see the effect if you ADD the following to the controller:
$scope.saveChanges = function () {
alert($scope.name2);
}
And to the HTML:
<button ng-click="saveChanges()">See Value</button>
try to follow me on this one.
On the first execution of the script, the variable (or property - doesn't really matter for this topic) is not declared.
Once the interpreter reaches the console.log function, it tries to call name2's value, But as we said - it is not defined.
In order to log the data you're binding, you should implement some logic that executes console.log only after a change or maybe even using $scope.apply. (I believe that $scope.apply is too far for you right now and you should ignore it).
Bottom line is - Your variable is not defined for the first iteration, therefore you're getting this result.
You must submit form to get Values or you use Watch Function
function DemoController($scope) {
$scope.name1 = 'LISA';
$scope.submitName = function () {
console.log($scope.name2)
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="" ng-controller="DemoController">
{{ name1 }}
<input type="text" placeholder="Lisa" ng-model="name2">
<button ng-click="submitName()">click </button>
</div>
name 2 will change as you type in the input box. You can see this by adding
{{name2}}
to your html
the controller will not see the change in name2 unless you watch for it, you can do this using $watch, add this to your controller
$scope.$watch('name2', function() {
console.log($scope.name2);
});
Put your ng model in watch for getting the updates
function DemoController($scope) {
$scope.name1 = 'LISA';
//this will work
$scope.$watch(function(val){
if(val){
console.log($scope.name2);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="" ng-controller="DemoController">
{{ name1 }}
<input type="text" placeholder="Lisa" ng-model="name2">
</div>
Related
I will have N number of input fields and every field will have a value CHANGE without getting in or out of focus. How can I detect value change of every input field.
I only found one question related and using that I tried following but it is not working. can Any one help further
for (var i=0;i<$scope.customers.product.length;i++)
{
//i m trying to get unique ids and bining input fields for change
$('#total-i').on('input', function() {
alert($(this).val()); // get the current value of the input field.
});
}
//there will be multiple of input fields having unique ids
<input id="total-{{$index}}" value={{cust.price*cust.quantity}}"/>
It should be easy and possible with ng-change provided you have ng-model associated to input.
<input id="total-{{$index}}" value={{cust.price*cust.quantity}}" ng-model="total" ng-change="updatemethod()"/>
total and updatemethod() should be part of controller $scope.
I'd create an object to associate with the ng-model and then watch it. Since you didn't provide a Codepen of fiddle instance to meddle with, I'm not sure this works, check it out.
//for each index
$.each(modelObject, function(key, value) {
//set a watcher
var watchString = "modelObject[" +key + "]";
$scope.$watch(watchString, function (newValue, oldValue) {
$scope.update(modelObject[key]);
});
});
The question you linked in your question is not about Angular (it uses jQuery). Where is the Angular way to do it (considering you are showing inputs with ng-repeat):
<div ng-repeat="i in items">
<input ng-model="i" ng-change="update(i)"/>
</div>
With this code, whenever you will update i (eg: when you will change the input value), the update(i) method will be triggered.
Here is a tiny example of what I'm explaining:
function MyCtrl($scope) {
$scope.items = ['1', '2', '3', '4', '5'];
$scope.update = function(item) {
alert(item + ' has been changed!');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
<div ng-repeat="i in items">
<input type="text" ng-model="i" ng-change="update(i)" />
</div>
</div>
See example here: https://jsfiddle.net/codefalling/u2mn764x/1/
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="number" ng-model="value" size="30" >
<input type="button" ng-click="change()" class="btn-primary" value="TEST" >
</div>
</div>
function TodoCtrl($scope) {
$scope.change = function() {
$scope.value = null
}
}
When I type 10 into number input, click button, it turn to be empty.
However when I type a standalone e or . into number input, then click button, nothing happend. But $scope.value = 123 stills works.
So, Why view didn't get update(empty) in this situation?
Additional, is there any other way to empty it?
To clear out the HTML 5 number controls, you can check the state of the control and if it is invalid then override its value to blank. I have updated your fiddle with the below code https://jsfiddle.net/u2mn764x/3/
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="number" ng-model="value" size="30" id='mynumber'>
<input type="button" ng-click="change()" class="btn-primary" value="TEST" >
</div>
</div>
function TodoCtrl($scope) {
$scope.change = function() {
if (!document.getElementById('mynumber').validity.valid)
{
$scope.value = null
document.getElementById('mynumber').value='';
}
}
}
For short, because e and . is not the complete legal numeric value. According to Foalting point number in W3 spec:
if the value started by ., it must be followed by one or more "0—9";
if the value started by e, it must be followed by an optional + or -, and one or more "0-9"
As the HTML check is not passed, it will not trigger the JS, as I imagine. If you continue to input .1 or e45, it works.
As soon as you type 10 inside Number Input,Angular will bind 10 and it will be like $scope.value = 10, but when you fire click event,you are changing the value to null like $scope.value = null,so send the value of model through the event and bind it to your variable.
<div ng-app>
<div ng-controller="TodoCtrl">
<input type="number" ng-model="value" size="30" >
<input type="button" ng-click="change($event,value)" class="btn-primary" value="TEST" >
</div>
</div>
And the javascript code :
function TodoCtrl($scope) {
$scope.change = function($event,val) {
$scope.value = val;
}
}
Thanks to comment of #zeroflagL.I found the answer.
Model did not have a value when input is illegal. So $scope.value = null or $scope.value = '' won't work because they are illegal value,too.
Model value and view value are both undefined, so angular did not update view.
We can use DOM API to empty illegal input manually. Or set modal to a value, force dirty check then set it to null again:
$scope.value = 0
$scope.$apply();
$scope.value = null
See https://jsfiddle.net/codefalling/xhcz3Lbj/
I have an ng-repeat which creates a form with some starting data. Then the user is free to modify said data and the changes should appear in the form. Before that, the user submitted data are sanitized by another function, which is called by an ng-click on a button.
Everything works well under the hood (I checked my $scope.some_array, from which ng-repeat takes the data and the new data is in the right place) but nothing happens on the page.
The element:
<li ng-repeat="field in some_array" id="field-{{$index}}">
<div class="{{field.field_color}}">
<button type="button" ng-click="save_field($index)">done</button>
{{field.nice_name}}
</div>
<div id="field-input-{{$index}}">
<input type="text" id="{{field.tag}}" value="{{field.content}}">
<label for="{{field.tag}}">{{field.nice_name}}</label>
</div>
</li>
save_field code:
$scope.save_field = function (index) {
console.log($scope.some_array[index]["content"])
var value = $("#field-" + index).children("div").children("input").val()
var name = $scope.some_array[index]["name"]
var clean_value = my_clean(value)
if (norm_value === "") {
return
}
$scope.some_array[index]["content"] = clean_value
console.log($scope.some_array[index]["content"])
}
On the console I see:
10.03.16
10/03/16
Which is right, but in the form I only see 10.03.16. I already tried putting $timeout(function(){$scope.$apply()}) as the last line of my function, but the output is still the same.
You shouldn't use input like this if you want to bind a variable to it. Digest loop will refresh the value but it will not be updated visibly because this is not html native behavior.
Use ng-model instead, it will update view value of the input as expected:
<input type="text" id="{{field.tag}}" ng-model="field.content">
Also using ng-model your variable will be updated when user modify the input, so you can retrieve it to do some treatments much more easily in save_field function, without jQuery:
$scope.save_field = function (index) {
if (norm_value === "") {
return;
}
$scope.some_array[index]["content"] = my_clean($scope.some_array[index]["content"]);
};
More infos: https://docs.angularjs.org/api/ng/directive/ngModel
I'm still fairly new to angular.js. This seems like it should be very simple, but I'm stumped.
I have an input field:
<input type="text" placeholder="Search" ng-model="search.txt">
And I have a button that calls this function in my controller on ng-click:
$scope.clearSearch = function() {
$scope.search = {txt:"qqqqq"};
}
Clicking the button behaves as expected - the input value on the page becomes "qqqqq". So the data binding seems correct.
However, if I type anything into the field first and then press the button, the input value does not change on the page - the input field keeps the value I typed. Why is that?
What I'm really trying to do is clear the field, I'm just using "qqqqq" for illustration - setting the value to null has the same behavior.
It works:
Script:
angular.module('myapp',[])
.controller('myctrl',function($scope){
$scope.search = {text:'some input'};
$scope.clearSearch = function () {
$scope.search={text:null};
}
});
Markup:
<div ng-app="myapp" ng-controller="myctrl">
<input type="text" ng-model="search.text"/>
<button ng-click="clearSearch()">clear</button>
</div>
In plunker
I want to sum up 2 values and display the result in the 3rd input:
HTML
<div ng-app="myApp">
<div ng-controller="MainCtrl as mainCtrl">
Main {{mainCtrl.foo}} <br/>
<input type="text" ng-model="mainCtrl.foo"/>
<input type="text" ng-model="mainCtrl.foo2"/>
<input type="text" ng-model="mainCtrl.foo3"/>
<br/>
</div>
</div>
JS
var myApp = angular.module('myApp', []);
var my = {};
my.MainCtrl = function() {
this.foo = '1';
this.foo2 = '2'
this.foo3 = this.sumUp();
}
my.MainCtrl.prototype.sumUp = function() {
return this.foo + this.foo2;
}
// register all controllers
myApp.controller('MainCtrl', my.MainCtrl);
My problem is that the 3rd input is set only when the document is loaded but it is not dynamically changing while typing values in first two inputs.
Fiddle:
http://jsfiddle.net/K64wb/
Use parameter ng-change for input-fields 1 and 2.
Solution for U ;) ng-change="mainCtrl.foo3=mainCtrl.sumUp()"
Example:
<div ng-controller="MainCtrl as mainCtrl">
Main {{mainCtrl.foo}} <br/>
<input type="text" ng-change="mainCtrl.foo3=mainCtrl.sumUp()" ng-model="mainCtrl.foo"/>
<input type="text" ng-change="mainCtrl.foo3=mainCtrl.sumUp()" ng-model="mainCtrl.foo2"/>
<input type="text" ng-model="mainCtrl.foo3"/>
<br/>
</div>
When your view loads, it only fires the controller function once. So it assigns foo and foo2, and then computes foo3, and then it's done. this.sumUp is never called again.
You can add ng-change="mainCtrl.foo3=mainCtrl.sumUp()" to the input boxes like Mularski suggests. This causes the sumUp function to run and be assigned to foo3 every time the input value changes. I think that looks kind of messy, though. And if you decided to add more input boxes to add up, you have to remember to put ng-change on all of them.
Another way to do it is to assign the sumUp function itself to foo3 like this
this.foo3 = this.sumUp;
instead of assigning the result of sumUp like you are doing (this.foo3 = this.sumUp();). Then in your view, assign foo3() to the ng-value of the textbox:
<input type="text" ng-value="mainCtrl.foo3()"/>
(you can't assign it to ng-model because the function isn't writeable).
Now you're telling the textbox to always show the result of that function, and it will fire whenever any of its dependencies change (i.e. foo and foo2).
Here's a Fiddle.