AngularJS ng-selected ng-repeat multi-dimension - angularjs

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

Related

Angular JS : Filter from 2 scope

I have 2 scope. I want to find based on the id of the scope "country", the country's name.
How can I print "France" for John, in this example.
$scope.country = [
{id:"1",name:"France"},
{id:"2",name:"Spain"}
];
$scope.people = [
{name:"John",country:"1"},
{name:"Ben",country:"2"}
]
I tried :
<tr ng-repeat="k in people">
<td>{{k.name}}</td>
<td>{{country | filter : {"id" : k.country } }}</td>
</tr>
I dont know if I am doit it wrong or not, but I can only get the array, not the field name of the country.
Try like this.
var app = angular.module('anApp', []);
app.controller('ctrl', function($scope) {
$scope.country = [{
id: "1",
name: "France"
},
{
id: "2",
name: "Spain"
}
];
$scope.people = [{
name: "John",
country: "1"
},
{
name: "Ben",
country: "2"
}
]
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<div ng-app="anApp" ng-controller="ctrl">
<div class="form-group">
<table>
<tr ng-repeat="k in people">
<td>{{k.name}}</td>
<td ng-repeat="c in country | filter:{id:k.country}">{{c.name}}</td>
</tr>
</table>
</div>
</div>
Can set filter up this way:
<td>{{(country | filter : {"id" : k.country })[0].name }}</td>
DEMO
In my opinion, generally speaking, if you want to share or access data between different scopes, you have to use the rootScope, but I recommend you to always use services if you need to share some data between scopes.
So I think it's a matter of application design not how to implement this requirement in AngularJS.
Hope this could help you

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.

how to filter data on a table with angularjs

So, I have this table that displays users taken from a server in angularjs. Here is the users object:
'users'= [
{
"name":"Jane Doe",
"gender":"female",
"role":"admin"
},
{
"name":"John Doe",
"gender":"male",
"role":"owner"
}
]
Here is the table that displays this data:
<div class="col-md-4">
<h3>Filter by user role</h3>
<select class="form-control" ng-model="roleOrder">
<option
ng-repeat="user in users"
value="{{user.role}}">{{user.role}}</option>
</select>
</div>
<table class="table table-bordered">
<thead>
<th>Name</th>
<th>Gender</th>
<th>role</th>
</thead>
<tbody>
<tr ng-repeat="user in users | filter:{role: roleOrder}">
<td>{{user.name}}</td>
<td>{{user.gender}}</td>
<td>{{user.role}}</td>
</tr>
</tbody>
</table>
The problem is, when the page loads, nothing gets displayed until I select a role from the dropdown to filter the users.
My goal is to have all the users displayed initially, and then to filter the users by their roles once their corresponding role is selected in the option select dropdown.
Is there a better way than the one I'm attempting? Or how do I do it right?
Thanks for any ideas
You can add function for it like here AngularJS custom filter function
In js file
$scope.predicate = function( roleOrder ) {
return function( item ) {
return !roleOrder || item.role === roleOrder;
};
};
And in html
<tr ng-repeat="user in users | filter:predicate(roleOrder)">
<td>{{user.name}}</td>
<td>{{user.gender}}</td>
<td>{{user.role}}</td>
</tr>
user data is displaying when page loads, its working fine. Can you check the below link.
http://plnkr.co/edit/FwqivguAcyLnqxKVWEC6?p=preview
$scope.users= [
{
"name":"Jane Doe",
"gender":"female",
"role":"admin"
},
{
"name":"John Doe",
"gender":"male",
"role":"owner"
}
]
Is this you expectation, it not please explain it briefly.
Check whether the data from server binds in $scope when the page loads

Angular ng-options object linked to ng-repeat object

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>

Dynamic Select Boxes in Angular ng-repeat

I'm an old "backender" and pretty new to Angular and modern frontend programming, but I have to learn...
I have the following problem: There is a list with several different person properties, which are created via ng-repeat from Controller response. The values are editable, but the display control depends on the type of the property. The Gender, for example, needs to be edited via a Select-Box. The options for the select box are obtained from a Rest-Server.
So now the main question: How can I build different Select Boxes for each property?
I tried the following code, which is not working:
<section class="contactProperty" ng-repeat="property in contactDetail.properties">
<table>
<tr>
<td>{{property.message}}</td>
<td rowspan=2>{{property.value}}
<script>
var lst = ContactDetailController.getClassification(property.type);
</script>
<input ng-show="{{property.displaystyle_id}}==1" type="text" ng-model="property.value"/>
<select ng-show="{{property.displaystyle_id}}==3" ng-model="property.value">
<option ng-repeat="opt in lst" value="{{opt.id}}">{{opt.message}}</option>
</select>
</td>
</tr>
<tr>
<td>
<select type="text" ng-model="property.status_id">
<option ng-repeat = "status in contactDetail.propertyStatus" value="{{status.id}}">{{status.message}}</option>
</select>
</td>
</tr>
</table>
</section>
The Controller is defined on the top level element with following code
.controller('ContactDetailController',
['$scope', '$rootScope', 'ContactDetailService',
function ($scope, $rootScope, ContactDetailService) {
$scope.getContactDetail = function () {
ContactDetailService.getContactDetail(function(response) {
if(response.success) {
$scope.contactDetail=response;
} else {
$scope.error = response.message;
}
});
};
$scope.getClassifications= function(type) {
ContactDetailService.getClassifications(type, function(response) {
if (response.success) {
return response;
}
});
};
$scope.getContactDetail();
}]);
And the corresponding service:
.factory('ContactDetailService',
['$http', '$rootScope', '$location',
function ($http, $rootScope, $location) {
var service = {};
service.getContactDetail = function(callbackFunc) {
delete $http.defaults.headers.common['X-Requested-With'];
var apiRoot="";
apiRoot = $rootScope.environments[window.location.host];
$rootScope.apiRoot=apiRoot;
var id=$location.search().id;
$http.get(apiRoot+'/contactdetail?id='+id, {})
.success(function(response){
$rootScope.contactDetail=response;
callbackFunc(response);
}).error(function(response){
alert("error"+response.message);
});
};
service.getClassifications = function(type, callbackFunc) {
var apiRoot="";
apiRoot = $rootScope.environments[window.location.host];
$http.get(apiRoot+'/classifications?type='+type, {})
.success(function(response) {
callbackFunc(response);
})
.error(function(response) {
alert("error"+response.message);
});
};
return service;
}]);
Can anyone help me?
you can show/hide fields using ng-show/ng-hide or ng-if or ng-switch depending on your type of variable selected. if this is what you want.
I will try to explain more precisley:
This is a part of my incomming Json from the Backend:
"properties": [
{
"id": 8,
"type_id": 25,
"status_id": 13,
"contact_id": 4,
"value": "27",
"create_date": null,
"update_date": null,
"guikey": "gui.gender",
"message": "Geschlecht",
"displaystyle_id": 3,
"queryparam": "9",
"options": [
{
"id": 26,
"type": 9,
"guikey": "gui.male",
"language": "de",
"message": "Männlich",
"displaystyle_id": 0
},
{
"id": 27,
"type": 9,
"guikey": "gui.female",
"language": "de",
"message": "Weiblich",
"displaystyle_id": 0
}
]
}
],
It is rendered by following code:
<section class="contactProperty" ng-repeat="property in contactDetail.properties">
<table>
<tr>
<td>{{property.message}}</td>
<td rowspan=2 ng-switch on="property.displaystyle_id">{{property.value}}
<input ng-switch-when="1" type="text" ng-model="property.value"/>
<input ng-switch-when="2" type="date" ng-model="property.value"/>
<select ng-switch-when="3" ng-model="property.value">
<option ng-repeat="opt in property.options" value="{{opt.id}}">{{opt.message}}</option>
</select>
</td>
</tr>
<tr>
<td>{{property.status_id}}
<select type="text" ng-model="property.status_id">
<option ng-repeat = "status in contactDetail.propertyStatus" value="{{status.id}}">{{status.message}}</option>
</select>
</td>
</tr>
</table>
</section>
The resulting HTML contains a Select box as expacted:
<section class="contactProperty ng-scope" ng-repeat="property in contactDetail.properties">
<table>
<tbody>
<tr>
<td class="ng-binding">Geschlecht</td>
<td class="ng-binding" on="property.displaystyle_id" ng-switch="" rowspan="2">
27
<select class="ng-scope ng-pristine ng-valid" ng-model="property.value" ng-switch-when="3">
<option class="ng-binding ng-scope" value="26" ng-repeat="opt in property.options">Männlich</option>
<option class="ng-binding ng-scope" value="27" ng-repeat="opt in property.options">Weiblich</option>
</select>
</td>
</tr>
<tr>
</tbody>
</table>
</section>
But the Browser displays the Value "Männlich" in this example, but I expected to see "Weiblich" because the property.value 27 is passed from the json. I just show the value for debug as {{property.value}} and it shows 27, which is correct. I don't understand why the dropdown still showing the first entry (26/Männlich) in this case...

Resources