AngularJS : ng-model not working in multiple drop down - angularjs

I am trying to create dynamic rows based on button click. The rows have drop down boxes. The issue is when I add new row and select an option in the new row the options which I selected in previous rows are also changing, I mean the previous rows options are not binding properly.
My HTML code :
<div id="features" ng-controller="featuresCtrl">
<br>
<div class="row">
<div class="form-group col-md-6">
<table cellpadding="15" cellspacing="10">
<thead>
<tr>
<th style="text-align: center;">Feature</th>
<th style="text-align: center;">Type</th>
<th style="text-align: center;">Value</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr></tr>
<tr ng-repeat="r in rows">
<td>
<select ng-model="r.data.model" ng-options="option.name for option in data.availableOptions"
ng-change="getValues(r.data.model.name)">
<option value="">Select Feature</option>
</select>
</td>
<td>
<select ng-model="r.updateData.model" ng-options="option.name for option in updateData.availableOptions"
ng-change="getBinSet(r.updateData.model.name)">
<option value="">Select Type</option>
</select>
</td>
<td>
<select ng-model="r.binData.model" ng-options="option.name for option in binData.availableOptions">
<option value="">Select Value</option>
</select>
</td>
<td ng-if="showAdd">
<div class="text-center">
<button ng-click="addRow()">Add</button>
</div>
</td>
<td ng-if="showAdd">
<div class="text-center">
<button ng-click="remove($index)">Remove</button>
</div>
</td>
</tr>
<tr>
<td></td>
<td style="align-self: center;">
<button style="align-self: center" ng-click="submitForm(rows)">Submit</button>
</td>
<td></td>
</tr>
</tbody>
</table>
<br>
</div>
My angular JS code :
'use strict';
var testControllers = angular.module('testControllers');
testControllers.controller('featuresCtrl', ['$scope','$route','$filter', '$http', '$location','$window','$timeout', 'NgTableParams',
function($scope, $route, $filter, $http, $location, $window, $timeout, NgTableParams) {
$scope.rows = [{}];
$scope.nrows = [];
$scope.showAdd = false;
$scope.addRow = function() {
$scope.rows.push({
});
};
$scope.remove = function(index) {
$scope.rows.splice(index, 1);
};
$scope.submitForm = function(rows) {
console.log("rows", rows);
};
$scope.data = {
model: null,
availableOptions: [
{ name: 'TestA'},
{ name: 'TestB'},
{ name: 'TestC'},
{ name: 'TestD'}
]
};
$scope.getValues = function (featureType) {
console.log("getValues", featureType);
$scope.showAdd = false;
if (featureType != null) {
$http.get('/getPropensityValues.do', {params: {'featureType': featureType}}).success(function (data) {
var test = [];
angular.forEach(data, function (item) {
test.push({name: item});
});
$scope.updateData = {
model: null,
availableOptions : test
};
});
}
};
$scope.getBinSet = function (featureType) {
console.log("getBinSet", featureType);
$scope.showAdd = true;
if (featureType != null) {
$scope.binData = {
model: null,
availableOptions: [
{name: '1'},
{name: '2'},
{name: '3'},
{name: '4'},
{name: '5'},
{name: '6_10'},
{name: '10_15'},
{name: '16_20'},
{name: '21_25'},
{name: '26_30'},
{name: '31_35'},
{name: '36_40'},
{name: '41_45'},
{name: '46_50'},
{name: '>50'}
]
};
}
};
}]);
Can some one tell me what I am doing wrong here ? I tried with another example - https://plnkr.co/edit/Jw5RkU3mLuGBpqKsq7RH?p=preview
Even here I am facing same issue when selecting the 2nd row 1st row also changing. Is it wrong to use r.data.model to bind each row's values ?

I updated your plunker to work:
https://plnkr.co/edit/4sJHHaJPEuYiaHjdnFBp?p=preview
You weren't defining what the model was when you were redefining the options menus (side note: you should leverage underscore.js's difference function within a filter to create the appropriate display options dynamically)
Anyway, in your addRow() function, I changed it from this:
if(val=== 'TestB') {
$scope.data1 = {
model: null,
availableOptions: [
{ name: 'TestA'},
{ name: 'TestC'},
{ name: 'TestD'}
]
};
}
to this:
if(val=== 'TestB') {
$scope.data1 = {
model: 'TestB',
availableOptions: [
{ name: 'TestA'},
{ name: 'TestC'},
{ name: 'TestD'}
]
};
}
Let me know if this helps
UPDATE:
I recreated the functionality from scratch because I think you were overthinking things. All that is needed here is very simple ng-repeat, ng-options, and ng-model bindings.
<tr ng-repeat="r in rows track by $index">
<td>
<select ng-model="r.name"
ng-options="option.name as option.name for option
in availableOptions">
<option value="">Select Value</option>
</select>
</td>
<td>
<input type="button" ng-click="addRow()" value="Add">
</td>
<td>
<input type="button" ng-click="deleteRow($index)"
value="Delete">
</td>
</tr>
and for the angular
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.rows = [{name:""}];
$scope.addRow = function(){
$scope.rows.push({name:""});
}
$scope.availableOptions = [
{ name: 'TestA'},
{ name: 'TestB'},
{ name: 'TestC'},
{ name: 'TestD'}
];
$scope.deleteRow = function(index){
$scope.rows.splice(index,1);
}
});
I didn't throw in the difference thing yet, but it should be easy.

Related

Push empty row with input field using angularjs

I have one table which have edit, delete and add options. My problem is when I click on add button want to add row with empty input fields. I have write below code for this. What should I do to add empty row with empty input values.
My code
<div ng-controller="AppKeysCtrl">
<button ng-click="add()">
Add
</button>
<table class="table table-hover mytable">
<thead>
<tr>
<th></th>
<th>Created</th>
<th>App Key</th>
<th>Name</th>
<th>Level</th>
http://jsfiddle.net/Thw8n/155/#update <th>Active</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="entry in appkeys" data-ng-class="{danger:!entry.active}">
<td>{{$index + 1}}</td>
<td>{{entry.timestamp | date:'mediumDate'}}</td>
<td>{{entry.appkey}}</td>
<td>
<span data-ng-hide="editMode">{{entry.name}}</span>
<input type="text" data-ng-show="editMode" data-ng-model="entry.name" data-ng-required />
</td>
<td>
<span data-ng-hide="editMode">{{entry.level}}</span>
<select class="form-control" name="entry.level" data-ng-model="entry.level" data-ng-show="editMode">
<option value="3">3 - Developer Access - [Temporary]</option>
<option value="2">2 - Standard Tool Access - [Default]</option>
<option value="1">1 - Administrative Access - [Admin Section Only]</option>
</select>
</td>
<td>
<span data-ng-hide="editMode">{{entry.active && 'Active' || 'Inactive'}}</span>
<select class="form-control" name="entry.active" data-ng-model="entry.active" data-ng-show="editMode">
<option value="true">Active</option>
<option value="false">Inactive</option>
</select>
</td>
<td>
<button type="submit" data-ng-hide="editMode" data-ng-click="editMode = true; editAppKey(entry)" class="btn btn-default">Edit</button>
<button type="submit" data-ng-show="editMode" data-ng-click="editMode = false" class="btn btn-default">Save</button>
<button type="submit" data-ng-show="editMode" data-ng-click="editMode = false; cancel($index)" class="btn btn-default">Cancel</button>
</td>
</tr>
</tbody>
</table>
<pre>newField: {{newField|json}}</pre></br></br>
<pre>appkeys: {{appkeys|json}}</pre>
</div>
app = angular.module("formDemo", []);
function AppKeysCtrl($scope, $http, $location) {
var tmpDate = new Date();
$scope.newField = [];
$scope.editing = false;
$scope.appkeys = [
{ "appkey" : "0123456789", "name" : "My new app key", "created" : tmpDate },
{ "appkey" : "abcdefghij", "name" : "Someone elses app key", "created" : tmpDate }
];
$scope.editAppKey = function(field) {
$scope.editing = $scope.appkeys.indexOf(field);
$scope.newField[$scope.editing] = angular.copy(field);
}
$scope.saveField = function(index) {
//if ($scope.editing !== false) {
$scope.appkeys[$scope.editing] = $scope.newField;
//$scope.editing = false;
//}
};
$scope.cancel = function(index) {
//if ($scope.editing !== false) {
$scope.appkeys[index] = $scope.newField[index];
$scope.editing = false;
//}
};
$scope.add = function () {
var entry = {};
//$scope.goals.push(goal);
$scope.appkeys.push(entry);
};
}
angular.element(document).ready(function() {
angular.bootstrap(document, ["formDemo"]);
});
I have problem in this that when I click on add empty row is adding which have form fields with ng-hide attribute. I want to add row dynamically with new input boxes for each column. What should I do for this? Please help.
It's quite simple. You need to push an object with blank value into your array.
Below is the code:
Controller
$scope.add = function () {
$scope.appkeys.push({appkey : '', name : '', created : '' });
};
The above code will only add a row. I have updated your JSFiddle for your desired output.
Please go through with the given link.
http://jsfiddle.net/Thw8n/570/
You need to paste the following code:
$scope.add = function () {
$scope.appkeys.push({appkey : '', name : '', created : '' });
};
You can push object with empty properties in your appkey array:
var tempObject = {
"appkey":"",
"name":"",
"created":""
};
$scope.appkeys.push(tempObject);

What triggers a function call in other column when ngmodel changes in first column?

Consider the snippet:
JS
var mod = angular.module('module', []);
mod.controller('controller', function($scope) {
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: {
name: 'aSubItem'
}
}, {
id: 2,
label: 'bLabel',
subItem: {
name: 'bSubItem'
}
}]
$scope.getValue = function(ngmodel) {
// some code goes here...
}
});
HTML
<body ng-controller='controller'>
<div>
<table>
<tr ng-repeat='count in counter'> // 5 times
<td>
<select ng-options="item.id as item.label for item in items"
ng-model="selected[$index]">
</select>
</td>
<td>
{{getValue(1)}}
</td>
<td>
</td>
</tr>
</table>
</div>
</body>
As soon as I select some value from the dropdown (select tag) in the first column, I notice that the function in the second column is triggered? What is the reason for this? What exactly is happening behind the scenes?
The reason is you are doing it inside ng-repeat
<tr ng-repeat = 'count in counter'>
You need to pass the object on the controller, in order to do some action on the same.
{{getValue(obj)}}

How to use an array on ng-model

This is my code http://plnkr.co/edit/oxtojjEPwkKng9iKkc14?p=preview
And I want to save object of sport and punctuation in an array, if there are one or more sports selected save it in the array like this:
likes[
{sport: 'futball', points: 1}, {sport: 'tennis', points: 1}
]
thanks!
You have to keep practicing your English a little bit more (you can ask me on the comment section in spanish if you are strugling)
I think what you are trying to do is to have a single select to be able to choose the sport and score,
Html:
<body ng-app="myapp">
<div class="main-container" ng-controller="main" ng-init="darr.dept=dept2">
<div class="client-area">
<label fo.table-container tabler="txt">Score</label>
<input type="text" id="name-txt" placeholder="Assign the score" ng-model="name">
<br />
Sport
<select ng-model="dept" ng-options="deptOpt.value as deptOpt.name for deptOpt in deptList"></select>
<br />
<button ng-click="add()">Add Item</button>
<table id="tab">
<thead>
<tr id="trow">
<th>Score</th>
<th>Sport</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="ar in arr">
<td>{{ar.name}}</td>
<td>{{ar.dept}}</td>
<td>
<button ng-click="del($index)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
js:
var app = angular.module("myapp", []);
app.controller('main', function ($scope) {
$scope.arr = [];
$scope.deptList = [{
name: 'Football',
value: 'football'
}, {
name: 'Tennis',
value: 'Tennis'
}, {
name: 'Baseball',
value: 'baseball'
}];
$scope.dept = "football";
$scope.name = "";
$scope.add = function () {
this.arr.push({
name: this.name,
dept: this.dept
});
};
$scope.del = function (ind) {
this.arr = this.arr.splice(ind, 1);
};
$scope.editStudent = function(student) {
console.log(student);
};
});
https://jsfiddle.net/azweig/v5kbsudy/1

Angular angucomplete-alt cannot populate the price

var app = angular.module('app', ["angucomplete-alt"]);
app.controller('MainController', function($scope) {
$scope.countries = [
{name: 'Hosting 1', code: '100.00'},
{name: 'Hosting 2', code: '200.00'},
{name: 'Hosting 3', code: '300.00'},
{name: 'Hosting 4', code: '400.00'},
{name: 'Hosting 5', code: '500.00'},
{name: 'Hosting 6', code: '600.00'},
];
$scope.countrySelected = function(selected) {
//$scope.invoice.item.lol = 1;
window.alert('You have selected ' + selected.title);
};
$scope.taxesData = {
singleSelect: null,
availableOptions: [
{id: '6.50', name: '6,5%'},
{id: '16.00', name: '16%'},
{id: '23.00', name: '23%'}
],
selectedOption: {id: '23.00', name: '23%'}
};
$scope.invoice = {
items: [{
description: '',
}]
};
$scope.addItem = function() {
$scope.invoice.items.push({
description: '',
price: 10.99,
});
};
$scope.removeItem = function(index) {
$scope.invoice.items.splice(index, 1);
};
$scope.total = function() {
var total = 0;
angular.forEach($scope.invoice.items, function(item) {
total += item.qty * item.price;
})
return total;
};
$scope.taxtotal = function() {
var taxtotal = 0;
angular.forEach($scope.invoice.items, function(item) {
taxtotal += item.qty * item.price * item.taxesData.repeatSelect * 0.01;
})
return taxtotal;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!--ng-controller="MainController"-->
<div ng-app="app"><div ng-controller="MainController">
<table class="table table-condensed table-striped">
<tr>
<th>Product Name</th>
<th>Item Price</th>
<th>Qty</th>
<th>Tax Rate</th>
<th>Line Total</th>
<th>Line Taxes Total</th>
<th></th>
</tr>
<tr ng:repeat="item in invoice.items">
<td angucomplete-alt id="ex1" placeholder="Search countries" maxlength="50" pause="100" selected-object="selectedCountry" local-data="countries" search-fields="name" title-field="name" minlength="1" input-class="form-control form-control-small" match-class="highlight"></td>
<td><input type="text" value="{{selectedCountry.originalObject.code}}"></td>
<td><input type="text" ng:model="item.qty" ng:required class="input-mini"></td>
<!--<td><input type="text" ng:model="item.taxRate"class="input-small"></td>-->
<td>
<select name="repeatSelect" ng-model="item.taxesData.repeatSelect">
<option ng-repeat="option in taxesData.availableOptions" value="{{option.id}}">{{option.name}}</option>
</select>
</td>
<td>{{item.qty * item.mama | currency}}</td>
<td>{{item.qty * itme.mama * item.taxesData.repeatSelect * 0.01 | currency}}</td>
<td>
[<a href ng:click="removeItem($index)">X</a>]
</td>
</tr>
<tr>
<td><a href ng:click="addItem()" class="btn btn-small">add item</a></td>
<td></td>
<td>Totals:</td>
<td></td>
<td>{{total() | currency}}</td>
<td>{{taxtotal() | currency}}</td>
</tr>
</table>
</div>
</div></div>
As you can see in this jfiddle I am using angular with angucomplete-alt plugin to manage an order form.
I have a scope "countries" which feed the autocomplete box.
Now i am trying to ,
when choosing a country (product :P) i want the field Item Price to feeded with the correct value (e.g. if i select hosting 1, the Item price must completed with 100.00 value.
The problem is that :
1) If I set ng:model to this field (because I want to use the price for the totals) the field does not completed.
2) If I set just value="{{selectedCountry.originalObject.code}}, the field completed but I haven't a ng:object to use it for the totals.
It should be working if you set ng:model as the following, for your Price input field:
<input type="text" ng:model="selectedCountry.originalObject.code">
See working fiddle

angularjs ng-repeat inside ng-repeat,the inside array can't update

I come from China,my English very poor,so I do a demo.how can I update array inside ng-repeat?
The HTML:
<body ng-app="main" ng-controller="DemoCtrl">
<table ng-table class="table">
<tr ng-repeat="user in users">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td>
{{user.spms|json}}
<div ng-repeat="u in user.spms">
<span ng-bind="u"></span>
<input type="text" ng-model="u" ng-change='updateArray($parent.$index, $index, u)'>
</div>
</td>
</tr>
</table>
</body>
The JS:
var app = angular.module('main', []).
controller('DemoCtrl', function($scope) {
$scope.users = [{
name: "Moroni",
age: 50,
spms: [
6135.7678,
504.4589,
2879.164,
669.7447
]
},
{
name: "seven",
age: 30,
spms: [
34135.7678,
5034.42589,
22879.1264,
63469.72447
]
}
];
$scope.updateArray = function(parent, index, u) {
$scope.users[parent].spms[index] = u * 1; // multiply by one to keep the value a Number
}
})
There are issues here are every update is changing the scope, so you can only change one time them click then change - so I would recommend add a update values button and implementing more or less the same logic to update the array values.
DEMO

Resources