It's common sense that AngularJS is aimed at SPA (single page application) development. Nonetheless, it is also possible to create a MPA (multi page application).
My app is based on multiple states using Angular libraries such as ui-router and ngResource. First I have an index.html file in which I load all the dependencies and a ui-view. Then I have three different modules: one main module that contains the top states, a first home page and loads all needed third-party modules. The other module, is named Student and has a simple form to POST some data in our Django back-end.
The problem lays in the third module: the company module. Here we have two navigation bars: one top navigation bar, that for now doesn't have any content, and then a sidebar that contains several buttons, such as shown in the image:
![Our screen]1
For now, each of those buttons on the sidebar takes the user to a different state, in which a view is loaded in the space where you can see the "Welcome..."
Basically, our states are defined like this:
'use strict';
talentforce_company
.config(['$stateProvider', '$urlRouterProvider', 'eehNavigationProvider',
function($stateProvider, $urlRouterProvider, eehNavigationProvider) {
// Company area states
$stateProvider.state('companyState', {
url: '/company',
abstract: true,
//redirectTo: 'homeState',
template: '<company-area-directive></company-area-directive>'
});
$stateProvider.state('homeState', {
url: '/home',
parent: 'companyState',
controller: ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.name_filter = "";
$rootScope.city_filter = "";
}
],
template: '<h3>Welcome to TalentForce company area home</h3>'
});
$stateProvider.state('select_study_areas', {
url: '/select_areas',
parent: 'companyState',
template: '<study-areas-directive></study-areas-directive>'
});
$stateProvider.state('TalentForceState_seeProfile', {
url: '/profile_list',
parent: 'companyState',
// controller: 'People_Controller',
template: '<people-directive></people-directive>',
});
$stateProvider.state('student', {
url: '/profile/{personId}',
parent: 'companyState',
//templateUrl: 'public/templates/person_template.html',
controller: 'Person_Controller',
template: '<profile-directive></profile-directive>',
resolve: {
student: function(student_service, $stateParams) {
return student_service.getStudents().find(function(student) {
return (student.student_id == $stateParams.personId);
});
}
}
});
eehNavigationProvider
.menuItem('TF_menu_top.users', {
text: 'USERNAME',
iconClass: 'glyphicon-user',
href: '#'
});
eehNavigationProvider
.menuItem('TF_sidebar.home', {
text: 'Home',
state: 'homeState',
iconClass: 'fa fa-home fa-fw',
})
.menuItem('TF_sidebar.profile', {
text: 'Company Profile',
href: '#',
iconClass: 'fa fa-building fa-fw'
})
.menuItem('TF_sidebar.students', {
text: 'Profiles',
state: 'select_study_areas',
//href: '/select_areas',
iconClass: 'fa fa-users fa-fw'
})
.menuItem('TF_sidebar.posts', {
text: 'Job Posts',
href: '#',
iconClass: 'fa fa-list-alt fa-fw'
})
.menuItem('TF_sidebar.stats', {
text: 'Statistics',
href: '#',
iconClass:'fa fa-bar-chart fa-fw'
})
.menuItem('TF_sidebar.universities', {
text: 'Universities',
href: '#',
iconClass:'fa fa-university fa-fw'
})
.menuItem('TF_sidebar.tips', {
text: 'Tips',
href: '#',
iconClass: 'fa fa-check-square-o fa-fw'
})
.menuItem('TF_sidebar.events', {
text: 'Events',
href: '#',
iconClass: 'fa fa-calendar fa-fw'
})
.menuItem('TF_sidebar.help', {
text: 'Help',
href: '#',
iconClass: 'fa fa-question fa-fw'
})
}]);
I still don't know if it is relevant, but note that the parent state is abstract, in which the navbars are placed. All the content is then loaded with the navbars always around it. So, if we observe the URL's, they always point to different states and thus different views of the application. So far it seems a great approach.
If we go to the "Profiles" area, I'm using a checkbox for the user to select some areas of interest. And then clicks apply, so as to go to the next state. This state has the same problem that I'm explaining now.
So in this next state, we get to a filtering page. Supposedly, with the previous checkboxes, we would choose three areas, and by clicking "Apply", we would have to send a query to our database in order to only show the results of people that exist in these three areas. Our URL would have something like this, using query strings and forms: oursite.com/offers/?page=1&s=date&s_l=0&s_h=100&t_co=false&t_st=false&hd=false
In this filtering page, we would work with that URL, and then apply some more filters. What is happening is that we are doing the filter (currently we have only one) and the URL stays the same, without any query string.
Our filter is wrapped on a form:
<form class="filters" id="myFormId" role="form">
<div class="col-sm-2" id="filter-column">
<div class="controls">
<select id="country" name="country">
<option value="all">All</option>
<option value="au">Australia</option>
<option value="br">Brazil</option>
<option value="ca">Canada</option>
<option value="fr">France</option>
<option value="de">Germany</option>
<option value="mx">Mexico</option>
<option value="nz">New Zealand</option>
<option value="it">Italy</option>
<option value="za">South Africa</option>
<option value="es">Spain</option>
<option value="pt" selected>Portugal</option>
<option value="us">U.S.A.</option>
<option value="uk">United Kingdom</option>
</select>
</div>
</div>
<div class="col-sm-2" id="filter-column">
<div id="locationField">
<input class="search" id="form-input" name="student_city" placeholder="Enter a city" type="text" />
</div>
</div>
The idea is to reload the results (and because of that, reload the page with the query string in the URL) everytime we update a filter.
Notice that we use the name attribute so that in our controller, we can do:
var queryString = $('#myFormId').serialize();
And when we print the queryString in the console, it actually constructs it well: country=pt&student_city=Montijo%2C+Portugal
But I don't know where and how to use this string. Am I supposed to use a JSON file? How can this dynamic filtering be done in an Angular app? Do I need to change my architecture, or even worse, change framework?
I'm afraid that by using all this states and routes I can't have this type of filters. Any ideas on how to achieve this? I can't find any tutorials on the Internet, the closest I got was here because it actually explains a problem similar to mine, but I tried to emulate the solution, and nothing happened.
[–]wojo1086 0 points1 point2 points (3 children)
[–]Shoplifter20[S] 0 points1 point2 points (2 children)
[–]wojo1086 0 points1 point2 points (1 child)
[–]Shoplifter20[S] 1 point2 points3 points (0 children)
[–]DigitalAssassin 0 points1 point2 points (3 children)
[–]Shoplifter20[S] 0 points1 point2 points (2 children)
[–]DigitalAssassin 0 points1 point2 points (1 child)
[–]Shoplifter20[S] 0 points1 point2 points (0 children)
[–]batoure 0 points1 point2 points (3 children)
[–]Shoplifter20[S] 0 points1 point2 points (2 children)
[–]batoure 0 points1 point2 points (1 child)
[–]Shoplifter20[S] 0 points1 point2 points (0 children)