ng-options for select box binding to hash - angularjs

I'm a little confused on how to do a binding with AngularJS. I'm putting a <select> element in with an ng-model="variable.type". I've also got a $scope.type variable with is a hash table. The key of that hashtable is the variable.type.
So basically I want the select box to list all of the values from $scope.type, and then do the binding so that the variable.type is linked to the key of the hashtable. I'm just not sure how to specify the ng-options to do that.
<tr ng-repeat="variable in variables">
<td>
<select ng-model="variable.type" ng-options="????">
</select>
</td>
</tr>

If I'm understanding your question, you're basically asking how to use an object as a data source for ng-options. If $scope.type looks like this:
$scope.type = {
"type1": { value: "value1" },
"type2": { value: "value2" },
"type3": { value: "value3" }
};
And $scope.variables looks like this:
$scope.variables = [
{
id: 1,
name: "item1",
type: "type1"
},
{
id: 2,
name: "item2",
type: "type2"
},
{
id: 3,
name: "item3",
type: "type3"
}
];
Then you could bind it up like this:
<tr ng-repeat="variable in variables">
<td>
<select ng-model="variable.type" ng-options="key as vartype.value for (key, vartype) in type"></select>
</td>
</tr>
Demo

Related

Angular-material set default options in md-select multiple

I tried to follow this tutorial, But I can't make it work for multiple md-select. In fact I have a multiple select list of user and i want to have 2 users selected by default.
Is there any solution for achieving that?
You need to track all selected users instead of just one. And remove/add them on the array on demand if needed.
.controller('MyCtrl', function($scope) {
$scope.users = [
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Alice' },
{ id: 3, name: 'Steve' }
];
$scope.selectedUsers = [];
$scope.selectUser = function (id) {
var user = $scope.users.filter(function(user) {
return user.id == id;
})[0];
var idx = $scope.selectedUsers.indexOf(user);
if (idx < 0) {
$scope.selectedUsers.push(user);
} else {
$scope.selectedUsers.splice(idx, 1);
}
}
}
And in the view add multiple and switch to selectedUsers.
<md-select ng-model="selectedUsers" multiple ng-model-options="{trackBy: '$value.id'}">
<md-option ng-value="user" ng-repeat="user in users">{{ user.name }}</md-option>
</md-select>
Codepen: https://codepen.io/kuhnroyal/pen/VWeWaw
This code defines the array of selected objects
$scope.selectedUsers = [];
You can set it by default with some of the users
$scope.selectedUsers =[
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Alice' }
];
This is because ng-model is set with selectedUsers.
If you need more info about NG-MODEL behaviour, take a look here : https://docs.angularjs.org/api/ng/directive/ngModel
You'll also learn more about data-binding in AngularJS.
Furthermore, you will have to update your HTML to allow the md-select to have multiple selected value.
<md-select ng-model="selectedUsers" multiple></md-select>
You'll learn more about it here https://material.angularjs.org/latest/api/directive/mdSelect
Controller:
$scope.users = [
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Alice' },
{ id: 3, name: 'Steve' }
];
$scope.selectedUser =[
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Alice' }
];
View:
<md-select ng-model="selectedUser" ng-model-options="{trackBy: '$value.id'}" multiple>
<md-option ng-value="user" ng-repeat="user in users">{{ user.name }}
</md-option>
</md-select>

filter by text in specifiec property

I have an array of objects, like those
{ name: "task1", owner: "david", des: "task1 description" },
{ name: "task2", owner: "Smith", des: "task2 description" },
{ name: "task1", owner: "david", des: "task1 description" },
also a select and textbox
and a table that shows them all.
i am looking a way to filter, the data in the table.
The user will select a value from drop-down and enter text in the textbox.
Then the table data will be filtered by text matches in selected value (object property) from drop-down.
Example:
choosing "name" from dropdown and write "task" in textbox will return all 3 items in array. text word is contained within all 3 records.
choosing "name" from dropdown and write "task1" in textbox will return record 1 and 3.
textbox value will be required for the filter to happen.
Can it be done with angularjs filter?
https://plnkr.co/edit/Afs7MOIziUOvFWzBY7qf?p=preview
You need to use ng-disabled property on text-box
Working Plunker
Html need to update
<input ng-model="filterdata[filterProperty]" type="text" ng-disabled="!filterProperty" />
At that point it's probably easiest to write a custom filter. Custom filters are very easy and straightforward and allow you to control all aspects of how and when the filter is applied. Here is a working sample for your case - it's not very robust because it will break if you try to filter a numeric property, but it gives you the gist and something to build on and customize for your needs.
angular.module('myApp', [])
.controller('myCtrl', function($scope) {
$scope.cards = [{
name: "task1",
owner: "david",
des: "task1 description"
},
{
name: "task2",
owner: "Smith",
des: "task2 description"
},
{
name: "task3",
owner: "Smith",
des: "task3 description"
},
{
name: "task4",
owner: "Davis",
des: "task4 description"
},
{
name: "task5",
owner: "Thomas",
des: "task5 description"
},
{
name: "task6",
owner: "david",
des: "task6 description"
}
];
})
.filter('myFilter', function() {
return function(items, property, value) {
// if items, property or value are missing return items by default
if (!items || !property || !value) {
return items;
}
// create an array to hold the matched items
var out = [];
angular.forEach(items, function(item) {
// see if the item property value contains the desired value
if (item[property].toLowerCase().includes(value.toLowerCase())) {
out.push(item);
}
});
// return the array of items
return out;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<div>
<select ng-model="filterProperty">
<option value="">filter by</option>
<option value="name">name</option>
<option value="owner">owner</option>
<option value="des">des</option>
</select>
<input ng-model="filterData" type="text" />
</div>
<table style="border: 1px solid">
<tbody>
<tr>
<th>name</th>
<th>owner</th>
<th>description</th>
</tr>
<tr ng-repeat="x in cards | myFilter:filterProperty:filterData">
<td>{{x.name}}</td>
<td>{{x.owner}}</td>
<td>{{x.des}}</td>
</tr>
</tbody>
</table>
</div>
</body>

How get a label from a store in Angular while repeat another store

I've two stores in my controller:
$scope.categoryStore = [{id: 1, label: "A"}, {id: 2, label: "B"}, {id: 3, label: "C"}];
$scope.collectionStore = [{id: 1, categoryId: 1, name: "Test"}, {id: 1, categoryId: 2, name: "Test2"}];
In my view I have a ng-repeat for the collectionStore. Now I want to display the label of the categoryStore instead of the categoryId.
<tr ng-repeat="item in collectionStore">
<td>{{item.id}}</td>
<td>{{item.categoryid}} <!-- this would be the label --></td>
<td>{{item.name}}</td>
</tr>
My suggestion is to create a function to handle this and use the $filter within that function.
In your view:
<tr ng-repeat="item in collectionStore">
<td>{{item.id}}</td>
<td>{{getCategoryLabel(item.categoryId)}}</td> <!-- handle this with a function -->
<td>{{item.name}}</td>
</tr>
Then in your controller:
$scope.getCategoryLabel = function(categoryId) {
var category = $filter('filter')($scope.categoryStore, { id: categoryId }, true);
if (category.length) return category[0].label;
}

AngularJS ng-repeat setting default select value

$scope.activities =
[
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
<select data-ng-model="engineer.currentActivity" data-ng-options="a.name for a in activities">
</select>
Using the above I am able to create a select box with 3 values, a blank one and then dropdown menu and horizontal bar.
I would like to set Horizontal Bar as my default and cannot see how to do this.
Help would be great
In the controller, just add a line to setup the initial selection:
$scope.activities =
[
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
$scope.engineer = {}; // if needed
$scope.engineer.currentActivity = $scope.activities[1];
In your angular controller:
$scope.activities = [
{ id: 1, type: "DROPDOWN_MENU", name: "Dropdown Menu" },
{ id: 2, type: "HORIZONTAL_BAR", name: "Horizontal Bar" }
];
$scope.activity = $scope.activities[1]; //Bind 2nd activity to the model.
In the HTML:
<select ng-model="activity"
ng-options="activity as activity.name for activity in activities">
<option value=""></option>
</select>
See the Fiddle
Use ng-init directive
ng-init="engineer.currentActivity = options[1]"

Select in AngularJS

I am trying to show a select box inside a ng-repeat and am stuck with the following:
<tr ng-repeat="element in elements" post-repeat-directive>
<td>{{element.name}}</td>
<td>
<select ng-model="element.type"
ng-options="item.id as item.name for item in tipo_items"></select>
</select>
</td>
</tr>
In my controller I have:
$scope.tipo_items = [
{ id: 1, name: 'uno' },
{ id: 2, name: 'dos' },
{ id: 3, name: 'tres' },
{ id: 4, name: 'cuatro' },
{ id: 5, name: 'cinco' },
];
This shows the select items, but no item is pre-selected!
I checked the element.type values and they are correct...
What am I doing wrong?
According to the comprehension expression you defined in the select, you need to use the id value to preselect the item and set it for the model object.
$scope.element = {};
$scope.element.type = $scope.tipo_items[0].id;
DEMO
OK I found the problem...
I was loading the id from the database as json, and the id was a string, not an integer...
this solved the problem:
$scope.tipo_items = [
{ id: '1', name: 'uno' },
...
instead of
$scope.tipo_items = [
{ id: 1, name: 'uno' },
...
This is default behavior by angular select directive. If you'll set ng-model to a default in the ctrl you'll get it preselected.
something like (in the ctrl):
$scope.element.name = $scope.tipo_items[0]

Resources