angular click on id should route to different page - javascript

Hi im new to angular and i have json data . SO when i click on Id obtained from json, it should route to different page. How should i do it
Head.html
</head>
<body ng-app="MyApp" ng-controller="MyController">
<table border="1" style="width:100%">
<tr >
<td href=#home>id</td>
<td>first_name</td>
<td>dateBirth</td>
<td>currentCountry</td>
</tr>
<tr ng-repeat="x in list">
<td>{{x.id}}</td>
<td>{{x.first_name}}</td>
<td>{{x.dateBirth}}</td>
<td>{{x.currentCountry}}</td>
</tr>
</table>
</body>
script.js
var app= angular.module("MyApp", []);
app.controller('MyController', function($scope,$http) {
$http({
method: "GET",
url: "http://192.168.1.1:8080/administrator/"
}).then(function mySucces(response) {
$scope.list = response.data;
console.log($scope.list)
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
});
my plunker http://plnkr.co/edit/Gpmsc7pb1gfWx3EgKk6s?p=preview
Any help is appreciated

There are various options to achieve what you are asking, using$routeProvider,$stateProvider and ng-click or ui-sref within that to achieve the navigation through id. I will go through a simple example using $stateProvider.
I will have 3 views to mock what you have provided:
header.html: which contains your ng-repeat to show the tabular data and whereby we have the click in the id to navigate.
first.html: if user clicks 1 in the id column, it is navigated to first.html
second.html: if user clicks 2 in the id column, it is navigated to second.html
Your JS:
var app = angular.module('nested', ['ui.router']);
app.config(function($stateProvider,$locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider.state('top', {
url: "",
templateUrl: "header.html",
controller: 'MyController'
})
.state('first', {
url: '/app/:id',
templateUrl: "first.html",
controller: 'FirstController'
})
.state('second', {
url: '/app/:id',
templateUrl: "second.html",
controller: 'SecondController'
})
});
app.controller('MyController', function($scope,$state) {
/*//commented this part so that you can work on it later.
$http({
method: "GET",
url: "http://192.168.1.134:8080/administrator/%20ApplicationList.json"
}).then(function mySucces(response) {
$scope.list = response.data;
console.log($scope.list)
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
*/
$scope.list = [{'id':1,'first_name':'alex','dateBirth':'18th march','currentCountry':'Nepal'},
{'id':2,'first_name':'rumba','dateBirth':'18th march','currentCountry':'USA'}
]
$scope.navigate = function(id){
if(id==1){
$state.go('first',{id:1});
}
else if(id==2){
$state.go('second',{id:2});
}
}
});
app.controller('FirstController', function($scope,$state) {
console.log(JSON.stringify($state.params));
$scope.params = $state.params;
});
app.controller('SecondController', function($scope,$state) {
console.log(JSON.stringify($state.params));
$scope.params = $state.params;
});
In this PLUNKER example, i have even provided how you pass params through controller:
http://plnkr.co/edit/n8p7ycV7k5rsn1f3bQcT?p=preview

You can add a ng-click attribute to your hyperlink tag like this
<td><a href="name.html" ng-click='displayFunc(x.id)'>{{x.id}}</a></td>
Now you can define this function in controller
$scope.displayFunc = function(id)
{
//Do something with id..
$location.path('/some route');
}
Don't forget to inject $location dependency in controller.

Related

AngularJS - Load Controller asynchronously From AJAX Without Changing Route

I want to dynamically load an angular controller upon an ajax call that renders a new view(HTML).
Here is what i have:
example of a view. HTML Snippet From AJAX
<!-- CVS Pharmacy Extracare - Add View -->
<div ng-controller="cvsViewCtrl" class="container-fluid">
<div class="col-md-8 col-md-offset-2">
<h3 id="asset-title" class=""></h3>
<br>
<p>Member ID</p>
<input class="input-s1 block-elm transition" type="text" placeholder=""/>
<br>
<input class="add-asset-btn btn btn-success block-elm transition" type="button" value="Add Asset!" ng-click="prepareCVS();"/>
</div>
</div>
the separate script that pertains to the view
App.controller('cvsViewCtrl', ['$scope', '$http', function($scope, $http){
console.log('cvs view loaded');
$scope.prepareCVS = function() {
console.log('admit one');
}
}]);
and the function that loads them
$scope.setAddAssetView = function(a) {
console.log(a);
if($scope.currentAddView == a) {
console.log('view already set');
return;
}
$scope.currentAddView = a;
$('#main-panel').html('');
$http({
method: 'POST',
url: '/action/setaddassetview',
headers: {
'Content-Type': 'application/json',
},
data: {
asset: a,
}
}).then(function(resp){
// Success Callback
// console.log(resp);
var index = resp.data.view.indexOf('<s');
var script = resp.data.view.slice(index);
var html = resp.data.view.replace(script, '');
$('#main-panel').html( html );
$('#asset-title').text(a.name);
var indexTwo = a.view.indexOf('/add');
var scriptLink = insertString(a.view, indexTwo, '/scripts').replace('.html', '.js').replace('.', '');
console.log( scriptLink );
window.asset = a;
$.getScript(scriptLink, function(data, textStatus, jqxhr){
console.log('loaded...');
})
},
function(resp){
// Error Callback
console.log(resp);
});
}
when $.getScript runs, the script gets loaded successfully but it doesn't initialize the controller. i even tried:
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = scriptLink;
s.innerHTML = null;
s.id = 'widget';
document.getElementById('switch-script').innerHTML = '';
document.getElementById('switch-script').appendChild( s );
this appends the script with the right link but still doesn't get initialized. How can i work around this?
Make this changes in your App, and be sure to load the controller file before the html with ng-controller rendered.
var App = angular.module("app", [...]);
App.config(["$controllerProvider", function($controllerProvider) {
App.register = {
controller: $controllerProvider.register,
}
}]);
App.register.controller('cvsViewCtrl', ['$scope', '$http', function($scope, $http){
console.log('cvs view loaded');
$scope.prepareCVS = function() {
console.log('admit one');
}
}]);
That would actually not be the right way to handle things.
If you use ui-router for routing, you can load the controller in the resolve function. A good service for that is ocLazyLoad.
That can be done as follows:
var app = angular.module('myApp', [
'ui.router',
'oc.lazyLoad',
]);
angular.module('myApp').config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/views/main.view.html',
controller: 'mainCtrl',
resolve: {
loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load('app/ctrls/main.ctrl.js');
}],
}
})
.state('second', {
url: '/second',
templateUrl: 'app/views/second.view.html',
controller: 'secondCtrl',
resolve: {
loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load('app/ctrls/controller_TWO.ctrl.js');
}],
}
})
});
When you're changing from one route to another, resolve will be triggered before the html is loaded and the controller will be registered properly.

Data for listing page and detail page without 2 API calls

I have set up a service to return a listing of clients from my API. Using UI-router, I can successfully pass a client's id to the details state - however, it seems unnecessary here to make another API call to retrieve a single client when I have all the necessary data in my controller.
What is the best way to use the ID in my detail state URL to show data for that client? Also - if a user browses directly to a client detail URL - I'll need to then make a call to the API to get just that client data - or is there a better way?
EDIT: I am not looking to load the two views on the same 'page', but completely switch views here, from a listing page to a detail page.
Routes in App.js
$stateProvider
.state('root', {
abstract: true,
url: '',
views: {
'#': {
templateUrl: '../partials/icp_index.html',
controller: 'AppController as AppCtrl'
},
'left-nav#root': {
templateUrl: '../partials/left-nav.html'
},
'right-nav#root': {
templateUrl: '../partials/right-nav.html'
},
'top-toolbar#root': {
templateUrl: '../partials/toolbar.html'
}
/*'footer': {
templateUrl: '../partials/agency-dashboard.html',
controller: 'AppController as AppCtrl'
}*/
}
})
.state('root.clients', {
url: '/clients',
views: {
'content#root': {
templateUrl: '../partials/clients-index.html',
controller: 'ClientsController as ClientsCtrl'
}
}
})
.state('root.clients.detail', {
url: '/:clientId',
views: {
'content#root': {
templateUrl: '../partials/client-dashboard.html',
//controller: 'ClientsController as ClientsCtrl'
}
}
})
// ...other routes
Service, also in app.js
.service('ClientsService', function($http, $q) {
this.index = function() {
var deferred = $q.defer();
$http.get('http://api.icp.sic.com/clients')
.then(function successCallback(response) {
console.log(response.data);
deferred.resolve(response.data);
},
function errorCallback(response) {
// will handle error here
});
return deferred.promise;
}
})
And my controller code in ClientsController.js
.controller('ClientsController', function(ClientsService) {
var vm = this;
ClientsService.index().then(function(clients) {
vm.clients = clients.data;
});
});
And finally, my listing page clients-index.html
<md-list-item ng-repeat="client in ClientsCtrl.clients" ui-sref="clients-detail({clientId : client.id })">
<div class="list-item-with-md-menu" layout-gt-xs="row">
<div flex="100" flex-gt-xs="66">
<p ng-bind="client.name"></p>
</div>
<div hide-xs flex="100" flex-gt-xs="33">
<p ng-bind="client.account_manager"></p>
</div>
</div>
</md-list-item>
You can use inherited states like suggested here.
$stateProvider
// States
.state("main", {
controller:'mainController',
url:"/main",
templateUrl: "main_init.html"
})
.state("main.details", {
controller:'detailController',
parent: 'main',
url:"/:id",
templateUrl: 'form_details.html'
})
Your service does not change.
Your controllers check if the Model has been retrieved:
app.controller('mainController', function ($scope, ClientsService) {
var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
promise.then(function(data){
$scope.Model = data;
});
})
app.controller('detailController', function ($q, $scope, ClientsService, $stateParams) {
var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
promise.then(function(data){
$scope.Model = data;
$scope.Item = data[$stateParams.id];
});
})
See
http://plnkr.co/edit/I4YMopuTat3ggiqCoWbN?p=preview
[UPDATE]
You can also, if you must, combine both controllers:
app.controller('mainController', function ($q, $scope, ClientsService, $stateParams) {
var promise = $scope.Model ? $q.when($scope.Model) : ClientsService.index();
promise.then(function(data){
$scope.Model = data;
$scope.Item = data[$stateParams.id];
});
})
I would change the service to cache the data. With $q.when() you can return a promise from a variable. So you save your response in a variable, and before doing the API call you check if the cache has been set. If there is any cache, you return the data itself. Otherwise, you do the usual promise call.
.service('ClientsService', function($http, $q) {
var clients = null;
this.getClient = function(id) {
if (clients !== null) {
return $q.when(id ? clients[id] : clients);
}
var deferred = $q.defer();
$http.get('http://api.icp.sic.com/clients').then(function(response) {
clients = response.data;
deferred.resolve(id ? clients[id] : clients);
}, function (response) {
// will handle error here
});
return deferred.promise;
}
})

RouteParams in AngularJS not working

I am trying to pass a routeParam to a $http.get in my Angular controller, but I am not getting data displayed.
Here is what I have below. Am I not using the $routeParams correctly?
link to JSON Data is http://enrolin.in/test/login.php?p=fetchone&&id=50
I need to pass the value of id dynamically.
Here is my angularJS code:
var app = angular
.module("Demo", ["ngRoute"])
.config(function ($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "templates/home.html",
controller: "homeController"
})
.when("/courses", {
templateUrl: "templates/courses.html",
controller: "coursesController"
})
.when("/students/:id", {
templateUrl: "templates/studentDetails.html",
controller: "studentDetailsController"
})
.otherwise({
redirectTo: "/home"
})
})
.controller("homeController", function ($scope) {
$scope.message = "Home Page";
})
.controller("coursesController", function ($scope) {
$scope.courses = ["C#", "VB.NET", "ASP.NET", "SQL Server"];
})
})
.controller("studentDetailsController", function ($scope, $http, $routeParams) {
$http({
url: "http://enrolin.in/test/login.php?p=fetchone&&id=",
method: "get",
params: { id: $routeParams.id }
}).then(function (response) {
$scope.stud = response.data;
})
})
Here is my partial page:
<h1>Student Details</h1>
<table style="border:1px solid black">
<tr>
<td>Id</td>
<td>{{stud.id}}</td>
</tr>
<tr>
<td>Name</td>
<td>{{stud.name}}</td>
</tr>
<tr>
<td>email</td>
<td>{{stud.username}}</td>
</tr>
</table>
<h4>Back to Students list</h4>
I checked using ng-inspector, When I load the page, It seems like data is being fetched but somehow not displayed. Please help.
Link to working application is http://enrolin.in/test/#/students/50

Passing return of function to another state

I have been trying to send data from one controller to another. A little background this is code being used in an ionic application if that helps any. I want the to send the data from send() function to the SubCtrl. The send function is being called in MainCtrl. I have created a service for this but the data is still not being shared. What am I missing to complete this action?
var app = angular.module('testapp', []);
app.config(function($stateProvider, $urlRouterProvider) {
"use strict";
/* Set up the states for the application's different sections. */
$stateProvider
.state('page2', {
name: 'page2',
url: '/page2',
templateUrl: 'page2.html',
controller: 'MainCtrl'
})
.state('page3', {
name: 'page3',
url: '/page3',
templateUrl: 'page3.html',
controller: 'SubCtrl'
});
$urlRouterProvider.otherwise('/page2');
});
app.factory('dataShare', function($rootScope) {
var service = {};
service.data = false;
service.sendData = function(data) {
this.data = data;
$rootScope.$broadcast('data_shared');
console.log(data);
};
service.getData = function() {
return this.data;
};
return service;
});
app.controller('MainCtrl', function($scope, $state, $http, dataShare) {
$scope.text = 'food';
$scope.send = function() {
dataShare.sendData(this.text);
};
});
app.controller('SubCtrl', function($scope, $state, dataShare) {
"use strict";
var sc = this;
$scope.text = '';
$scope.$on('data_shared', function() {
var text = dataShare.getData();
sc.text = dataShare.data;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script id="page2.html" type="text/ng-template">
<div>{text}}</div>
<input type='text' ng-model='text' />
<button class="button button-outline button-royal" ng-click="send();">add</button>
</script>
<script id="page3.html" type="text/ng-template">
<div>text: {{text}}</div>
</script>
I was able to figure this issue out after reading this page. If anyone is having a similar issue I would encourage this reading. Also the video link on this post was really helpful.

Loading URL into ng-view programatically

Referring to the code given below, I would like to be able to load viewTeam URL into ng-view from the showTeam() function. How can I do this?
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-route.min.js"></script>
<script>
var teamApp = angular.module("teamApp", ['ngRoute']);
teamApp.controller('teamController', function($scope, $http) {
$http
.get('/teams')
.success(function(response) {
$scope.teams = response;
}
);
var showTeam = function(id) {
}
});
teamApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/addTeam', {
templateUrl: 'addTeam.htm',
controller: 'AddTeamController'
}).
when('/viewTeam', {
templateUrl: 'viewTeam.htm',
controller: 'ViewTeamController'
}).
otherwise({
redirectTo: '/addTeam'
});
}]);
teamApp.controller('AddTeamController', function($scope) {
});
teamApp.controller('ViewTeamController', function($scope, $routeParams) {
});
</script>
</head>
<body>
<div ng-app = "teamApp" ng-controller="teamController">
<button ng-click="newTeam()">new</button>
<div ng-repeat="team in teams" >
Name: {{team.name}}
<br />
Description: {{team.description}}
<br />
<button ng-click="showTeam(team.id)">show</button>
</div>
<div ng-view></div>
<script type = "text/ng-template" id = "addTeam.htm">
<h2> Add Team </h2>
To be implemented later.
</script>
<script type = "text/ng-template" id = "viewTeam.htm">
Name: {{team.name}}
Description: {{team.description}}
</script>
</div>
</body>
</html>
You need to change your $routeprovider for viewTeam to expect an id parameter. Then get that id in the viewTeamController using routeparams. Here is how you do it. Just follow the pattern in the script below:
<script>
var teamApp = angular.module("teamApp", ['ngRoute']);
teamApp.controller('teamController', function($scope, $http,$location) {
$http
.get('/teams')
.success(function(response) {
$scope.teams = response;
}
);
var showTeam = function(id) {
$location.url("#/viewTeam/" + id);//there are other means as well.
}
});
teamApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/addTeam', {
templateUrl: 'addTeam.htm',
controller: 'AddTeamController'
}).
when('/viewTeam/:id', {
templateUrl: 'viewTeam.htm',
controller: 'ViewTeamController'
}).
otherwise({
redirectTo: '/addTeam'
});
}]);
teamApp.controller('AddTeamController', function($scope) {
});
teamApp.controller('ViewTeamController', function($scope, $routeParams) {
alert($routeParams.id);//you get the route params here.
});
</script>
When navigating from view:
<a href="#viewTeam/45">
In your case:
<a href="#viewTeam/{{team.id}}"> //to navigate from view.
In your teamController do this -
var showTeam = function(id) {
$location.path('/viewTeam.htm').search({'id': id});
}
In ViewTeamController you can get id like this
//Get id from url params
$location.search('id');
you can use $location to change the path
$scope.showTeam = function(view){
$location.path("/viewTeam"); // path not hash
}

Categories

Resources