How to add different inputs values into array of objects dynamically in angualrJs - angularjs

I have multiple input fields under different headings:-
<label>User</label>
<input type="text" ng-model="a.arr.username"/>
<input type="text" ng-model="a.arr.userdob"/>
<input type="text" ng-model="a.arr.userpanNo"/>
<label>Employee</label>
<input type="text" ng-model="a.arr.empname"/>
<input type="text" ng-model="a.arr.empdob"/>
<input type="text" ng-model="a.arr.emppanNo"/>
<label>Daily Workers</label>
<input type="text" ng-model="a.arr.dwname"/>
<input type="text" ng-model="a.arr.dwdob"/>
<input type="text" ng-model="a.arr.dwpanNo"/>
I want to save above data in the format:- [{a.arr.username:any value,a.arr.userdob:any value,a.arr.userpanNo:any value},{a.arr.empname:any value,a.arr.empdob:any value,a.arr.emppanNo:any value},{a.arr.dwname:any value,a.arr.dwdob:any value,a.arr.dwpanNo:any value}].
In my directive:-
scope.a.array=[];
var properties = Object.keys(scope.a.arr);
for(var i=0;i<properties.length;i++){
scope.a.array.push({});
scope.a.array[scope.a.array.length - 1][properties[i]] = scope.a.arr[properties[i]];
};
But above code is creating data like this:- [{a.arr.username:any value},{a.arr.userdob:any value},{a.arr.userpanNo:any value},{a.arr.empname:any value},{a.arr.empdob:any value},{a.arr.emppanNo:any value},{a.arr.dwname:any value},{a.arr.dwdob:any value},{a.arr.dwpanNo:any value}]
It is pushing different properties in array instead of combining them. What is the correct way of doing this?

Related

How to populate data from one input box to another when both have different ng-models?

Angularjs newbie here..
I have two input boxes,
<input type="text" class="form-control" ng-model="d.d_oad1">
<input type="text" class="form-control" ng-model="d.c_oad1">
then I have
<input type="text" class="form-control" ng-model="d.d_oad2">
<input type="text" class="form-control" ng-model="d.c_oad2">
<input type="text" class="form-control" ng-model="d.d_oad3">
<input type="text" class="form-control" ng-model="d.c_oad3">
and so on...
I need to populate value from the first input box to the next, while keeping the second input box's update independent. For example, I need to populate data from input box with ng-model d.d_oad1 to d.c_oad1, similarly, d.d_oad2 to d.c_oad2 and so on..
It would have been easy if I could use the same ng-model for both, however that is not possible...
So to begin, whatever gets changed in input1 will be stored in variable1(d.d_oad1) and whatever is changed in input2 will get stored in variable2(d.c_oad2), to create the below functionality needed.
First we define an ng-change which runs whenever the ng-modal value changes (i.e. d.d_oad1) and call a function call copy() and pass the value of variable 1(d.d_oad1) to the function.
<input type="text" class="form-control" ng-model="d.d_oad1" ng-change="copy(d.d_oad1)">
So inside this copy function we can write the functionality needed.
Copy functionality:
$scope.copy = function(val) {
$scope.d.c_oad2 = angular.copy(val);
}
Snippet:
Here the copy function will receive the value of variable1 in the first arguement and assign it to the second arguement.
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.d = {
d_oad1: "",
c_oad1: "",
d_oad2: "",
c_oad2: "",
d_oad3: "",
c_oad3: ""
}
$scope.copy = function(str, val) {
var key = "c_"+str.split("_")[1];
$scope.d[key] = val;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller='MyController' ng-app="myApp">
<input type="text" class="form-control" ng-model="d.d_oad1" ng-change="copy('d.d_oad1', d.d_oad1)"><br>
<input type="text" class="form-control" ng-model="d.c_oad1"><br>
<input type="text" class="form-control" ng-model="d.d_oad2" ng-change="copy('d.d_oad2', d.d_oad2)"><br>
<input type="text" class="form-control" ng-model="d.c_oad2"><br>
<input type="text" class="form-control" ng-model="d.d_oad3" ng-change="copy('d.d_oad3', d.d_oad3)"><br>
<input type="text" class="form-control" ng-model="d.c_oad3">
</div>

Dynamic model with Array object in AngularJS

I am saving my data in below format
$scope.data = {
name:'abc',
Address:[{
Address1:'XXXX',
state:'XXXX',
County:'XXXX'
}]
}
<input type="text" class="form-control" name="Address1" ng-model="data.Address[0][Address1]">
<input type="text" class="form-control" name="state" ng-model="data.Address[1][State]">
<input type="text" class="form-control" name="County" ng-model="data.Address[2][County]">
While retrieving the data I am getting data in below format:
$scope.data = {
name:'abc',
Address:[{
state:'XXXX',
County:'XXXX'
}]
}
Where one of the array objects (Address1) is missing so I am unable to update the form model even if the data is available. Is there any workaround to solve the above issue?
Change your input model to index 0, because that's the array item you are targeting. After that change your reference to the . notation and not using brackets []. You can use the brackets, but make sure to make them strings, like data.Address[0]['Address1']. But it's not necessary here. Also:
<input type="text" name="Address1" ng-model="data.Address[0].Address1">
<input type="text" name="state" ng-model="data.Address[0].state">
<input type="text" name="County" ng-model="data.Address[0].County">
(removed class for simplicity)
(are you using state or State?)

Using protractor to test an angularjs app, how do i keep a reference to one of the rows of element.all when the array changes as I work with it?

I have an ng-repeat which has a new element added to it as soon as the existing "last" element is modified in any way. My protractor test looks something like this:
var emptyPerson = this.people.last() // this gets me the last row of the ng-repeat
emptyPerson.element(by.css('.firstName')).sendKeys('first'); // this sets the firstname correctly but then the app adds a new row to the ng-repeat because of the model change here.
emptyPerson.element(by.css('.lastName')).sendKeys('last'); // this sets the lastname of the new row instead of the row that emptyPerson previously referenced
Is there any way to essentially tell emptyPerson to stick to the same element until we're done with it?
Example HTML before firstname is edited:
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
example after firstname is edited:
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
This is how Protractor works internally. It searches for the element at the time an action is applied on the element. I am afraid you have to handle it "manually" and re-reference the desired repeater item.
To make things a little bit better in terms of coding, I would hide the first interaction with the repeater item part in a function - basically, touching the input for repeater to have one more item, then returning the item before last. Something along the lines:
var MyPageObject = function () {
this.people = element(by.repeater("person in object.People"));
this.touch = function () {
var emptyPerson = this.people.last();
emptyPerson.element(by.css('.firstName')).sendKeys('smth');
var newEmptyPerson = this.people.get(-2); // I think -1 would be the last
emptyPerson.element(by.css('.firstName')).clear();
return newEmptyPerson;
}
this.fillForm = function () {
var emptyPerson = this.touch();
emptyPerson.element(by.css('.firstName')).sendKeys('first');
emptyPerson.element(by.css('.lastName')).sendKeys('last');
}
}
Try saving to a variable before it changes:
var oldLastName = emptyPerson.element(by.css('.lastName'));
emptyPerson.element(by.css('.firstName')).sendKeys('first');
oldLastName.sendKeys('last');
Hope it helps

ng-model convert object to string

Being very new to Angular I have a kinda unusual request.
I have a bunch of input fields
<div class="blurb" ng:repeat="item in fieldData.postData">
<input type="text" class="form-control" ng-model="item.key" />
<input type="text" class="form-control" ng-model="item.operator" />
<input type="text" class="form-control" ng-model="item.value" />
</div>
The values of these fields inturn are bound to another field
<input name="finalVal" type="text" ng-model="fieldData.postData" />
All works fine and I get an object inside finalVal, but I want the object in string format. Is there a way to achieve it without any changes in my controller? The reason being finalVal is basically stored as a string in DB and I cannot modify the data type.
Appreciate the help

AngularJS Math issue

I am trying to do some math with user inputs.
I have this basic objets to start with
$scope.shape =
{id: 1, cx: 0, cy: 0, result: 0}
;
And the user can type the value of cx and cy into fields;
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
I want to multiply the 2 values cx and cy and show the result in another input.
<input type="text" class="form-control" id="A" ng-model="shape.cx * shape.cy">
This is working, I can see the the result in the field but I get an error;
Error: [ngModel:nonassign]
I would also like to asign this result to shape.result.
How can I set the value of shape.result to be shape.cx*shape.cy
See here it could be done like this :
SCENARIO 1 : Result on Button Click : (Procedural Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="button" class="form-control" ng-click="calculate()">
<input type="text" class="form-control" id="A" ng-model="shape.result">
$scope.calculate = function(){
$scope.shape.result = parseInt($scope.shape.cx) * parseInt($scope.shape.cy);
}
SCENARIO 2 : As soon as Value Changes in text boxes : (Direct Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="text" class="form-control" id="A" ng-model="parseInt(shape.cx) * parseInt(shape.cy)">
SCENARIO 3 : Using $watch : (Procedural Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="text" class="form-control" id="A" ng-model="shape.result">
$scope.$watch(function (){
$scope.shape.result = parseInt($scope.shape.cx) * parseInt($scope.shape.cy);
});
Note :
Scenario 3 is using $watch hence it should be not used untill and unless you're in real need of it.
Scenario 1 is best suited to you I think as it will make your concept.
Scenario 2 is a direct approach hence should be used after gaining some knowledge as well as experience(But it's short & best within 3 scenatios). It's a reference from #tapos answer
Thanks & Cheers
Well you need to watch for cy and cx changes and do the calculation when it change.
$scope.$watch('shape.cx', function() {
$scope.shape.result = $scope.shape.cx * $scope.shape.cy;
});
Example fiddle: http://jsfiddle.net/ccmf07k2/
Every language input field is string when a user enter any number in text box it is string
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
so you need some work in your result box ix
<input type="text" class="form-control" id="A" ng-model="parseInt(shape.cx) * parseInt(shape.cy)">
then you get your appropriate result

Resources