AngularJS - Filtering when targeting another page - angularjs

I have built a simple filter with angularJS, the html is like
<a class="filterbutton" ng-click="filters.grade = '7'">7 Grade</a>
<a class="filterbutton" ng-click="filters.grade = '6'">6 Grade</a>
<a class="filterbutton" ng-click="filters.grade = ''">X Clear Filters</a>
<ul>
<li ng-repeat="name in names | filter:filters">{{name.student}}, {{name.grade}} grade</li>
</ul>
And the controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.filters = { };
$scope.names = [{
"student": "Jimmy", "grade":7
}, {
"student": "Johny", "grade":7
}, {
"student": "Little Joe", "grade":6
}];
});
This works as expected. But what I wanted to do is to be able to check one of the filters and jump to another page with the same controller, so that when loaded the second page would be already filtered. So for example, if I click "filter by 7 grade in another page", it would jump to anotherpage.html and the output there would be already filtered.
I have made a plunkr here to illustrate what I mean. Thanks in advance!

Also you can try this simple solution:
HTML (add filter parameter to href attribute):
<a class="filterbutton" href="anotherpage.html?filter=7">Filter by 7 Grade in Another Page</a>
<a class="filterbutton" href="anotherpage.html?filter=6">Filter by 6 Grade in Another Page</a>
Javascript (get them from url and apply it)
app.controller('myCtrl', function($scope) {
$scope.filters = { grade : window.location.search.replace('?filter=','') };
$scope.names = [{
"student": "Jimmy", "grade":7
}, {
"student": "Johny", "grade":7
}, {
"student": "Little Joe", "grade":6
}];
});

Related

how to get the value from selected checkbox in angularjs

onhstrong text:
When i click checkbox table id based column name shown in the right side using json data
JS
var app = angular.module('plunker', ['ui']);
app.controller('MyCtrl', function($scope) {
$scope.records = [ { "Id": 1 }, { "Id": 2 }, { "Id": 3 } ];
$scope.selected = {};
$scope.ShowSelected = function() {
$scope.records = $.grep($scope.records, function( record ) {
return $scope.selected[ record.Id ];
});
};
});
HTML
<div data-ng-controller="MyCtrl">
<ul>
<li data-ng-repeat="record in records">
<input type="checkbox" ng-model="selected[record.Id]"> {{record.Id}}
</li>
</ul>
Show Selected
</div>

AngularJS $routeParams / service not fetching data from JSON

On test-detail.html page (partial view), data from respective json files are not fetched/displayed, i.e. the controller TestDetailCtrl is called in test-detail.html (as can be seen on a working alert button), but params curly brackets in view (test-detail.html) are empty.
However ListController for test-list.html works and fetches the tests.json.
File structure:
index.html
(tests)
tests.json (content correctly displayed in test-list.html)
a.json
b.json
(js)
(partials)
(css)
partials/test-list.html:
<form action="" data-ng-repeat="test in tests | orderBy:orderProp">
<input type="checkbox" data-ng-model="item.selected" data-ng-change="change(item)">
<a href="#/tests/{{test.id}}">
<img data-ng-src="{{test.imageUrl}}" alt="{{test.name}}" class="test-thumb">
</a>
<a href="#/tests/{{test.id}}">
{{ test.name }}
</a><br />
</form>
partials/test-detail.html (where none of the data are displayed and all checkmarks are false):
<div class="main">
<img data-ng-src="{{mainImageUrl}}"/>
<h2>{{ test.name }}</h2>
<p>{{ test.description }}</p>
Customization:
<ul>
<li>Test items: {{test.customization.items | checkmark }}</li>
<li>Test duration: {{test.customization.duration | checkmark }}</li>
</ul>
</div>
route provider in js/app.js:
app.config(['$routeProvider',
{$routeProvider
.when('/tests',
{templateUrl: 'partials/test-list.html', controller: 'ListController'})
.when('/tests/:testId',
{templateUrl: 'partials/test-detail.html', controller: 'TestDetailCtrl'})
.otherwise({redirectTo: '/tests'});
}]);
RESTful handling with js/services.js:
var appServices;
appServices = angular.module('appServices', ['ngResource']);
appServices.factory('Test', ['$resource',
function($resource){
return $resource('tests/:testId.json', {}, {
query: {method:'GET', params:{testId:'tests'}, isArray:true}
});
}]);
controllers.js:
var ctr = angular.module('myApp.controller', []);
ctr.controller('ListController', ['$scope', 'Test', function ($scope, Test)
{$scope.tests = Test.query(); /*works*/
$scope.orderProp = 'duration';}]);
ctr.controller('TestDetailCtrl', ['$scope', '$routeParams', 'Test', function($scope, $routeParams, Test)
{$scope.$on('$routeChangeSuccess', function() {
$scope.test = Test.get({testId: $routeParams.testId}, function(test) {
$scope.mainImageUrl = test.screenshots[0];
});
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
};
$scope.hello = function(name) {
alert('Test ' + (name || 'works' + '!')); /*works*/
}
})}
]);
Example test-a.json:
[{
id: "test-a",
name: "test a",
description: "text ... bla",
"customization": {
"items": true,
"duration": false}
}]
I think you are mixing aspx partials with angular-arrays here.
Angular ng-repeat will work on client side only and will evaluate your scope.tests array when it finishes loading.
Your aspx partial (test-detail.html) will probably work server-side and will depend on you data-binding it with a container.
Edit: Your test-a.json looks strange... why is it encapsulated with brackets? (Why is it an array?) The partials/test-a.html is not made for arrays. Try this JSON (test-a.json):
{
id: "test-a",
name: "test a",
description: "text ... bla",
"customization": {
"items": true,
"duration": false}
}

ng-repeat items in fixed positions

I have a ng-repeat directive and I want to show different object values in fixed index positions.
data:
{
"recipe": {
"id":"0001",
"name":"soup",
"cat":[{"name":"dinner"}, {"name":"lunch"}, {"name":"breakfast"}]
}
I want it to show like..
ng-repeat:
1: (show cat.name: "breakfast") should only be shown at index 0
2: (dont show items that contains "breakfast", "dinner")
3: (dont show items that contains "breakfast") (show cat.name:
"dinner") - only show "dinner" at possition index 3
4: (dont show items that contains "breakfast", "dinner")
5: (dont show items that contains "breakfast", "dinner")
etc..
How should I manage this?
orderBy filter will achieve this but you need to help it.
I would give each cat item a displayOrder since it needs something.
Then just
<ul>
<li ng-repeat="x in data.recipe.cat | orderBy:orderMeals">
{{x.name}}
</li>
</ul>
With a controller doing something like
var app = angular.module('myapp', []);
app.controller('myCtrl', function($scope, $timeout) {
$scope.data = {
"recipe": {
"id": "0001",
"name": "soup",
"cat": [{
"name": "dinner", displayOrder: 2
}, {
"name": "lunch", displayOrder: 1
}, {
"name": "breakfast", displayOrder: 0
}]
}};
$scope.orderMeals = function(item) {
console.log('item', item);
return item.displayOrder;
}
});
Notice I added displayOrders into your recipe object (see here)
try this
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', function($scope) {
$scope.json = {
"recipe": {
"id":"0001",
"name":"soup",
"cat":[{"name":"dinner"}, {"name":"lunch"}, {"name":"breakfast"}]
}
};
$scope.json.recipe.cat.reverse();
}]);
.html
<body ng-app='myApp' ng-controller='myCtrl'>
<div ng-repeat ="t in json.recipe.cat" ng-if="t.name != 'breakfast' && t.name != 'dinner'">
here : {{t.name}}
</div>
see the plunker Code here

How to filter the parent object by looping it's child array of object

I am getting some of objects from back-end. each of the object has the child array called 'phaseIds', it has multiple array of object, from the array i required to find the "name" existance according to the filter..
once i filtered, that object need to show in the page. I tried but i coun't get the result. any one help me with correct way to do this?
at present i am filter by students, but i am getting all the objects without filtered.
var app = angular.module('myApp', []);
var projects = [
{"name":"one", "PhaseIds":[
{id:"1",name:"school"},
{id:"2",name:"student"},
{id:"3",name:"teacher"}
]},
{"name":"two", "PhaseIds":[
{id:"1",name:"school"},
{id:"3",name:"teacher"}
]},
{"name":"three", "PhaseIds":[
{id:"1",name:"school"},
{id:"2",name:"student"}
]},
{"name":"four", "PhaseIds":[
{id:"1",name:"school"},
{id:"3",name:"teacher"}
]},
{"name":"five", "PhaseIds":[
{id:"1",name:"school"},
{id:"3",name:"teacher"}
]}
]
app.controller('MainCtrl', function($scope) {
$scope.projects = angular.forEach( projects, function (project) {
var filteredProject = project;
angular.forEach( project.PhaseIds, function ( phase ) {
if(phase.name.toLowerCase().indexOf('student') > -1 ){
//only required the students avilable projects
return filteredProject;
}
})
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainCtrl">
<ul>
<li ng-repeat="project in projects">{{project.name}}</li>
</ul>
</div>
Live Demo
You needn't put the logic in your controller code. You can achieve it in your HTML snippet as well by using $filter. Check below example. You can make your filter structure as deeper as you want.
<ul>
<li ng-repeat="project in projects | filter:{ PhaseIds : { name : 'student' } }">{{project.name}}</li>
</ul>
Please check your plunker. I've updated it
I prefer the #Vineet solution but if you need to play with the Json from the controller the right code should be:
app.controller('MainCtrl', function ($scope) {
$scope.projects = [];
angular.forEach(projects, function (project) {
var filteredProject = project;
angular.forEach(project.PhaseIds, function (phase) {
if (phase.name.toLowerCase().indexOf('student') > -1) {
//only required the students avilable projects
$scope.projects.push(filteredProject);
}
})
})
});
You can see the solution here - http://plnkr.co/edit/seIfZlhIbUnYMhWdEpGr
var filterProjectData = function(projects) {
var filteredProjects = [];
angular.forEach( projects, function (project) {
angular.forEach( project.PhaseIds, function ( phase ) {
if(phase.name.toLowerCase().indexOf('student') > -1 ){
//only required the students avilable projects
filteredProjects.push(project);
}
});
});
return filteredProjects;
}
$scope.projects = filterProjectData(projects);
No brainier . I simply tweaked your foreach logic.
try this one
app.controller('MainCtrl', function($scope) {
$scope.projects = [];
angular.forEach( projects, function (project) {
var filteredProject = project;
angular.forEach( project.PhaseIds, function ( phase ) {
if(phase.name.toLowerCase().indexOf('student') > -1 ){
//only required the students avilable projects
$scope.projects = $scope.projects.concat(filteredProject)
}
})
})
});
Hre is the Plunker
EDIT :
using concat you will get object structure like this as per your requirement.
[ {"name":"one", "PhaseIds":[
{id:"1",name:"school"},
{id:"2",name:"student"},
{id:"3",name:"teacher"}
]},
{"name":"three", "PhaseIds":[
{id:"1",name:"school"},
{id:"2",name:"student"}
]}
]
And using push you will get like this
[0: [{
"name": "one",
"PhaseIds": [{
id: "1",
name: "school"
},
{
id: "2",
name: "student"
},
{
id: "3",
name: "teacher"
}]
}],
1: [{
"name": "three",
"PhaseIds": [{
id: "1",
name: "school"
},
{
id: "2",
name: "student"
}]
}]]

"Conroller as" with ng-repeat with array of objects (does not work with 'this')

I noticed that for me this shows nothing in ng-repeat:
<ul ng-controller="UserCtrl as ctrl">
<li ng-repeat="user in ctrl.users">
{{user.name}}
</li>
</ul>
But this, works ok:
<ul ng-controller="UserCtrl">
<li ng-repeat="user in users">
{{user.name}}
</li>
</ul>
Why is that?
My Controller code is simple as that:
angular.module('main.controllers').controller('UserCtrl', ['$scope', 'UserResource', function UserCtrl($scope, UserResource) {
$scope.users = UserResource.list(); // works with $resource service
// ideally I would like type "var users = ..." without using $scope
var ctrl = this;
this.users = function() {
return UserResource.list();
};
return this;
}
where users are json array of objects I'm eventually getting as resolved promise result:
[
{ id: "1", name: "name1" },
{ id: "2", name: "name2" },
{ id: "3", name: "name3" }
]
Update:
The whole point is that it does not work with this.users and controller-as notation when it is wrapped in promise that I'm getting from $resource service.
return $resource(' /rest/user-api/user/:id/:action',
{id: "#id"}, //parameters default
{
list: { method: "GET", params: {action : "list"}, isArray: true},
});
In you controller you've got
this.users = function() ..
so in you view you need to execute that function to get users
<li ng-repeat="user in ctrl.users()">
this.users should be rather array like in my demo this.users2 and in that case you can use it in repeater as
<li ng-repeat="user in ctrl.users2">
var app = angular.module('app', []);
angular.module('app').service("userService", function($timeout, $q) {
this.getData = function() {
var deffered = $q.defer();
$timeout(function() {
var arr = [{
id: 1,
name: "Jack from Service"
}];
deffered.resolve(arr);
}, 2000);
return deffered.promise;
};
return this;
});
angular.module('app').controller('UserCtrl', ['userService',
function UserCtrl(userService) {
// ideally I would like type "var users = ..." without using $scope
var ctrl = this;
ctrl.users = function() {
return [{
id: 1,
name: "Jack Function"
}];
};
ctrl.users2 = [{
id: 1,
name: "Jack Array"
}];
////// users from service
this.usersFromService = [];
function activate() {
userService.getData().then(function(data) {
angular.copy(data, ctrl.usersFromService);
});
}
activate();
return this;
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<ul ng-controller="UserCtrl as ctrl">
<li ng-repeat="user in ctrl.users2">
{{user.name}}
</li>
<li ng-repeat="user in ctrl.usersFromService">
{{user.name}}
</li>
</ul>
</body>
My answer is that:
When I do this:
<ul ng-controller="UserCtrl as ctrl">
<li ng-repeat="user in ctr.users">
It does not work.
When I do this:
<ul ng-controller="UserCtrl as userCtrl">
<li ng-repeat="user in userCtrl.users">
or UserCtrl as a or UserCtrl as b ... - it works.
I just does not like ctrl as a name.
Thanks to all who were not voting "close". I can NOT explain how it differs from that I got as replies. In my case I use end-to end angular - NodeJS application that actually does whole client-server communication. Not sure it matters.
Maybe it clashes with another scopes.. I'm not sure yet. But the general advice - try to change the name after "as" and see what happen If you have issue like that. I know it's weird.

Resources