angularJs filter from in controller - angularjs

i have the following arry in my scope
items: [
{
id: "0",
name: "כיבוי אורות",
roomId: "0",
type: "scenario",
status: 1
},
{
id: "1",
name: "הדלקת אורות",
roomId: "0",
type: "scenario",
status: 1
},
{
id: "0",
name: "תנור מטבח",
roomId: "0",
type: "heater",
status: 0
}]
i would like to filter it by id and type within the controller ( not by ng-repeat | filter).
Thanks allot
Avi

Well if you want to filter by name and id from within the controller you could just use native filter. Look at the polyfill for support for older browsers.
var type = "TypeTOfilter", id=idToFilter;
$scope.items = items.filter(function(itm){ return itm.id === id && itm.type === type });
Or you could even inject ``$filter` in your controller, if you just want to do it one time, and not have it in the ng-repeat.
.controller('ctrl', ['$scope', 'filterFilter', function($scope, filter){
//...
$scope.items = filter(items)({type:type, id:id});
//....
}]);
Or you could even do a for-loop to filter out items..

Related

How to use ngoptions to generate an optgroup without repeating the group name

Hello i'm trying to use ng-options to get a grouping of countries by region. It only works by repeating the group name in every row. Is it possible to do it using the following json :
$scope.countries = [
{ region: "americas", countries: [{ value: "usa", key: "1" }, { value: "mexico", key: "2" }] },
{ region: "Africa", countries: [{ value: "3", key: "Algeria" }, { value: "4", key: "Morocco" }, { value: "5", key: "Tunisia" }] },
];
ng-options is pretty locked down in it's definition, so you'll probably need to loop through your countries array and add the region, something like:
$scope.countries_with_regions = [];
$scope.countries.forEach(function(region){
region.countries.forEach(function(country){
country.region = region.region;
$scope.countries_with_regions.push( country );
});
});
then you can do your ng-options with the countries_with_regions
You data structure fo countries needs to be like
countries = [{value : 3, key: "algeria", region : "africa"}, ...]
for the ng-options to be able to "group by" region.

Kendo UI + Angular - v2014.2.903 vs v2014.3.1119 JSFiddle Issues

I am working on upgrading one of my Angular/Kendo UI projects from v2014.2.903 to v2014.3.1119. I have encountered a few instances where v2014.3.1119 breaks functionality that worked fine in v2014.2.903. I decided to create a couple JSFiddles to illustrate the issues, but unfortunately, the JSFiddle that points to v2014.2.903 doesn't seem to even recognize Kendo UI.
v2014.3.1119 JSFiddle (this works) ... http://jsfiddle.net/lejuan5150/w0711rdg/
v2014.2.903 JSFiddle (this doesn't work) ... http://jsfiddle.net/lejuan5150/4svqnaz6/
Both contain the same code and configuration aside from the version of Kendo UI they are referencing. Here is the code:
HTML:
<div>
<div data-ng-controller="personController">
<div
kendo-grid="personGrid"
k-options="personGridOptions"
k-ng-delay="personGridOptions">
</div>
<br />
First Name Combo Box:
<select
kendo-combo-box="firstNameComboBox"
k-options="firstNameComboBoxOptions"
k-ng-delay="firstNameComboBoxOptions"
k-ng-model="selectedPerson.firstName"
></select>
<br />
Last Name Combo Box:
<select
kendo-drop-down-list="lastNameDropDownList"
k-options="lastNameDropDownListOptions"
k-ng-delay="lastNameDropDownListOptions"
k-ng-model="selectedPerson.lastName"
></select>
</div>
JavaScript:
var app = angular
.module("app", [
"kendo.directives"
]);
app.controller("personController", [
"$scope",
personController
]);
function personController(
$scope
){
init();
function init(){
var personData = [{
firstName: "Joe",
lastName: "Smith",
status: "Active"
},{
firstName: "John",
lastName: "Smith",
status: "Active"
},{
firstName: "Travis",
lastName: "Smith",
status: "Expired"
}];
$scope.personDataSource = new kendo.data.DataSource({
data: personData
});
$scope.firstNamesData = [{
id: "Joe",
firstName: "Joe"
},{
id: "George",
firstName: "George"
},{
id: "John",
firstName: "John"
},{
id: "Travis",
firstName: "Travis"
}];
$scope.lastNamesData = [{
id: "Jones",
lastName: "Jones"
},{
id: "Smith",
lastName: "Smith"
}];
bindPersonGrid();
bindFirstNameComboBox();
bindLastNameDropDownList();
}
function bindPersonGrid(){
$scope.personGridOptions = {
dataSource: $scope.personDataSource,
selectable: "row",
dataBound: onPersonGridDataBound,
change: onPersonGridRowSelected
}
}
function onPersonGridDataBound(){
var grid = this;
var firstRow = grid.element.find("tbody tr:first");
grid.select(firstRow);
}
function onPersonGridRowSelected(
event
){
var grid = event.sender;
$scope.selectedPerson = grid.dataItem(grid.select());
$scope.$digest();
}
function bindFirstNameComboBox(){
$scope.firstNameComboBoxOptions = {
dataSource: $scope.firstNamesData,
dataTextField: "firstName",
dataValueField: "id"
};
}
function bindLastNameDropDownList(){
$scope.lastNameDropDownListOptions = {
dataSource: $scope.lastNamesData,
dataTextField: "lastName",
dataValueField: "id"
};
}
}
Does anyone know why the v2014.2.903 JSFiddle doesn't work?
I found the issue. Kendo v2014.2.903 doesn't like k-ng-delay when using a hard coded array of JavaScript objects.

AngularJS: 'Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys."

I have this code example on codepen: http://codepen.io/anon/pen/hauvb
The problem is that ng-repeat does not update after I push my form object into the array. I can see the content is being added to the array but ng-repeat doesn't update. I tried working with $apply but I was told I don't need that since ng-click updates the $digest for me. Any help would be appreciated to understand what I'm missing. Thanks.
var app = angular.module('theTasker', []);
app.controller('MyTasks', [function(){
this.tasks = [
{
title: "This is the title",
completed: false
},
{
title: "This is the title",
completed: true
},
{
title: "This is the title",
completed: false
}
];
this.myform = {
item: "Item Title",
completed: false
};
this.addtask = function(){
this.tasks.push(this.myform);
};
}])
edit:
the code above produces this error:
Duplicates in a repeater are not allowed. Use 'track by' expression to
specify unique keys.
while testing your code I got an error
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.
change your HTML ng-repeat line to look like this:
li(ng-repeat="task in mytasks.tasks track by $index")
here's an example plnkr
You also had a typo in the myform object, where you specified 'item' instead of 'title', so new tasks were added, but the title didn't show.
Change it to look like this:
this.myform = {
title: "Item Title",
completed: false
};
here's a fixed code-pen
Your array needs to be on a scope. Trythis ensuring ng-repeat is repeats over "tasks":
app.controller('MyTasks', ['$scope', function($scope){
$scope.tasks = [
{
title: "This is the title",
completed: false
},
{
title: "This is the title",
completed: true
},
{
title: "This is the title",
completed: false
}
];
this.myform = {
item: "Item Title",
completed: false
};
this.addtask = function(){
$scope.tasks.push(this.myform);
};
}])

Use angular binding with kendo grid templates

I use kendo ui grid with angular. I want the grid to be updated with every change in the array (of any property). Meaning, if my data is:
this.rowData = [{ id: "1", name: "A", age: "16" }, { id: "2", name: "B", age: "42" }];
and the age is changed from 16 to 17 I want the grid to be updated automatically.
I understand that I can use ObservableArray and when updating the observable the grid will be updated but I don't want the entire application to know the observable. I want to be able to update the original rowData and affect the grid. Any suggestions of how I do that?
I thought that adding a template to a row or a specific column with angular binding will help but it didn't, here is an example of it:
function Controller(GridConstants) {
this.rowData = [{ id: "1", name: "A", age: "16" }, { id: "2", name: "B", age: "42" }];
this.gridDataSource = new kendo.data.DataSource({
data: new kendo.data.ObservableArray(this.rowData),
schema: {
model: { id: "id" }
}
});
this.gridOptions = {
dataSource: this.gridDataSource,
selectable: "row",
columns: [
{
field: "name",
title: "Name"
},
{
field: "age",
title: "Age",
template: "<label>{{dataItem.age}}</label>"
}
],
selectable: "single"
};
}
You can try ng-bind instead:
template: "<label ng-bind='dataItem.age'></label>"
var rowDataObservable = new kendo.data.ObservableArray(this.rowData);
...
data: rowDataObservable,
...
//and you need work with rowDataObservable, this will work
rowDataObservable[0].age = 17;

Iterate over returned angular resource in controller

I have a controller that accesses a resource Tag like so:
$scope.tags = Tag.query();
which resolves to something like this:
$scope.tags = [
{ name: "tag1", label: "Tag1" },
{ name: "tag2", label: "Tag2" },
{ name: "tag3", label: "Tag3" },
{ name: "tag4", label: "Tag4" },
];
For this particular controller, the returned tags should have an additional attribute "active": true, like { name: "tag1", label: "Tag1", active: true }.
How can I iterate over the returned promise once it is resolved to add this boolean?
Use the promise.then() function.
Tag.query().$promise.then(function (results) {
angular.forEach(results, function (result) {
result.active = true;
});
$scope.tags = results
});
see the docs on $q
I think what you need is this:
$scope.tags = Tag.query(function() {
$scope.tags['active'] = true;
});
When the server finishes calling the function that adds the property is executed.
I recommend you read https://docs.angularjs.org/api/ngResource/service/$resource

Resources