How to make ng-model work with ng-value? - angularjs

I have this input:
<input type="number" id="totWeight" ng-model="totWeight" ng-value="getTotWeight()" />
which value is calculated based on other fields, but it can also be inserted manually via the input field.
The problem is that when it's calculated, ng-model remains empty, so I tried to assign the calculated value if (!$scope.totWeight) when I send the data to the server, which is not optimal. Further if I insert a value via the input field and then change the other fields mentioned above which trigger the getTotWeight() function, the $scope.totWeight has a value so it won't get updated with the above if (!$scope.totWeight).
Sorry, I don't know how to explain it. Hopefully someone can help me with that.

The purpose of the NgValue directive is as the docs says
It is mainly used on input[radio] and option elements, so that when
the element is selected, the ngModel of that element (or its select
parent element) is set to the bound value.
So when using input type "number" you should not use it as it's value actually will be in the NgModel instead.
If you want to trigger an event when the input is change, key is press etc you should use the NgChange, NgKeypress etc instead to trigger the function.
The value will be keept in the NgModel for all situations.

Related

Incompatibility between ng-value and ng-model [duplicate]

As far as i understood ng-model sets the value for that particular element in which the model is been assigned.
given that how is ng-value different from ng-model?
It works in conjunction with ng-model; for radios and selects, it is the value that is set to the ng-model when that item is selected. Use it as an alternative to the 'value' attribute of the element, which will always store a string value to the associated ng-model.
In the context of radio buttons, it allows you to use non-string values. For instance, if you have the radio buttons 'Yes' and 'No' (or equivalent) with values 'true' and 'false' - if you use 'value', the values stored into your ng-model will become strings. If you use 'ng-value', they will remain booleans.
In the context of a select element, however, note that the ng-value will still always be treated as a string. To set non-string values for a select, use ngOptions.
Simple Description
ng-model
Is used for two way binding of variable that can be available on scope as well as on html.
which has $modelValue(value reside in actual scope) & $viewValue (value displayed on view).
If you mentioned on form with name attribute then angular internally creates validation attributes for it like $error, $valid, $invalid etc.
Eg.
<input type="text/checkbox/radio/number/tel/email/url" ng-model="test"/>
ng-value
Is used to assign value to respective ng-model value like input,
select & textarea(same can be done by using ng-init)
ng-value does provide good binding if your are setting ng-model value through ajax while writing value attribute doesn't support it
Basically meant to use for radio & option tag while creating select options dynamically.
It can only have string value it, it doesn't support object value.
HTML
<input
[ng-value="string"]>
...
</input>
OR
<select ng-model="selected">
<option ng-value="option.value" ng-repeat="option in options">
{{option.name}}
</option>
</select>
...
A good use for ng-value in input fields is if you want to bind to a variable, but based on another variable's value. Example:
<h1>The code is {{model.code}}.</h1>
<p>Set the new code: <input type="text" ng-bind="model.code" /></p>
When the user types in the input, the value in the title will be updated. If you don't want this, you can modify to:
<input type="text" ng-value="model.code" ng-bind="model.theNewCode" />
theNewCode will be updated, but code will remain untouched.
According to the https://docs.angularjs.org/api/ng/directive/ngValue, ngValue takes an "angular expression, whose value will be bound to the value attribute of the input element".
So, when you use ng-value="hard", it is interpreted as an expression and the value is bound to $scope.hard (which is probably undefined).
ngValue is useful for evaluating expressions - it has no advantage over value for setting hard-coded values. Yet, if you want to hard-code a value with ngValue, you must enclose it in '':
ng-value="'hard'"
ng-model is intended to be put inside of form elements and has two-way data binding ($scope --> view and view --> $scope) e.g. <input ng-model="val"/>.
or you can say The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.
The documentation clearly states that ng-value should not be used when doing two-way binding with ng-model.
From the Docs:
ngValue
Binds the given expression to the value of the element.
It can also be used to achieve one-way binding of a given expression to an input element such as an input[text] or a textarea, when that element does not use ngModel.
— AngularJS ng-value Directive API Reference
Instead, initialize the value from the controller:

AngularJS - independent input for same ng-model

I am really new to AngularJS so my question might be a bit silly. I am trying to solve a problem where I have two input fields which uses the same ng-model and I'd like the put value in one field not have the other input field displaying that value. I know it is desired that when I type in some value in one of the input fields it automatically reflects in the other. I wonder if there's any work around so that when I put value in one input, it does not show up in the other input field.
Here's how you can achieve this:
<input ng-model="foo">
<input value="{{::foo}}">
The second inputs' value will be set to the initial value of foo but it's one time bound. Changing foo after this will no longer affect it.
Furthermore, if you want the second input to update the first but the first not to update the second, you could go:
<input ng-model="foo">
<input ng-init="bar=foo"
ng-model="bar"
on-change="updateFoo()">
// And, inside controller:
$scope.updateFoo = function() {
$scope.foo = $scope.bar;
};

ngChange on input changed by a select

I have a simple select input field where the user can choose an option:
<select class="form-control" id="calc-masterbatchCode"
ng-options="masterbatch as masterbatch.code for masterbatch in masterbatches"
ng-model="$parent.materialTAB.selectedMasterbatch">
</select>
as you can see the selectedMasterbatchobject is stored in a parent controller.
Then i have a disabled input field in the order to show the property of the selectedMasterBatch:
<input type="text" class="form-control" id="calc-masterbatchPercentage"
ng-model="$parent.materialTAB.selectedMasterbatch.percentage"
ng-change="onMasterbPercentageChange()">
It works, but the problem is the ngChangedirective:
because it doesn't fire the onMasterbPercentageChange function when the user select another masterbatch.
The only way to fire that function is to type something manually into the calc-masterbatchParcentageinput field.
My goal is:
the user select a masterbatch, then he can see the masterbatch's property (the percentage) into the disabled input field and, when this one change, the onMasterbPercentageChangefunction is fired.
ngChange directive doesn't work on disable/readonly inputs, because it's only evaluated when a change in the input value causes a new value to be committed to the model. So, since you're changing the value programmatically and not typing anything to this model, it doesn't calls ngChange
Here is more one part extracted from docs:
ngChange will not be evaluated:
if the value returned from the $parsers transformation pipeline has not changed
if the input has continued to be invalid since the model will stay null
if the model is changed programmatically and not by a change to the input value
So, to achieve what you want you must move your ng-change to your <select>.
I hope it helps.

ng-model preventing ng-value to be displayed

I'm pretty new to angular world and I have an issue with it.
I'm working with ejs too.
I have an input that I want to fill (value) with an ng-model.
The problem is my model is empty while the user doesn't specify a value.
I want to display a default value when my model is empty. This default value is sending by the ejs (server side). Doing that, I can't set a default value in my controller.
To do so I wrote the following :
<input type="text" ng-model="owner_adress" ng-value="'{{owner_adress || '<%=user.owner_adress%>'}}'"/>
If I look into my code, I can see the value is okay (ejs result when my model is empty, my model value otherwise) but the value is not displayed in my input (ie the user can't see it).
I looked for a work around (ng-cloak was fine but I can't use it in my input field).
Any clue would be nice !
Use ngInit directive instead. If owner_adress is defined in controller it will be used, otherwise it will default to serverside rendered value:
<input ng-model="owner_adress" type="text"
ng-init="owner_adress = owner_adress || '<%=user.owner_adress%>'"/>

AngularJS: Setting selected option in dropdown

I'm assigning an array of 'types' to a dropdown. When a user selects a value in the dropdown, I save it off to a cookie.
The code where I'm updating the ng-model:
$scope.typeItem = $cookieStore.get('typeItem');
This is the dropdown itself:
<select class="transmission-option-width" ng-model="typeItem"
ng-options="t as t.Type for t in transmissionTypes" ng-change="update()"></select>
I set a break point, and $scope.typeItem has a value, but the select is not being set. Any idea what I'm doing wrong here?
The object you're getting back from the cookie store...
$scope.typeItem = $cookieStore.get('typeItem');
while it might have the same properties as one of the items in $scope.transmissionTypes, it's actually an entirely different object. Because angular does the comparison by reference, it can't find a matching object in $scope.transmissionTypes and the dropdown is not set.
Is t.Type a numeric value? That might prevent angular from treating the selected value as equal to the option value.
Might be easiest to convert $scope.typeItem to a numeric value after getting it from the $cookieStore.
i think you misted this part of the docs
Note: ngModel compares by reference, not value. This is important when binding to an array of objects. See an example in this jsfiddle.
try to traverse your array and assign the element in the array holding the same value to your model variable

Resources