I have the following code:
<div data-ng-controller="MainController">
<input class="amount" type="text" name="" value="" />
<input class="result" type="text" name="" value=""/>
</div>
I want to take a numerical value from $scope and add it to a number entered by a user in the input with class "amount" and display the result in the input with class "result". So, basically, the variable is defined in the MainController function as the following:
$scope.cost = 100;
I'm a bit confused as to what the best way is to do this, I see there are ng-value and ng-model directives at my disposal but I am having a hard time understanding which is the right one for this application (and how to properly use them).
Seems like your application is asking for an inputs and they are going to submit there values OR gonna store it somewhere in DB. So ng-model (two way binding) will suits you application, which will update the value on model & view both.
Markup
<div data-ng-controller="MainController">
<input class="amount" type="text" ng-model="cost"/>
</div>
Above field will pre-populated as 100 and as you update it will also change $scope.cost value and the value if it is displayed on view anywhere.
Don't think about the ng-value that is only one way sort of binding. You can assign the value to input using ng-value="cost" that will only update the value attribute of input but when you update input from html you will never get those changes reflected inside cost scope variable as ng-value is meant for single way binding. Thinks like you should use use ng-value only when you want to display a value.
you should use ng-model
ng-value : Its a directive useful for evaluating expression and the value is bound to $scope used for evaluating expressions
ng-model : helps in two-way data binding ,view-->controller and vice versa moreover its a directive binds the value of HTML controls
Related
i need to pass value from vue to textbox, doing for one day but still didn't work.
my html input type code
<input type="hidden" id="variation" name="variation" v-model="variation">
second is my is my value is appear on paragraph
<p name fs="paragraph" fw="semi-bold" color="dark">{{ getVariantTitle(variant) }}</p>
its works for passing value to paragraph but not working for passing value into hidden html textbox. i really need value for passing into form post.
As the input type is hidden, instead of v-model just try using v-bind:value, as you don't need two way binding for a hidden input
I am sure there is better way to achieve what you're trying to do but for a quick fix you can try using v-bind instead of v-model
<input type="hidden" id="variation" name="variation" v-bind:value="variation">
This means the hidden text field will always have the same value as this.variation
EDIT:
<input type="hidden" id="variation" name="variation" :value="getVariantTitle(variant)">
A weird thing is happening on my form or maybe i am not doing it right, let me explain to you by presenting my code.
i have defined a form object inside my component
form = {};
There is a button on each row with data that when you click it opens a modal widow and also passes the item as argument.
<a class="btn btn-warning" (click)="open(item)"><i class="glyphicon glyphicon-pencil"></i></a>
This is the method that fires and opens a modal window but also assign the item object to form object above:
open = (item: any) => {
this.inventoryEditModal.open(); //Opens a modal window
this.form = item; // the assignment
}
The item object is available on the view by printing it out like this:
{{ form | json }} // i can see all item properties
The modal window contains a form where user will edit the item, so basically the input form fields should get filled with item properties values but for some reason the third level is undefined and i don't understand why, let me show you an screenshot of the second level
<input type="text" class="form-control" [(ngModel)]="form.alarmSystem" name="wireless">
The third level gets undefined:
<input type="text" class="form-control" [(ngModel)]="form.alarmSystem.wireless" name="wireless">
This issue is happening only for the third level "object.object.property". I am only showing one input field but the form contains more than 8 fields they all have same issue.
Not sure what i am missing here, but logically it should work. Do you have see this issue happening here and there or experienced your self?
Thank you in advance.
I am not sure if it helps your case, but I was in a very similar situation.
What helped me out was using the "safe-navigation-operator".
I assume that what you need to do is just add the ? after form:
<input type="text" class="form-control" [(ngModel)]="form?.alarmSystem.wireless" name="wireless">
The docs can be found here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#safe-navigation-operator
There can be 3 possible solutions with Angular 5
Don't assign ngForm to the template variable of the form (in form HTML element)
Don't do this -
<form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);">
Instead, do this -
<form (ngSubmit)="saveItem();">
<input type="text" class="form-control" name="wireless [(ngModel)]="form.alarmSystem.wireless">
<submit type="submit">Save</submit>
</form>
By this, you will be able to assign a 3 level nested property to
[(ngModel)] without any elvis or safe navigation operator (?).
If you are assigning ngForm to the form template variable then [(ngModel)] will give undefined for a 3 level nested property even if it already has some value.
So, use the name attribute instead -
<form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);">
<input type="text" name="alarmSystem.wireless" ngModel class="form-control">
</form>
Now, in this case, the nested property alarmSystem.wireless assigned
to the name attribute will be bound 2-way using ngModel directive.
And you can easily access it in the Event emitter function.
And the last solution by using elvis operator (?) is -
Here, again we will not assign ngForm in the form template variable, although there will not be any error but it won't store the value entered in input correctly.
So, split 2-way data binding with [ngModel] and (ngModelChange) like this
<form (ngSubmit)="saveItem();">
<input type="text" name="wireless"
[ngModel]="form?.alarmSystem?.wireless"
(ngModelChange)="form.alarmSystem.wireless=$event" class="form-control">
</form>
Also you can refer to this answer - Correct use of Elvis operator in Angular2 for Dart component's view
But, I don't recommend this solution as it adds up a lot of code.
I would like to know the better way of assigning model name for each form elements using Angular JS.
I can assign it using individual scope variables.
<input type="text" ng-model="firstName"/>
<input type="text" ng-model="lastName"/>
I can also assign it using singleton object.
<input type="text" ng-model="contact.firstName"/>
<input type="text" ng-model="contact.lastName"/>
Which is the better way of handling form data in terms of memory and execution time?
You should choose the second option, in order to avoid issue with scope inheritance, see the doc:
Scope inheritance is normally straightforward, and you often don't even need to know it is happening... until you try 2-way data binding (i.e., form elements, ng-model) to a primitive (e.g., number, string, boolean) defined on the parent scope from inside the child scope.
According to Miško Hevery, the creator of AngularJS:
Whenever you have ng-model there’s gotta be a dot in there somewhere.
If you don’t have a dot, you’re doing it wrong.
The question is why?
Because ng-switch, ng-repeat, etc. creates their own scopes.
For example, have a look at this plnkr
<form ng-submit='addName()'>
Name 1: <input type='text' ng-model='name'/>
<input type='submit' value="Submit"/>
</form>
<p ng-switch='true'>
Name 2: <input type='text' ng-switch-when="true" ng-model='name'/>
</p>
<p>
Name 3: <input type='text' ng-model='name'/>
</p>
Output:
When you type in the Name 1 text box, the value shows up immediately in all text boxes. This is as expected. The problem is that now when you type into the Name 2 text box, it value gets disconnected and the three box values are no longer in sync. This is because of the way that JavaScript’s prototypal inheritance works.
To avoid, we should use dot in ng-model. For example, have a look at this plnkr
<form ng-submit='addName()'>
Name 1: <input type='text' ng-model='contact.name'/>
<input type='submit' value="Submit"/>
</form>
<p ng-switch='true'>
Name 2: <input type='text' ng-switch-when="true" ng-model='contact.name'/>
</p>
<p>
Name 3: <input type='text' ng-model='contact.name'/>
</p>
Output:
Now the code works with all three text box always in sync.
Source:
AngularJS MTV Meetup: Best Practices (2012/12/11)
5 AngularJS Antipatterns & Pitfalls
Why ng-model value should contain a dot
Nested Scopes in AngularJS
AngularJS: dot in ng-model
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
Does my ng-model really need to have a dot to avoid child $scope problems?
AngularJS: If you are not using a .(dot) in your models you are doing it wrong?
I'm trying to select a radio button using a variable but, although I can print the selected value the button does not stay selected.
This button is defined in an angular template as follows:
<a ng-click="selectNode($event, node)">
<input type="radio" name="library" style="float:left;" id="id-{{n}}" />
</a>
Where id is a GUID so is definitely unique.
Then, because it is the angular click event that is called when a button is selected I call this code in selectNode:
context.selectedNodes = [node];
$scope.selectedNode = node.$model.name;
var id = '#id-' + node.$model.id;
//console.log(typeof id);
//console.log(id);
$(id).prop("checked", true);
alert($("[name=library]:checked").val())
Which should theoretically check the radio button. However, it checks for a moment (it is checked when I call the alert) and then seems to disappear. I am however able to hardcode in an id and it stays checked.
I recommend diving more into the tools angular gives you to handle this things simply. If you need to track the value on this input, tie it to a model. If you want to process something once the checkbox has changed, use ng-change and tie it to a function.
<input type="radio" name="library" style="float:left;" ng-model=libraryModel ng-change="doSomething()" />
Keep in mind that doSomething() needs to be in scope, so in your controller, you need to define the function as $scope.doSomething(). Your model will also be attached to the $scope object, so you'd reference it as $scope.libraryModel. You can initialize the model as true or false as needed for a default value in the controller, then any user changes will auto update this value.
You're mixing jQuery and Angularjs, and it is not really worth. You can do the following just by using AngularJS ngModel, if you use AngularJs in your project.
Controller
function Controller($scope) {
//Init data input to value 1
$scope.data = ['1'];
}
HTML
<input type="radio" name="name" value="1" ng-model="data">
<input type="radio" name="name" value="2" ng-model="data">
Here, our $scope.data is set to 1 in our Controller, so it will match with the first input.
I'm only starting to dive into angular.js and have found this issue that I can't seem to get around. Consider this simple code:
<input type="text" ng-model="test">
<input type="text" value="{{test}}">
When I write in the first field, the second one is updated nicely. When I write in the second field and then go back to the first one, the binding is not updated anymore. Interestingly though, the HTML attribute value does get updated - it's just not displayed.
Equivalent (at least roughly) code in vanilla javascript does not suffer from this:
<input type="text" id="model">
<input type="text" id="binding">
<script>
var model = document.getElementById("model");
var binding = document.getElementById("binding");
model.addEventListener("keyup",function() {
binding.value = model.value;
});
</script>
Here's a fiddle for you to test both: http://jsfiddle.net/Q6b5k/
Any idea why this happens when using angular.js and how to fix this?
[EDIT] Judging by the initial replies, it appears I have not made it clear. I do not want the second field to update the first one. The binding is to be one-way only, e.g. to allow filtering or even manual corrections (such as automatic creation of a URL alias in a blog post creation form). http://jsfiddle.net/Q6b5k/1/
The value attribute is only used when rendering the initial HTML. After the page load, everything else happens in the Angular Event Loop and therefore you need to do something that event loop can pick up. You can use ng-change for what you are looking to do:
<input type="text" ng-model="test" ng-change="test2=test.toLowerCase();" />
<input type="text" ng-model="test2"">
This happens because {{value}} does not create a binding, it is used for interpolation.
The simplest solution is to use ng-model in both the fields
<div ng-app>
Angular.js:<br>
<input type="text" ng-model="test">
<input type="text" ng-model="test">
</div>
Demo: Fiddle