Create a dynamic ng-model for an input - angularjs

How can I make the ng-model of an input dynamic?
Static ng-model:
<input type="text" ng-model="myModel.firstName" />
Dynamic ng-model:
$scope.myInputs = [{ key: "firstName"}, { key: "lastName" }];
<div ng-repeat="input in myInputs">
<input type="text" ng-model="myModel[input.key]" />
</div>
The myModel[input.key] does not seem to be calculating correctly.

In myInputs[input.key], input.key is not the index. So you cannot access expected value.
You can either
<div ng-repeat="input in myInputs">
<input type="text" ng-model="input.key" />
</div>
Or
<div ng-repeat="input in myInputs track by $index">
<input type="text" ng-model="myInputs[$index].key" />
</div>

Related

AngularJS ng-repeat for input array

I have empty model with cars:
$scope.registration.cars = {
1: {
capacity: '',
count: '',
license: ''
},
2: {
capacity: '',
count: '',
license: ''
}
};
Then I use ng-repeat to generate cars form:
<div class="row row_vehicles" ng-repeat="(key, value) in registration.cars">
<input type="number" name="registration_car_capacity[{{key}}]" ng-model="registration.car[{{key}}].capacity" />
<input type="number" name="registration_car_count[{{key}}]" ng-model="registration.car[{{key}}].count" required />
<input type="text" name="registration_car_license[{{key}}]" ng-model="registration.car[1].license" ng-minlength="7" required />
</div>
But this is not working. How can I insert KEY into ng-model array?
Don't use interpolation operator ({{..}}) inside angular scope.(anything like ng-*), In your case ng-model
<div class="row row_vehicles" ng-repeat="(key, value) in registration.cars">
<input type="number" name="registration_car_capacity[key]" ng-model="registration.car[key].capacity" />
<input type="number" name="registration_car_count[key]" ng-model="registration.car[key].count" required />
<input type="text" name="registration_car_license[key]" ng-model="registration.car[key].license" ng-minlength="7" required />
</div>
You just have to remove interpolation {{}} enclosing the key. You can't use this with angular directives.
<div ng-controller="MyCtrl">
<div class="row row_vehicles" ng-repeat="(key, value) in registration.cars">
<input type="number" name="registration_car_capacity[key]"
ng-model="registration.cars[key].capacity"
/>
<input type="number" name="registration_car_count[key]"
ng-model="registration.cars[key].count"
required />
<input type="text" name="registration_car_license[key]"
ng-model="registration.cars[key].license"
ng-minlength="7" required />
</div>
</div>
Working Fiddle: http://jsfiddle.net/ADukg/12094/

Angularjs - How to compare more than two input values in a form validation

I am having two sets of same input fields. The input value should be unique. So I should show an error message if user repeats in other input variables. Example: Let say if user entered "Hopes School" value in "Option 1" group "Elementary school name 1" input, we should show an error message if user tries to enter "Hopes school" value in other input fields. So looking for help on how we can handle this in angular since I am new to angular. Appreciate your help.
FYI - The logic should apply for school input fields alone. Notes input value can be duplicated.
Plunker link: http://plnkr.co/edit/2sZZiFOLKUS8ewqlbck9?p=preview
<body ng-controller="empCtrl">
<div ng-repeat="school in areas.school">
<div class="form-group">
<label for="areas"></label>
<select name="area{{school.id}}" ng-model="areas.school[$index].type" ng-init="areas.school[$index].type = 'area1'">
<option value="area1" selected="selected">Area 1</option>
<option value="area2">Area 2</option>
</select>
</div>
<div ng-show="areas.school[$index].type == 'area1'">
<div class="form-group">
<label for="elementary">Elementary school name {{school.id}}</label>
<input type="text" name="elementary{{school.id}}" placeholder="elementary school name" ng-model="areas.school[$index].elementary"/>
</div>
<div class="form-group">
<label for="title">Middle school name {{school.id}}</label>
<input type="text" name="middle{{school.id}}" placeholder="middle school name" ng-model="areas.school[$index].middle" />
</div>
<div class="form-group">
<label for="Notes">Notes</label>
<input type="text" name="notes{{school.id}}" placeholder="Notes" ng-model="areas.school[$index].notes" />
</div>
</div>
<div ng-show="areas.school[$index].type == 'area2'">
<div class="form-group">
<label for="elementary">Elementary school name {{school.id}}</label>
<input type="text" name="elementary{{school.id}}" placeholder="elementary school name" ng-model="areas.school[$index].elementary"/>
</div>
<div class="form-group">
<label for="title">Middle school name {{school.id}}</label>
<input type="text" name="middle{{school.id}}" placeholder="middle school name" ng-model="areas.school[$index].middle" />
</div>
</div>
<br/>
</div>
</body>
Angular code(this doesn't have validation logic):
// Code goes here
var employeeApp = angular.module("EmployeeApp",[]);
employeeApp.controller("empCtrl",function($scope){
$scope.areas = {
};
$scope.areas.school = [
{
'id': 1,
'type': ''
},
{
'id': 2,
'type': ''
}
];
});
Pass the modal value of one input box to the ng-pattern of other input box.
<input type='text' name='input1' ng-model = 'model1'/>
<input type='text' name='input2' ng-model = 'model2' ng-pattern='model1'/>
{{input2.$error.pattern}}
First use Angularjs Model option
Section 1 :
<input type="text" nd-model="school1" ng-required="school1==school2"/>
Section 2 :
<input type="text" ng-mode="school2" ng-required="school1==school2"/>
Warning :
<span ng-if="school!=school"> School Names Should be Same in 2 Sections</span>

How to use one model in ng-repeat using AngularJs?

This is my Fiddle.
http://jsfiddle.net/0c5p38dt/1/
In the above fiddle use ng-model in textfield and add save button
<input type="text" ng-model="eachItem.value"/>
<input type="button" value="save" ng-click="save()"/>
and i write code in js file :-
$scope.save=function(){
console.log($scope.data);
};
In the above code first i click add button when i enter data in first textfield(name) that will also effect on second textfield(name). I want to save the data . So how to differentiate these textboxes.
you should use a 'name' attribute in your input fields with angular
$index
on ng-repeat.
in your Fiddle:
<div ng-app>
<div ng-controller="Ctrl">
<div ng-repeat="eachItem in data">
<input type="button" value="add" ng-click="addFields(eachItem)"/>
<label>{{eachItem.label}}</label>
<input type="text" name="eachItem.label[$index]" />
</div>
</div>
</div>
The result would be like:
<input type="text" name="email[1]">
<input type="text" name="email[2]">
<input type="text" name="email[3]">
<input type="text" name="name[1]">
<input type="text" name="name[2]">
I'm not completely sure what you want, but I don't think you want the <input> in an ng-repeat, maybe what you want is in your .html:
<div ng-app>
<div ng-controller="Ctrl">
<label>Name</label>
<input type="text"ng-model="item.name"/>
<label>Email</label>
<input type="text"ng-model="item.email"/>
<input type="button" value="add" ng-click="addFields(item)"/>
<div ng-repeat="item in data">
<div ng-bind="item.name"></div>
<div ng-bind="item.email"></div>
</div>
</div>
</div>
and in your .js:
function Ctrl($scope) {
$scope.data=[];
$scope.addFields = function (item) {
$scope.data.push(item);
};
}
This will give you the inputs once and then keep track (and display) the data from the inputs

$scope.formName.fieldName.$setValidity is not working

I would like to set invalid with angular when firstname is equals to lastname and change the color using styles to red.
http://jsbin.com/japir/2
function RegoController($scope) {
$scope.app = {
firstName: "Saroj"
};
$scope.$watch("app.lastName", function(newVal, oldVal) {
if (!!$scope.app.lastName && !!newVal)
if (angular.lowercase($scope.app.firstName) === angular.lowercase(newVal)) {
debugger;
$scope.form.inputLastName.$setValidity("sameName", false);
}
});
}
<body ng-app>
<div class="container" ng-controller="RegoController">
<div class="col-lg-4">
<form name="form">
<div class="form-group">
<label for="inputFirstName">First Name</label>
<input id="inputFirstName" class="form-control" type="text" ng-model="app.firstName" placeholder="Enter your firstname" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputLastName">Last Name</label>
<input id="inputLastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input id="inputEmail" class="form-control" type="email" ng-model="app.email" placeholder="Enter your email" required />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</form>
{{app}}
</div>
</div>
</body>
The problem is that you are trying to select a form input that has no name; thus making it unable to find the field you are trying to invalidate. Here is a working example:
JSBIN: http://jsbin.com/yozanado/1/
Input field with name:
<input id="inputLastName" name="lastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
Javascript:
$scope.form.lastName.$setValidity("sameName", false);
AngularJS form validation relies on the name of the form and the name of the fields to find the validation models on scope.
For example, if your HTML is:
<form name="form">
<input name="firstName" ng-model="firstName" />
</form>
You will be able to access the validation $error property on scope using the name attributes:
$scope.form.firstName.$error.sameName
To fix the issues you're having, add a name attribute to your input fields.
JSBin Demo

Bind <div> to element of Angular controller

We have a somewhat complicated model on an AngularJS controller:
function controller($scope) {
$scope.model = {
childmodel1: {
childmodel2: {
property1: 'abc',
property2: 3,
property3: 0.5,
property4: 'abc'
}
}
}
}
In the HTML markup, we don't want to repeat the whole access chain everytime we access childmodel2:
<div ng-controller="ctrl">
<div>
<input type="text" ng-model="model.childmodel1.childmodel2.property1" />
<input type="text" ng-model="model.childmodel1.childmodel2.property2" />
<input type="text" ng-model="model.childmodel1.childmodel2.property3" />
<input type="text" ng-model="model.childmodel1.childmodel2.property4" />
</div>
</div>
Is there an AngularJS directive that creates a sub-scope like this:
<div ng-controller="ctrl">
<div ng-unknowndirective="model.childmodel1.childmodel2">
<input type="text" ng-model="property1" />
<input type="text" ng-model="property2" />
<input type="text" ng-model="property3" />
<input type="text" ng-model="property4" />
</div>
</div>
It's the same thing that's done on ng-repeat, but without the repetition :)
We tried ng-scope, ng-controller, ng-model, none of them works this way. Googling didn't yield any results, we don't know the terminology to search for.
Thank you #Ufuk, here's my solution:
mt.directive('subscope', function () {
return {
scope: {
subscope: '='
}
};
});
and
<div ng-controller="ctrl">
<div subscope="model.childmodel1.childmodel2">
<input type="text" ng-model="subscope.property1" />
<input type="text" ng-model="subscope.property2" />
<input type="text" ng-model="subscope.property3" />
<input type="text" ng-model="subscope.property4" />
</div>
</div>
You can use ng-init to suppress the access chain
<div ng-init="childmodel2 = model.childmodel1.childmodel2">
<input type="text" ng-model="childmodel2.property1" />
<input type="text" ng-model="childmodel2.property2" />
<input type="text" ng-model="childmodel2.property3" />
<input type="text" ng-model="childmodel2.property4" />
</div>
It creates alias model. More appropriate you create the alias in your controller like
$scope.childmodel2 = $scope.model.childmodel1.childmodel2 // and remove ng-init from HTML
Demo

Resources