AngularJS : Ng-Options in Array of Arrays inside select - javascript

I am trying show options from array of array inside a select drop down but it is not showing up. Can someone tell me what I am doing wrong here ? https://plnkr.co/edit/HMYbTNzkqkbAGP7PLWWB?p=preview
HTML :
<div ng-controller="MainCtrl">
<table>
<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>
<select ng-model="r.value"
ng-options="opt.name for opt in option.value for option in availableOptions | filter:{name: r.name}">
<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>
</table>
<div>
{{rows}}
</div>
JS :
var bb = [];
bb.push({name:"CCCC"});
bb.push({name:"AAAA"});
bb.push({name:"DDDD"});
var aa = [];
aa.push({name:"CCCC"});
aa.push({name:"AAAA"});
aa.push({name:"BBBB"});
var cc = [];
cc.push({name:"BBBB"});
cc.push({name:"AAAA"});
cc.push({name:"DDDD"});
var dd = [];
dd.push({name:"CCCC"});
dd.push({name:"AAAA"});
dd.push({name:"CCCC"});
$scope.availableOptions = [
{ name: 'TestA',
value : aa
},
{ name: 'TestB',
value : bb
},
{ name: 'TestC',
value : cc
},
{ name: 'TestD',
value : dd
},
{ name: 'TestE',
value : []
}
];
How do I specify the ng-options for value which is an array filtered based on name: 'TestE' or something ?

The are two problem sin your code :
1# you did not assign value to all aa,bb,cc,dd they were empty
2# Filter would return you array so you need to use its 1st element like this
<select ng-model="r.value"
ng-options="option.name as option.name for option
in (availableOptions | filter:{name: r.name})[0].value">
<option value="">Select Value</option>
</select>
See this https://plnkr.co/edit/cQTISC1SPucCCRQQ8ca7?p=preview

Your array are not coming through correct json format.. for more check it https://docs.angularjs.org/api/ng/directive/ngOptions

Assign the child collection to an array and use that array for populating the child dropdown:
<select ng-model="selectedChildren"
ng-options="option.value as option.name for option
in availableOptions"
data-ng-change="childOptions = selectedChildren">
<option value="">Select Value</option>
</select>
<select ng-model="value"
ng-options="option as option.name for option
in childOptions track by $index">
<option value="">Select Value</option>
</select>
Here, when parent dropdown is selected, the value property (which is basically child dropdown collection) is assigned to a scope variable childOptions which is inturn used for binding the child dropdown
https://plnkr.co/edit/mXz8jpzTrnRoqx5r7b1W?p=preview

Please make the following changes and try,
var app = angular.module('plunker', []);
app.filter('ddOptions')
app.controller('MainCtrl', function($scope) {
$scope.rows = [{name:""}];
$scope.secondOptions = [];
$scope.addRow = function(){
$scope.rows.push({name:""});
}
var bb = [];
bb.push({name:"CCCC"});
bb.push({name:"AAAA"});
bb.push({name:"DDDD"});
var aa = [];
aa.push({name:"CCCC"});
aa.push({name:"AAAA"});
aa.push({name:"BBBB"});
var cc = [];
cc.push({name:"BBBB"});
cc.push({name:"AAAA"});
cc.push({name:"DDDD"});
var dd = [];
dd.push({name:"CCCC"});
dd.push({name:"AAAA"});
dd.push({name:"CCCC"});
$scope.availableOptions = [
{ name: 'TestA',
value : aa
},
{ name: 'TestB',
value : bb
},
{ name: 'TestC',
value : cc
},
{ name: 'TestD',
value : dd
},
{ name: 'TestE',
value : []
}
];
$scope.populateOptions = function(name){
var temp = $scope.availableOptions.filter(function(val){ return val.name === name; })
console.log(temp);
$scope.secondOptions = temp[0].value;
}
$scope.deleteRow = function(index){
$scope.rows.splice(index,1);
}
});
and HTML,
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<table>
<tr ng-repeat="r in rows track by $index">
<td>
<select ng-model="r.name" ng-change="populateOptions(r.name)"
ng-options="option.name as option.name for option
in availableOptions">
<option value="">Select Value</option>
</select>
</td>
<td>
<select ng-model="r.value"
ng-options="option.name as option.name for option
in secondOptions">
<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>
</table>
<div>
{{rows}}
</div>
</div>
</body>
</html>

Related

AngularJS multiple filter

I have a list of orders and a dropwdown list to filter orders depending on their status. Statuses are: not delivered, fully delivered and partially delivered. Filtering works fine with those 3 options, however I would like to implement one extra option that shows both not delivered and partially delivered orders together.
<select class="form-control" id="status" ng-model="orderFilter.status"
ng-init="orderFilter.status = '_'">
<option value="_">all</option>
<option value="_not" class="text-danger">not delivered</option>
<option value="_part" class="text-info">partially delivered</option>
<option value="n-p" class="text-warning">not and partial</option>
<option value="_done" class="text-success">delivered</option>
</select>
So I've added a new "custom" value, and the way it all works is, it is making copy of objects which are either one or the other, and that is bad, redundant and not what I want.
I thought it may be possible something like:
<option value="_not || _part" class="text-warning">not and partial</option>
Filtering part:
<tr ng-repeat="s in vm.sales | filter: orderFilter">
<td>...</td>
</tr>
The best solution is to write your own filter, if you don't want to do that for some reason, than you can filter the list programmaticaly and updating the list depending on selected value:
<select class="form-control" ng-change="filterSales()" id="status" ng-model="orderFilter.status"
ng-init="orderFilter.status = '_'">
<option value="_">all</option>
<option value="_not" class="text-danger">not delivered</option>
<option value="_part" class="text-info">partially delivered</option>
<option value="n-p" class="text-warning">not and partial</option>
<option value="_done" class="text-success">delivered</option>
</select>
And than in your controller somewhere:
$scope.filterSales = function(){
if($scope.orderFilter.status === 'n-p'){
var filteredWithNoStatus = $filter('filter')($scope.vm.sales,'_not');
var filteredWithPartStatus = $filter('filter')($scope.vm.sales,'_part');
$scope.filteredList = Object.assign(filteredWithNoStatus,filteredWithPartStatus);
}else{
$scope.filteredList = $filter('filter')($scope.vm.sales,$scope.orderFilter.status);
}
}
In your html you can remove than the filter
<tr ng-repeat="s in filteredList>
<td>...</td>
</tr>
Sorry that I didn't had the time to test the code, but I hope you understand the Idea.
If your possible statuses aren't going to change you could use !_done as your option value which would filter out the _done but leave _not and _part.
var app = angular.module("app", []);
app.controller("controller", function($scope) {
$scope.orderFilter = {
status: "_"
};
$scope.sales = [{
status: "_not",
item: "NOT"
},
{
status: "_part",
item: "PART"
},
{
status: "_done",
item: "DONE"
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
<select class="form-control" id="status" ng-model="orderFilter.status">
<option value="_">all</option>
<option value="_not" class="text-danger">not delivered</option>
<option value="_part" class="text-info">partially delivered</option>
<option value="!_done" class="text-warning">not and partial</option>
<option value="_done" class="text-success">delivered</option>
</select> {{orderFilter}}
<table>
<tbody>
<tr ng-repeat="s in sales | filter: orderFilter.status">
<td>{{s.item}}</td>
</tr>
</tbody>
</table>
</div>
Otherwise you'd need to write a custom filter. See the snippet below which let's you add multiple values e.g. "_not, _part" would return both not and partially delivered items.
var app = angular.module("app", []);
app.controller("controller", function($scope) {
$scope.orderFilter = {
status: ""
};
$scope.sales = [{
status: "_not",
item: "NOT"
},
{
status: "_part",
item: "PART"
},
{
status: "_done",
item: "DONE"
}
];
});
app.filter("filterByProp", function() {
return function(items, prop, filterVal) {
// don't filter if no value to filter on
if (!filterVal) {
return items;
}
// split filter val to allow for multiple props e.g. "_not, _part"
var filters = filterVal.replace(" ", "").split(",");
// only return items which match at least one of the values
return items.filter(function(item) {
return filters.indexOf(item[prop]) > -1
});
};
});;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
<select class="form-control" id="status" ng-model="orderFilter.status">
<option value="">all</option>
<option value="_not" class="text-danger">not delivered</option>
<option value="_part" class="text-info">partially delivered</option>
<option value="_not, _part" class="text-warning">not and partial</option>
<option value="_done" class="text-success">delivered</option>
</select> {{orderFilter}}
<table>
<tbody>
<tr ng-repeat="s in sales | filterByProp : 'status' : orderFilter.status">
<td>{{s.item}}</td>
</tr>
</tbody>
</table>
</div>

ng-model using ng-options to get property value

Here is my code
var filter1 = { id: 96, name: "Affinity Groups Allowed In Site",typeId: 74, description: "SiteAffinityGroupsAllowed" };
var filter2 = { id: 125, name: "AffinityLob", typeId: 100, description: "AffinityLob" };
$scope.filterCriteriaObjets = [filter1, filter2];
I am trying to get the name using ng-model but it seems the ng model is getting the whole object . Here is my dropdown
<select class="form-control" name="role" ng model="filterCriteria.ObjectName"
ng-options="item as item.name for item in filterCriteriaObjets" ng-required="true" ng-change="getObjectInfo()">
<option value="">- Select Filter Name -</option>
</select>
But when I change the option filterCriteria.ObjectName is getting the whole object. I want the ng-model to be equals just the name property
here is what you can do...
<select class="form-control" name="role" ng-model="filterCriteria.ObjectName"
ng-options="item.name as item.name for item in filterCriteriaObjets" ng-required="true" ng-change="getObjectInfo()">
<option value="">- Select Filter Name -</option>
</select>
your error is declaring ng-model you declared it as ng model
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<select class="form-control" name="role" ng-model="filterCriteria.ObjectName"
ng-options="item.name as item.name for item in filterCriteriaObjets" ng-required="true" ng-change="getObjectInfo()">
<option value="">- Select Filter Name -</option>
</select>
</body>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
var filter1 = { id: 96, name: "Affinity Groups Allowed In Site",typeId: 74, description: "SiteAffinityGroupsAllowed" };
var filter2 = { id: 125, name: "AffinityLob", typeId: 100, description: "AffinityLob" };
$scope.filterCriteriaObjets = [filter1, filter2];
});
</script>
</html>

Reset to unbound option in dropdown menu

I have a dropdown menu in HTML as below, with a default option. I am using ng-options to generate the remaining options thus binding these and not the first with the variable dropdown.
<td>
<select ng-model="dropdown" ng-options="item as item.name for item in items">
<option value="">--- Select an item---</option> <!-- default -->
</select>
</td>
Results in to the following HTML
<td>
<select ng-model="dropdown" ng-options="item as item.name for item in items">
<option value="">--- Select an item---</option>
<option value="0" label="item1">item1</option>
<option value="1" label="item2">item2</option>
<option value="2" label="item3">item3</option>
</select>
</td>
I need to support a reset button, which should reset the drop down to the default option "Select an item". Since this option is not bound to the model. i cant do something like this -
$scope.dropdown = items[0] // this would select item1
or even
$scope.dropdown = null
How can i reset my dropdown to the first option ?
try like this.
var app = angular.module("app",[]);
app.controller("MyCtrl" , function($scope){
$scope.items = [{name:"ali"},{name:"reza"}];
$scope.dropdown = $scope.items[0];
$scope.reset = function(){
$scope.dropdown = {};
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<select ng-model="dropdown" ng-options="item as item.name for item in items">
<option value="">--- Select an item---</option>
</select>
<button type="submit" name="button" ng-click="reset()">Reset</button>
</div>

repeat Select option in ng-repeat Angularjs

I have a form that repeat select option in ng-repeat. in this form i want to selected defualt value for select element. In fact in first select element selected value is "n1" and in second select element selected value is "n2". while in tow select element defualt value is "n2".
what is my problem?
function MyCntrl($scope) {
$scope.data = {
orders: [{ s:'' }]
};
$scope.list = [1,2];
$scope.data.orders[0] = "n1";
$scope.data.orders[1] = "n2";
$scope.sizes = [ {code: 1, name: 'n1'}, {code: 2, name: 'n2'}];
$scope.update = function() {
console.log($scope.item.code, $scope.item.name)
}
}
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="MyCntrl">
<div ng-repeat="l in list track by $index">
<select ng-model="data.orders[$index]" ng-change="update()">
<option ng-selected ="data.orders[$index] == size.name" ng-repeat="size in sizes">
{{size.name}}
</option>
</select>
</div>
<select ng-model="data.orders[0]" ng-change="update()">
<option ng-selected ="data.orders[0] == size.name" ng-repeat="size in sizes">
{{size.name}}
</option>
</select>
<select ng-model="data.orders[1]" ng-change="update()">
<option ng-selected ="data.orders[1] == size.name" ng-repeat="size in sizes">
{{size.name}}
</option>
</select>
</div>
</body>
</html>
Try this code instead. It uses $parent.$index instead of $index.
ng-repeat tracks by $index by default, so there's no need to specify it.
This causes a problem in your inner loop, which is also tracking by $index. When you say $index in the inner loop it picks up the inner loops index which is always going to evaluate to true.
function MyCntrl($scope) {
$scope.data = {
orders:[{ s:'' }]
};
$scope.list = [1,2];
$scope.data.orders[0] = "n1";
$scope.data.orders[1] = "n2";
$scope.sizes = [{code: 1, name: 'n1'}, {code: 2, name: 'n2'}];
$scope.update = function() {
console.log($scope.item.code, $scope.item.name)
}
}
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="MyCntrl">
<div ng-repeat="l in list track by $index">
<select ng-model="data.orders[$index]" ng-change="update()">
<option ng-selected ="data.orders[$parent.$index] == size.name" ng-repeat="size in sizes">
{{size.name}}
</option>
</select>
</div>
</div>
</body>
</html>

NG-Click not working in Chrome but works in FireFox

I have a NG-Click to change the amount of elements on the page (that are coming from an API call). The NG-Click utilizes a drop down box that works in FireFox. But I recently discovered that it isn't working in Chrome when a co-worker started working on the service. I have no idea as to why it wouldn't work and any help is appreciated. I've attached a JSFidle with the code.
http://jsfiddle.net/pAy3B/
JavaScript:
app.controller("AppCtrl", function($http, $scope){
var app = this;
$scope.toLoad=50;
$scope.page= 0;
$scope.sortArray = [];
$scope.filterList = "";
function getData(page){
$http.get('/file/filter/' + $scope.toLoad + '/' + $scope.page + '?' + $scope.filterList ).success(function(data){
app.info = data;
console.log(data);
});
}
$scope.changeLoad = function(toLoad){
$scope.toLoad = toLoad;
getData($scope.page)
}
}
HTML:
<body ng-app="app" ng-controller="AppCtrl as app" id="body">
<div id="main-table">
<div class="widget-body no-padding">
<div id="select-more">
<select class="form-control" name="dt_basic_length" aria-controls="dt_basic" id="box-test" style="width:6%">
<option value="10" ng-click="changeLoad(10)"> 10 </option>
<option value="25" ng-click="changeLoad(25)"> 25 </option>
<option value="50" ng-click="changeLoad(50)"> 50 </option>
<option value="100" ng-click="changeLoad(100)"> 100 </option>
<option value="1000" ng-click="changeLoad(1000)"> 1000 </option>
</select>
</div>
<table>
<tbody>
<tr ng-repeat="information in app.info | filter:searchText">
<td>{{information.uuid}}</td>
<td>{{information.publisher}}</td>
<td>{{information.ts}}</td>
</tr>
</tbody>
</table>
</div>
</div>
You should use ng-change please see here
<body ng-app="app" ng-controller="AppCtrl" id="body">
<div id="main-table">
<div class="widget-body no-padding">
<div id="select-more">
<select class="form-control" name="dt_basic_length" aria-controls="dt_basic" id="box-test" style="width:6%" ng-change="update()" ng-model="selectedItem">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="1000">1000</option>
</select>
</div>
<table>
<tbody>
<tr ng-repeat="information in app.info | filter:searchText">
<td>{{information.uuid}}</td>
<td>{{information.publisher}}</td>
<td>{{information.ts}}</td>
</tr>
</tbody>
</table>
</div>
</div>
js:
var app = angular.module('app', []);
app.controller("AppCtrl", function ($http, $scope) {
var app = this;
$scope.toLoad = 50;
$scope.page = 0;
$scope.sortArray = [];
$scope.filterList = "";
$scope.selectedItem = {};
function getData(page) {
$http.get('/file/filter/' + $scope.toLoad + '/' + $scope.page + '?' + $scope.filterList).success(function (data) {
app.info = data;
console.log(data);
});
}
$scope.changeLoad = function (toLoad) {
$scope.toLoad = toLoad;
getData($scope.page);
};
$scope.update = function () {
alert($scope.selectedItem);
};
});

Categories