Angular ng-options object linked to ng-repeat object - angularjs

I have a problem with angular, using ng-options on a select tag, where the default selected element should be determined by a property in "company" from the ng-repeat element.
Look at this code:
<tr data-ng-repeat="company in companies">
<td><input data-ng-model="company.Name" value="{{company.Name}}" /></td>
<td>
<select data-ng-model="selectedSeller" data-ng-options="seller.Login for seller in sellers">
</select>
</td>
</tr>
I can set a default element on all elements by $scope.selectedSeller = $scope.companies[0] in the controller scope, but what I really want, is to set selected to whoever is responsible for the company by linking the seller object to the company object.
I need someway to implement "isSelected" from the code below.
<tr data-ng-repeat="company in companies">
<td><input data-ng-model="company.Name" value="{{company.Name}}" /></td>
<td>
<select data-ng-model="selectedSeller" isSelected="company.responsible == seller.id" data-ng-options="seller.Login for seller in sellers">
</select>
</td>
</tr>
Anyone know how to solve this?

Angular is data driven, so you specify just model and ng-model connects it to the inputs.
So you provide just ng-model, no value and no "isSelected"
Look at this example: http://jsbin.com/kiqazaxahe/edit?html,js,output
<table>
<tr ng-repeat="company in vm.companies">
<td><input data-ng-model="company.
name"/></td>
<td>
<select data-ng-model="company.responsible"
data-ng-options="seller.id as seller.login for seller in vm.sellers">
</select>
</td>
</tr>
</table>
<h2>Json vm.companies</h2>
<pre>{{vm.companies | json}}</pre>
And your data probably look like this:
var StackController = function() {
this.companies = [
{
name: 'company 1',
responsible : 1
},
{
name: 'company 2',
responsible : 2
},
{
name: 'company 3',
}
];
this.sellers = [
{
login : 'pavel',
id : 1,
},
{
login : 'petr',
id : 2,
},
{
login : 'igor',
id : 3,
}
];
};
angular.module('stackApp', [])
.controller('StackController', StackController);
Model of select is company.seller which is connected to seller.id, syntax of ng-options can determine what is used as identifier and what is label.
seller.id as seller.login for seller in vm.sellers
One more thing to add, identifier could be not just id but whole object.

Use the filter as:
<select data-ng-model="selectedSeller" data-ng-options="seller.Login for seller in sellers" ng-init="selectedSeller = $filter('filter')($scope.company, {responsible: seller.id})[0]">
</select>
var app = angular.module('stackApp', []);
app.controller('StackController', function($scope) {
$scope.companies = [
{
name: 'company 1',
responsible : 1
},
{
name: 'company 2',
responsible : 2
},
{
name: 'company 3',
}
];
$scope.sellers = [
{
login : 'pavel',
id : 1,
},
{
login : 'petr',
id : 2,
},
{
login : 'igor',
id : 3,
}
];
}).filter("filterSeller", function() {
return function(sellers, company) {
var seller = {};
angular.forEach(sellers, function(item, j) {
if(company.responsible == item.id){
seller = item;
return false;
}
});
return seller.id;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="stackApp" ng-controller="StackController">
<tr ng-repeat="company in companies">
<td><input ng-model="company.name"/></td>
<td>
<select ng-model="company.responsibleSelected" ng-options="seller.id as seller.login for seller in sellers"
ng-init="company.responsibleSelected = (sellers | filterSeller:company)">
</select>
</td>
<td>{{company.responsibleSelected}}</td>
</tr>
</table>

Related

I am creating multiple "single" select tags dynamically in html using angularjs. Two columns contain two different select tags. I want the second

I have two columns in which I generate select tags dynamically. So if there are four rows, four select tags for each column. I want that the second select tag of column2 should only be selectable when a particular option in the first select tag has been selected.
<tbody ng-init="count=0">
<tr ng-repeat="a in CustomerCallDetails">
<td colspan="1">{{a.first_name}} {{a.last_name}}</td>
<td colspan="1">{{a.date}}</td>
<td colspan="1">{{a.parent_classification_name}}({{a.parent_brand}})</td>
<td colspan="1">₹ {{a.customer_revenue | number}}</td>
<td colspan="1">{{a.phone}}</td>
<td>
<select><option ng-click="!disableSelect[count];count=count+1">Called</option><option selected="selected">Not Called</option></select>
</td>
<td colspan="1">
<select ng-disabled="disableSelect[count]"><option>Called</option><option selected="selected">Not Called</option></select>
</td>
</tr>
</tbody>
This is the code I have tried till now. But it doesnt seem to work. I have a for loop in my controller that defines disabledSelect as true. Where am I going wrong? I am new to angular. Maybe this sounds like a very tiny problem.
You can have a look at this example to infer idea and adapt it on your existing code.
HTML
<div ng-app="myapp">
<fieldset ng-controller="FirstCtrl">
<select
ng-options="p.id as p.first for p in people"
ng-model="selectedPerson"></select>
<select ng-disabled='selectedPerson === 2'
ng-options="p.id as p.actor for p in actor"
ng-model="selectedActor"></select>
selected person id: {{selectedPerson}}
</fieldset>
</div>
Controller
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
$scope.people = [
{ id: 1, first: 'John', actor: 'Silvester' },
{ id: 2, first: 'Rocky',actor: 'Silvester' },
{ id: 3, first: 'John',actor: 'Arnold' },
{ id: 4, first: 'Ben',actor: 'Arnold' }
];
$scope.actor = [
{ id: 1, actor: 'Silvester' },
{ id: 2, actor: 'Silvester' },
{ id: 3, actor: 'Arnold' },
{ id: 4, actor: 'Arnold' }
];
});
Here the first select dropdown is for the people and the value for the <option> is the id of the people. So, whenever the people with id:2 is selected the select dropdown for the Actor is disabled.
For your simplicity and further experiment here is the link to JSFIDDLE

AngularJS : ng-model not working in multiple drop down

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.

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)}}

AngularJS ng-selected ng-repeat multi-dimension

i try to make a table with with an select each row. the data from table and the select field is from an array...
<div ng-app="app" ng-controller="MainCtrl">
<table>
<thead>
<tr>
<th>Headline #1</th>
<th>Headline #2</th>
<th>Headline #3</th>
<th>Headline #4</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>
<select name="" id="">
<option value="" ng-repeat="role in roles">{{role.name}}</option>
</select>
</td>
<td>anything...</td>
</tr>
</tbody>
</table>
angular.module('app', [])
.controller('MainCtrl', function ($scope) {
$scope.users = [
{
id : 1,
name : 'Andrew',
role : "admin"
},
{
id : 2,
name : 'Tanya',
role : "admin"
},
{
id : 3,
name : 'Roland',
role : "author"
},
];
$scope.roles = [
{
name : "author"
},
{
name : "admin"
}
];
});
see my example here:
jsFiddle
what i need is simple, each user has an role, and i would like that each row the correct role is selected...
sorry for my very bad english...
thx nathan
Add id field for the roles data list like this
$scope.roles = [{
id: "author",
name: "author"
}, {
id: "admin",
name: "admin"
}];
and change select element to
<select ng-model="user.role" ng-options="role.id as role.name for role in roles"></select>
Demo on jsFiddle

Updating table based on select option value with AngularJS

I have a drop down (select option) menu with various url query strings. Each option represents a server side query that sends back json data. What I'm trying to implement is that when the user selects an option, Angular sends a $http.get that fetches the json data and updates a table in my app. Below is a mock-up of the html with some Angular to (hopefully) clarify:
...
<select>
<option value="http://host:8000/getjsondata.jsp?var=1">option1</option>
<option value="http://host:8000/getjsondata.jsp?var=2">option2</option>
<option value="http://host:8000/getjsondata.jsp?var=N">optionN</option>
</select>
<table>
<tr ng-repeat="result in results">
<td>{{value1}}</td>
<td>{{value2}}</td>
<td>{{valueN}}</td>
</tr>
</table>
What would be the cleanest way to do this in Angular?
<select ng-options="obj.val as obj.txt for obj in slctOptions"
ng-change="update()"
ng-model="slctItem">
</select>
<table>
<tr ng-repeat="result in results">
<td>{{result.value1}}</td>
<td>{{result.value2}}</td>
<td>{{result.value3}}</td>
</tr>
</table>
<script>
function MyCtrl($scope, $http) {
$scope.slctOptions = [
{
val: 'a',
txt: "option1"
},
{
val: 'b',
txt: "option2"
},
{
val: 'c',
txt: "option3"
},
{
val: 'n',
txt: "optionn"
},
];
$scope.update = function () {
$http.get('http://host:8000/getjsondata.jsp?var=' + $scope.slctItem).success(function (data) {
$scope.results = data;
});
};
}
</script>

Resources