map bind with ng-model not updating data - angularjs

I called REST service which gives me an Object contains a map.
Map in java looks like Map
Following is my js
$scope.marks = {};
//get data from rest
StudentService.query().$promise.then(function(data)
{
$scope.students = data;
for(var i=0;i<$scope.students.length;i++){
var obj = $scope.students[i];
//marks (key=studentName, value=mark in decimal)
$scope.marks[obj["studentName"]]=0.0;
}
following is my html
<div class="row" ng-repeat="(key,value) in marks">
<input type="text" class="form-control" ng-model="key" disabled>
{{marks[key]}} <!-- Here it is not updating value from above model-->
<input type="number" class="form-control" ng-model="value">
</div>
When I update value in textfield it is not update value displayed just below textfiled ie {{marks[key]}} is not showing updated value. Please correct me if wrong. Thank you :)

What you are passing to the ng-model is just a string, which is immutable. You need to define the ng-model like this:
<input type="number" class="form-control" ng-model="marks[key]">
angular.module('app', [])
.controller('Ctrl', function($scope) {
$scope.marks = {
mark1: 1,
mark2: 2,
mark3: 3
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl">
<div class="row" ng-repeat="(key,value) in marks">
<input type="text" class="form-control" ng-model="key" disabled>{{marks[key]}}
<!-- Here it is not updating value from above model-->
<input type="number" class="form-control" ng-model="marks[key]">
</div>
</div>

Related

Angular JS dropdown list select "Others" option and Others input become mandatory

I am trying to add a dropdown list with "Others" option. If user select "Others", Others (Please specify) input box will become Mandatory. How should I validate this case? Right now I added Javascirpt code to valid this. Is there anyway to do this like "Please specify other reason."?
<form name="myForm">
<div ng-app="myApp" ng-controller="myCtrl">
Reason : <select ng-model="reason" ng-options="x for x in names" required></select> <span ng-show="myForm.reason.untouched">The reason is required.</span>
<p>Others (specify): <input type="text" ng-model="others"></p>
</div>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = ["reason1", "reason2", "reason3","Others"];
$scope.addItem = function () {
if ($scope.reason == "Others" && !$scope.others)
{
window.alert("Please specify others");
}
if($scope.others && $scope.reason!='Others')
{
window.alert("Please select reason others");
}
});
</script>
Angular has an ng-required property that allows you to set it conditionally.
<form name="myForm">
<div ng-app="myApp" ng-controller="myCtrl">
Reason : <select ng-model="reason" ng-options="x for x in names" required>
</select> <span ng-show="myForm.reason.untouched">The reason is required.
</span>
<p>Others (specify): <input type="text" ng-model="others" ng-required="reason == 'Others'"></p>
</div>
</form>

Multiplying in Angular.js

I'm an Angular.js noob and I want to multiply two values get that sum of those values and then multiply the sum buy another value.
I want to input a value:
<input type="text" ng-model="averageSalary">
then get that result, then be able to enter another value:
<input class="input input-sm" type="text" ng-model="benefitsAt">
get the the sum of those to values and multiply that by:
<input class=" input input-sm" type="text" ng-model="occupancy">
I hope this helps, I tried to explain it the best that I could
You just need to add something that outputs the display:
<span>{{(averageSalary + benefitsAt) * occupancy}}</span>
You can or the result with zero to eliminate displaying null when the user hasn't entered anything:
<span>{{(averageSalary + benefitsAt) * occupancy || 0}}</span>
HTML ...
<div ng-app="myapp" ng-controller="MyController">
<form>
<input type="text" ng-model="averageSalary">
<input class="input input-sm" type="text" ng-model="benefitsAt">
<input class=" input input-sm" type="text" ng-model="occupancy">
</form>
<span ng-bind="getMySum()"></span>
</div>
CONTROLLER ...
angular.module("myapp").controller('MyController', ['$scope', function($scope) {
$scope.getMySum = function() {
return $scope.averageSalary * $scope.benefitsAt * $scope.occupancy;
};
}]);
I havent tested this code - and I would use the Controller As sytax - but this seems pretty much what you want
This code below should work and run for you.
angular.module('myApp', [])
.controller('myController', function($scope) {
$scope.averageSalary = 55000;
$scope.benefitsAt = .02;
$scope.$watch('averageSalary + benefitsAt', function() {
$scope.occupancy = $scope.averageSalary * $scope.benefitsAt;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
Average Salary
<input type="text" ng-model="averageSalary"><br/>
Benefits
<input class="input input-sm" type="text" ng-model="benefitsAt"><br/>
Occupancy
<input class=" input input-sm" type="text" ng-model="occupancy"><br/>
</div>

angular removes ng-model variable if ng-required is true

as in the title.. how to prevent such operations to happen? Here is a link to the official site, see the example. The variable user.name is bound to the first input userName and if the input is empty the object user.name is removed. How can I disable this functionality of angularjs?
Try ng-model-options="{allowInvalid: true}" to update the model even for invalid entries.
<input ng-model="user.name" required ng-model-options="{allowInvalid: true}">
You've got 2 option
remove required from input tag it allows you to send back empty string to your backend
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
$scope.params = {
user: "John"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<input name="userName" ng-model="params.user" />
<hr/>
<pre>{{params| json}}</pre>
</div>
Option two validate your form before you send it to backend.
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
$scope.user = {
name: "John"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<form name="someForm">
<input name="userName" ng-model="user.name" required name="userName" />
<span ng-show="someForm.userName.$error.required">User Name required</span>
<br/>{{user | json}}
<br/>
<button type="submit" ng-disabled="someForm.$invalid">Submit</button>
</form>
</div>

How to get data from ngform in angularjs?

HTML:
<div ng-controller="TestController" >
<form name="test_form" ng-submit="submit()">
<input type="text" name="some_name" ng-model="form_data.some_name" required>
<ng-form ng-repeat="key in keys" name="keyForm">
<input type="text" name="data_input" ng-model="form_data.data_input" required>
</ng-form>
<a ng-click="addKey()">NEW KEY</a>
</form>
</div>
JS:
app.controller('TestController', function TestController($scope){
$scope.keys = [];
$scope.addKey = function() {
$scope.keys.push({});
}
$scope.submit = function() {
console.log($scope);
}
});
In submit function I can get the value of "some_name" input:
$scope.submit = function() {
console.log($scope.form_data.some_name);
}
But I can't get the values of "data_input" inputs (they are inside ngform tag). How to do that?
(ngform tag is using for ability to validate each new added input separately)
Each input inside the ng-repeat needs its own unique ng-model property -- they all can't use form_data.data_input. Here is one way to solve your problem:
<ng-form ng-repeat="key in keys" name="keyForm">
<input type="text" name="data_input" ng-model="key.data" required>
</ng-form>
$scope.addKey = function () {
$scope.keys.push({ data: ''});
}
Fiddle.
See also https://stackoverflow.com/a/14379763/215945

AngularJS - Trigger when radio button is selected

I searched and tried many ng-xxxx kind of options but couldn't find the one..
I just want to call some function in the controller when radio button is selected.
So it might be similar to following..(Of course, below code is not working)
<input type="radio" ng-model="value" value="one" ng-click="checkStuff()"/>
Is there any way to achieve what I want?
There are at least 2 different methods of invoking functions on radio button selection:
1) Using ng-change directive:
<input type="radio" ng-model="value" value="foo" ng-change='newValue(value)'>
and then, in a controller:
$scope.newValue = function(value) {
console.log(value);
}
Here is the jsFiddle: http://jsfiddle.net/ZPcSe/5/
2) Watching the model for changes. This doesn't require anything special on the input level:
<input type="radio" ng-model="value" value="foo">
but in a controller one would have:
$scope.$watch('value', function(value) {
console.log(value);
});
And the jsFiddle: http://jsfiddle.net/vDTRp/2/
Knowing more about your the use case would help to propose an adequate solution.
Should use ngChange instead of ngClick if trigger source is not from click.
Is the below what you want ? what exactly doesn't work in your case ?
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.value = "none" ;
$scope.isChecked = false;
$scope.checkStuff = function () {
$scope.isChecked = !$scope.isChecked;
}
}
<div ng-controller="MyCtrl">
<input type="radio" ng-model="value" value="one" ng-change="checkStuff()" />
<span> {{value}} isCheck:{{isChecked}} </span>
</div>
In newer versions of angular (I'm using 1.3) you can basically set the model and the value and the double binding do all the work this example works like a charm:
angular.module('radioExample', []).controller('ExampleController', ['$scope', function($scope) {
$scope.color = {
name: 'blue'
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<html>
<body ng-app="radioExample">
<form name="myForm" ng-controller="ExampleController">
<input type="radio" ng-model="color.name" value="red"> Red <br/>
<input type="radio" ng-model="color.name" value="green"> Green <br/>
<input type="radio" ng-model="color.name" value="blue"> Blue <br/>
<tt>color = {{color.name}}</tt><br/>
</form>
</body>
</html>
For dynamic values!
<div class="col-md-4" ng-repeat="(k, v) in tiposAcesso">
<label class="control-label">
<input type="radio" name="tipoAcesso" ng-model="userLogin.tipoAcesso" value="{{k}}" ng-change="changeTipoAcesso(k)" />
<span ng-bind="v"></span>
</label>
</div>
in controller
$scope.changeTipoAcesso = function(value) {
console.log(value);
};
Another approach is using Object.defineProperty to set valueas a getter setter property in the controller scope, then each change on the value property will trigger a function specified in the setter:
The HTML file:
<input type="radio" ng-model="value" value="one"/>
<input type="radio" ng-model="value" value="two"/>
<input type="radio" ng-model="value" value="three"/>
The javascript file:
var _value = null;
Object.defineProperty($scope, 'value', {
get: function () {
return _value;
},
set: function (value) {
_value = value;
someFunction();
}
});
see this plunker for the implementation
i prefer to use ng-value with ng-if,
[ng-value] will handle trigger changes
<input type="radio" name="isStudent" ng-model="isStudent" ng-value="true" />
//to show and hide input by removing it from the DOM, that's make me secure from malicious data
<input type="text" ng-if="isStudent" name="textForStudent" ng-model="job">
<form name="myForm" ng-submit="submitForm()">
<label data-ng-repeat="i in [1,2,3]"><input type="radio" name="test" ng-model="$parent.radioValue" value="{{i}}"/>{{i}}</label>
<div>currently selected: {{radioValue}}</div>
<button type="submit">Submit</button>
</form>

Resources