filter by text in specifiec property - angularjs

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>

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>

How to pre-select values in multi select input with AngularJS

I have the following HTML:
<div ng-controller="CreateSpreadsheetCtrl as csCtrl" ng-init="csCtrl.init()">
<select multiple="multiple" style="height:100px;" class="form-control"
ng-model="csCtrl.Template.BusinessUnitMappings"
ng-options="department as department.LocalizedName for department in csCtrl.DepartmentMasters">
</select>
</div>
Inside the CreateSpreadsheetCtrl.init(), we are loading an array called "DepartmentMasters" (csCtrl.DepartmentMasters) which contains a list of objects (e.g. {Id:1, Name: "Department 1" }, {Id:2, Name: "Department 2" }).
Also in the init() method, we load this "csCtrl.Template" object, which has a property inside it called "BusinessUnitMappings" (csCtrl.Template.BusinessUnitMappings), which is an array of DepartmentMaster objects.
With the above code, it binds correctly to the model and when you change the selections, csCtrl.Template.BusinessUnitMappings is bound correctly.
However, when csCtrl.Template.BusinessUnitMappings is pre-loaded with an existing array of objects, it doesn't select it in the UI when the page initially loads.
Change the expression to :
ng-options="department as department.Name for department in csCtrl.DepartmentMasters track by department.Id"
Working Demo :
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl',function($scope) {
var ctrl = this;
ctrl.DepartmentMasters = [
{Id:1, Name: "Department 1" },
{Id:2, Name: "Department 2" },
{Id:3, Name: "Department 3" },
{Id:4, Name: "Department 4" },
{Id:5, Name: "Department 5" }
];
ctrl.Template = {
"BusinessUnitMappings" : [
{Id:2, Name: "Department 2" },
{Id:3, Name: "Department 3" }
]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl as csCtrl">
<select multiple="true" style="height:100px;" class="form-control"
ng-model="csCtrl.Template.BusinessUnitMappings"
ng-options="department as department.Name for department in csCtrl.DepartmentMasters track by department.Id"></select>
</div>

Preselected values for angular-schema-form

Does angular-schema-form have a method to show preselected values?
When the titleMap on the select will set an integer, preselected values will show. But if it will set an object, I found no way of showing the correct name.
Is there anything to tie the object to, like with ng-options where you can set an attribute to compare them with the "track by" clause?
ng-options="option as option.name for option in array track by option.id"
In my example code, cats1 will set an object, cats2 will set an integer.
HTML:
<body>
<div ng-controller="MainCtrl">
<div class="login-container">
<form name="myForm"
sf-schema="schema"
sf-form="form"
sf-model="model">
</form>
</div>
</div>
</body>
Controller:
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.form = [
{
key: 'cats1',
type: 'select',
titleMap: [
{value: {id: 0, name: "Leopard"}, name: "Leopard"},
{value: {id: 1, name: "Tiger"}, name: "Tiger"}
]
},
{
key: 'cats2',
type: 'select',
titleMap: [
{value: 0, name: "Leopard"},
{value: 1, name: "Tiger"}
]
}
];
$scope.schema = {
"type": "object",
"properties": {
"cats1": {
"title": "Cats",
"type": "object"
},
"cats2": {
"title": "Cats",
"type": "number"
}
}
};
$scope.model = {cats1: {id: 1, name: "Tiger"}, cats2: 1};
}]);
Here is a plunkr:
https://plnkr.co/edit/0hK5Hrc9GXklfRwa6fjE?p=preview

ng-options for select box binding to hash

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

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