AngularJS: How to create routes with ui-router for my application - html

I have a problem with my a tag - I have a page that present data according to the GET vars.
For example - /foo.php?opt=1 will show table of cities that each one will go to - /foo.php?city=4 that have table of schools that go to /foo.php?school=4 that show table of students etc..
The problem is that the first time it works - when I choose city it will show me the list of schools and change the url, but when I choose school, it changes the URL but I still see the city table, and only if I press F5 it will show me table students.
This is the code:
odinvite.php:
<?php
if (isset($_GET['city']))
{
include "odbycity.php";
}
else if (isset($_GET['school']))
{
include "odbyschool.php";
}
else
{
include "odshowcities.php";
}
?>
odshowcities.php:
<div ng-controller="allcities">
<button class="btn btn-info" ng-repeat="x in names">
<a href="/odinvite.php?city={{x.areaid}}">
{{x.areaname}}</a>
</button>
</div>
odbyschool.php:
<div ng-controller="odbycity">
<button class="btn btn-info" ng-repeat="x in names">
<a href="/odinvite.php?school={{x.schoolid}}">
{{x.school_name}}</a>
</button>
</div>
MyAngular.js:
var myApp = angular.module('myApp',[]);
myApp.config(function( $locationProvider) {
$locationProvider.html5Mode(true);
});
myApp.controller ('allcities', function ($scope, $http)
{
$http.get("fetch_json_sql.php?option=1")
.then(function (response)
{
$scope.names = response.data.result;
});
console.log($scope.names);
});
myApp.controller ('odbycity', function ($scope, $http, $location)
{
$scope.cityid=$location.search().city;
console.log($scope.cityid);
$http.get("fetch_json_sql.php?option=2&cityid="+$scope.cityid)
.then(function (response)
{
$scope.names = response.data.result;
});
});
myApp.controller ('odbyschool', function ($scope, $http ,$location)
{
$scope.schoolid = $location.search().school;
console.log($scope.schoolid);
$http.get("fetch_json_sql.php?option=4&schoolid="+$scope.schoolid)
.then(function (response)
{
$scope.names = response.data.result;
});
});
What can be the problem?
I tried to make 100% change of the URL - link and it didn't work. just changed the URL without redirect.
Thanks!

You should stop rendering your templates with a backend. AngularJS is for SPA. If you need data provided by a backend try to implement an API e.g. a RESTful API. you need to configure your routes for example like in this runnable demo plnkr. It uses ui-router. Please note, this is just a demo. You should be able to put your logic into that prototype. I prepared all routes you need by using some dummy data. Just include your existing API in the controllers and you should be fine.
var myApp = angular.module("myApp", ['ui.router']);
myApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/main");
$stateProvider
.state("main", {
url: "/main",
templateUrl: "main.html"
})
.state("main.listSchools", {
url: "/listSchools/:schoolId",
templateUrl: "schools.html"
})
.state("main.listAreas", {
url: "/listAreas/:areaId",
templateUrl: "areas.html"
});
});
myApp.controller('mainMenuController', function ($scope) {
$scope.schools = [{
schoolid: 1,
name: 'Test School 1'
},{
schoolid: 5,
name: 'Test School 5'
},{
schoolid: 11,
name: 'Test School 11'
}];
$scope.areas = [{
areaid: 3,
name: 'Test area 3'
},{
areaid: 7,
name: 'Test area 7'
},{
areaid: 19,
name: 'Test area 7'
}];
});
myApp.controller('listSchoolController', function ($scope, $state) {
$scope.schoolId = $state.params.schoolId;
});
myApp.controller('listAreaController', function ($scope, $state) {
$scope.areaId = $state.params.areaId;
});

Related

templateUrl changes when refresh or reload page in AngularJS

I am using angular packet template. Here 11 pages loaded and 11 different buttons like the following:
Here is the route code:
state('app.pagelayouts.fixedsidebar1', {
url: "/fixed-sidebar",
templateUrl: "assets/views/page-1.html",
resolve: loadSequence('d3', 'ui.knob', 'countTo', 'dashboardCtrl'),
title: 'Fixed Sidebar',
ncyBreadcrumb: {
label: 'Fixed Sidebar'
},
controller: function ($scope) {
$scope.setLayout();
$scope.app.layout.isSidebarFixed = true;
$scope.$on('$routeChangeSuccess',function(){
$scope.templateUrl = $route.current.templateUrl;
})
}
})
.state('app.pagelayouts.fixedsidebar2', {
url: "/fixed-sidebar",
templateUrl: "assets/views/page-2.html",
resolve: loadSequence('d3', 'ui.knob', 'countTo', 'dashboardCtrl'),
title: 'Fixed Sidebar',
ncyBreadcrumb: {
label: 'Fixed Sidebar'
},
controller: function($scope) {
$scope.setLayout();
$scope.app.layout.isSidebarFixed = true;
}
}).
page-3.html, page-4.html and so on....
Suppose I am in page-1.html, when I refresh it doesn't stay in page-1. Goes to another page. But it should be stay at page-1.html. The templateUrl is changing.
How can i fix it ?
One obvious problem is that you have same url for all the routes.
You should update it with a parameter indicating the template to load, so that when page is refreshed, UI Router knows which state to activate based on the url. For example:
state('app.pagelayouts.fixedsidebar1', {
url: "/fixed-sidebar/1",
templateUrl: "assets/views/page-1.html",
resolve: loadSequence('d3', 'ui.knob', 'countTo', 'dashboardCtrl'),
title: 'Fixed Sidebar',
ncyBreadcrumb: {
label: 'Fixed Sidebar'
},
controller: function($scope) {
$scope.setLayout();
$scope.app.layout.isSidebarFixed = true;
}
});
If all your routes are similar, you can create a single route with a param like:
state('app.pagelayouts.fixedsidebar', {
url: "/fixed-sidebar/:id",
templateUrl: function($stateParams) {
return "assets/views/page-" + $stateParams.id + ".html";
},
resolve: loadSequence('d3', 'ui.knob', 'countTo', 'dashboardCtrl'),
title: 'Fixed Sidebar',
ncyBreadcrumb: {
label: 'Fixed Sidebar'
},
controller: function($scope) {
$scope.setLayout();
$scope.app.layout.isSidebarFixed = true;
}
});

Launching modal on parent from a directive

I have a view with a ui.bootstrap modal that has its own controller.
In the view, i have a directive that generates a number of buttons with a unique ID.
I want to be able to click on one of the buttons generated and call the main view's controller to launch the modal.
Here is the main view module:
/* global angular */
angular.module('my.jobs', [
'ui.router',
'ui.bootstrap'
])
.controller('DashboardJobsCtrl', function DashboardJobsController($rootScope, $scope, $log, $state, $modal) {
var self = this;
angular.extend(this, {
displayReceipt: function(jobId) {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'receiptModal.html',
size: 'lg',
controller: function($scope, $modalInstance, jobsService) {
//CODE HERE FOR ADDING VALUES TO THE MODAL...
$scope.clear = function() {
$modalInstance.close();
};
}
});
}
});
});
Here is the directive:
angular.module('jobView', ['ui.router', 'ui.bootstrap'])
.directive('jobView', function($compile, $http, $templateCache, DOMAINS) {
return {
restrict: 'E',
scope: {
job: '=',
view: '#'
},
template: 'myTemplate.html',
link: function($scope, element, attrs) {
//ASSUME THERE IS CODE HERE FOR GENERATING UNIQUE ID FOR JOBS
//NEXT LINE I WANT TO CALL MODAL FROM THE MAIN VIEW MODULE
$scope.displayReceipt('jobId')
}
};
});
I know this is a simple scope issue, but it's driving me nuts that I can't make the connection.
Here is the perfect example. calling method of parent controller from a directive in AngularJS.
I have update your example below.
<job-View updateParent='displayReceipt()'></job-View>
angular.module('jobView', ['ui.router', 'ui.bootstrap'])
.directive('jobView', function($compile, $http, $templateCache, DOMAINS) {
return {
restrict: 'E',
scope: {
job: '=',
view: '#',
updateParent:'&'
},
template: 'myTemplate.html',
link: function($scope, element, attrs) {
//ASSUME THERE IS CODE HERE FOR GENERATING UNIQUE ID FOR JOBS
//NEXT LINE I WANT TO CALL MODAL FROM THE MAIN VIEW MODULE
$scope.displayReceipt('jobId')
}
};
});

How to pass data between pages in Ionic app

I have had a look at all the examples around and tried to integrate with my Ionic project and failed. Here is what I have so far.
I am using a project created using creator.ionic.com
I have an html page that im loading a JSON file into
(agentSchedule.html)
<ion-view style="" title="Agent Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
<ion-refresher on-refresh="doRefresh()">
</ion-refresher>
<div ng-controller="agentScheduleCtrl">
<ion-list style="">
<ion-item class="item-icon-right item item-text-wrap item-thumbnail-left" ng-repeat="user in users">
<img ng-src="{{ user.image }}">
<h2>{{ user.fname }} {{ user.lname }}</h2>
<h4>Role : {{ user.jobtitle }}</h4>
<h4>Username : {{ user.username }}</h4><i class="button-icon icon ion-ios-arrow-forward"></i>
</ion-item>
</ion-list>
</div>
</ion-content>
Here is the controller and routes for that page
.controller('agentScheduleCtrl', function($scope, $http, $timeout) {
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$scope.users = response;
});
.state('menu.agentSchedule', {
url: '/page4',
views: {
'side-menu21': {
templateUrl: 'templates/agentSchedule.html',
controller: 'agentScheduleCtrl'
}
}
})
I am another page that I want to pass the username to, and then use on any page that I go from there
(specificAgentDetails.html)
<ion-view style="" view-title="Agent Specific Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
</ion-content>
</ion-view>
Here is the controller and routes for that page
.controller('specificAgentDetailsCtrl', function($scope) {
})
.state('menu.specificAgentDetailsCtrl', {
url: '/page9',
views: {
'side-menu21': {
templateUrl: 'templates/specificAgentDetailsCtrl.html',
controller: 'specificAgentDetailsCtrl'
}
}
})
How to Pass the user.username JSON variable to the next page as a global variable ??
Any help would be awesome - im going around in circles
So what #shershen said is true most ionic apps are set up as SPA's, what you're going to do isn't a "ionic" thing it's more of a AngularJS thing. You're going to want to setup a Service to hold your User info and then share it with your other controllers.
Create a Factory to share the data.
Inject the factory into the first controller and set it.
Inject the factory into the second controller and retrieve it.
Share data between AngularJS controllers
If you're familiar with get/set in OOP you should have no problem.
.factory('Data', function () {
var user = {};
return {
getUser: function () {
return user;
},
setUser: function (userparameter) {
user = userparameter;
}
};
})
.controller('agentScheduleCtrl', function($scope, $http, $timeout, Data) {
var url = "http://www.otago.ac.nz/itssdschedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
Data.setUser(response);
$scope.users = response;
});
Then in your second controller:
.controller('specificAgentDetailsCtrl', function($scope, Data) {
$scope.user = Data.getUser();
})
Make sure the syntax between the view and controllers are correct. I'm using user you're using users, setup breakpoints in your controllers to see what's going on there.
I use a little generic factory to do the job.
.factory('LocalRepo', function () {
var data = {}
return {
Get: function (key) {
return data.key;
},
Set: function (key, val) {
return data.key = val;
}
}
})
.controller('One', function($scope, LocalRepo) {
//Set in first controller
//TODO: $scope.users = .... from your call
LocalRepo.Set('users', $scope.users);
})
.controller('Two', function($scope, LocalRepo) {
//Get in second controller
$scope.users = LocalRepo.Get('users');
})
Use it to set whatever you want between controllers
Here is a quite simple solution. use $window and it will hold the data globally available for all controllers, services or anything etc.
.controller('agentScheduleCtrl', function($scope, $http, $timeout,$windows) {
$window.users = [];
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$window.users = response;
});
})
Inject $window as dependency in other controller and you can access it like $window.users.
Hope it helps someone.

AngularJS same html site for insert and update

This one is going to be a long one :)
So here is the idea, I wanna use same html page for two controllers , problem is , that page in insert state wont load , because of ng-repeat="employee in employee" because its non existent in insert controller.
What my repeater does it just fills textboxes , it doesnt repeat anything , its just a single form and it fills information of that one single employee , am i doing this wrong ?
employeeUpdate works like a charm , problem is in employeeInsert , is there a posibility that it can fill textboxes without ng-repeat part , because it does not work without it , but it does fill comboBox/select options without it.
.state('employeeUpdate', {
url: '/employeeUpdate?employeeCode=:param1',
templateUrl: 'pages/employeeUpdate.html',
controller: 'employeeUpdateCtrl',
resolve: {
employeeGatherAll: ['$http', function ($http) {
return $http.jsonp("webserviceSite&procedureName=wsEmployeeGatherAll 'param','param'&callback=JSON_CALLBACK")
.success(function (response) {
return (response)
}).error(function (response) {
console.log("failed");
});
}],
employeeSelectByCode: ['$http','$location', function ($http, $location) {
var employeeCode = $location.search().employeeCode
return $http.jsonp("webServiceSite&procedureName=wsEmployeeSelectByCode 'paramet','parame','" + employeeCode + "'&callback=JSON_CALLBACK")
.success(function (response) {
return (response)
}).error(function (response) {
console.log("failed");
});
}]
}
})
.state('employeeInsert', {
url: '/employeeInsert',
templateUrl: 'pages/employeeUpdate.html',
controller: 'employeeInsertCtrl',
resolve: {
employeeGatherAll: ['$http', function ($http) {
return $http.jsonp("webServiceSiteUrl&procedureName=wsEmployeeGatherAll 'parametar','parametar'&callback=JSON_CALLBACK")
.success(function (response) {
return (response)
}).error(function (response) {
console.log("failed");
});
}],
}
})
So i have selectView as well , where i list all employees, and on click i go to employeeUpdate where i send code trough url as well , my html employeeUpdate page looks something like this :
<div ng-repeat="employee in employee">
<div class="col-md-4">
<label>Employee code</label>
<input type="text" class="form-control" id="txtEmployeeCode" ng-model='employee.employeeCode' />
</div>
<div class="col-md-4">
<label>Status</label>
<select id="Select3" class="form-control" ng-model="employee.statusCode" ng-options="item.code as item.name for item in employeeGather.status">
<option value="">Select status</option>
</select>
</div>
</div>
And these are the controllers
angular
.module('app')
.controller('employeeUpdateCtrl', ['$scope', 'employeeGatherAll', 'employeeSelectByCode', function ($scope, employeeGatherAll, employeeSelectByCode) {
$scope.employee = employeeSelectByCode.data.employee;
$scope.employeeGather = employeeGatherAll.data
}])
.controller('employeeInsertCtrl', ['$scope', 'employeeGatherAll', function ($scope, employeeGatherAll) {
$scope.employeeGather = employeeGatherAll.data
}])
employee.SelectByCode.data.employee[0] was the soulution , without ng-repeat

Angularjs UI-router not working and no error message

I'm new to angularjs and I'm trying to set up my ui-routes. When I go to the page, I click on the button that sends you to the route and nothing happens (not even an error message). This is what my routing configure looks like ...
var route = angular.module('route', ["ui.router", 'ngResource'])
// configure the routing
route.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
// send to profile page
$urlRouterProvider.otherwise("/user_stats");
$stateProvider
// route for personal info
.state('index', {
url: "/user_stats",
templateUrl : "statistics/user_stats.html" ,
controller : 'user_statsController'
})
});
And this is my html file with the button and view
<!-- navigation bar -->
<div class="wrapper" ng-controller="HeaderController" style="margin-top:8px">
<ul class="nav nav-pills">
<li ng-class="{ active: isActive('/user_stats')}"> <a ui-sref="user_stats"><span class="glyphicon glyphicon-eye-open"></span> Statistics</a></li>
</ul>
</div>
<!-- route veiw -->
<div class="container" id="route" style="width:90%">
<div ui-view></div>
</div>
Any ideas? Thanks in advanced
I think the comment //route for personal info looks in an odd position and I also prefer this to declare routes:
$stateProvider.when('/', {
url: "/user_stats",
templateUrl : "statistics/user_stats.html" ,
controller : 'user_statsController'
}).otherwise({ redirectTo: '/' });
You have to do some work on configuration. see the code sample below
route.config(['$routeProvider', '$locationProvider', '$stateProvider', function ($routeProvider, $locationProvider, $stateProvider) {
var home = {
name: 'home',
controller: 'HomeController',
templateUrl: '../shell/home.html',
pageTitle: ''
},
login = {
name: 'login',
controller: 'loginController',
templateUrl: '../../authentication/login.htm',
pageTitle: ''
},
signatories = {
name: 'signatories',
controller: 'SignatoriesCtrl',
templateUrl: '../signature/signatories.htm',
pageTitle: "Signatories"
};
$stateProvider.state(home);
$stateProvider.state(login);
$stateProvider.state(signatories);
$locationProvider.html5Mode(true);
} ]).run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
} ]).controller('RootController', ['$scope', '$route', '$routeParams', '$location', '$state', function ($scope, $route, $routeParams, $location, $state) {
} ]);