How do I access the page below and show the div CertificateRegister instead of div EmailRegister via URL, for example www.mysite.com/register#CertificateRegister
eAssinatura.controller('CadastroController', ['$scope', '$route', '$routeParams', '$location', '$http', '$modal', 'blockService', 'notifyService', 'browserService', 'locale',
function ($scope, $route, $routeParams, $location, $http, $modal, blockService, notifyService, browserService, locale) {
//$scope.EmailRegister = true; // setting the div register by e-mail visible when the page loads
//$scope.CertificateRegister = false;
//$scope.showEmailRegister = function () {
// $scope.EmailRegister = true;
// $scope.CertificateRegister = false;
//};
//$scope.showCertificateRegister = function () {
// if (!$scope.LoadedPKI) { //setting PKI when register by certificate is selected
// init();
// }
// $scope.EmailRegister = false;
// $scope.CertificateRegister = true;
//};
$scope.RegisterDisplay = false;
if ($location.path() == '/CertificateRegister') {
$scope.RegisterDisplay = true;
}
}
]);
<div ng-show="RegisterDisplay">
<p>E-mail Register</p>
Don' t Have Digital Certificate »
</div>
<div ng-hide="RegisterDisplay">
<p>Certificate Register</p>
Have Digital Certificate »
</div>
At the top of your controller you can:
$scope.RegisterDisplay = false;
if ($location.path() == '/CertificateRegister') {
$scope.RegisterDisplay = true;
}
In your html you should be able to do something like this:
<div id="certregister" ng-show="RegisterDisplay">//This is your CertificateRegister div</div>
<div id="EmailRegister" ng-hide="RegisterDisplay">//This is your EmailRegister div</div>
I would try adding url variable in your route then have controller watch for that and show/hide div
If you are using ui-router you can add an optional parameter to the state, and take that parameter in your controller using the $stateProvider like this example
You probably would do something like:
$stateProvider
.state('register', {
url: "/register/:emailRegister",
templateUrl: '.html',
controller: function ($stateParams) {
// If we got here from a url of /register/true
if($stateParams.emailRegister){
$scope.showCertificateRegister();
}
}
})
Are you using $routeProvider for routing?
If so, you can create a parameter and read it in your controller.
route:
$routeProvider.when('/register/:showParam?', {...});
controller:
if ($route.current.params.showParam === 'CertificateRegister') {
$scope.CertificateRegister = true;
}
*I you should add some validations (undefined, toLowerCase)
Related
I have my body controlled by a MainController. In the body, I have another nested controller. In my index.html, I have a div element controlled by the nested controller:
index.html
<body ng-controller="MainController">
<div ng-controller="LoginController" ng-hide="isLoggedIn"></div>
<div class="navbar" ng-hide="!isLoggedIn">
<!-- A form which calls login() function inside LoginController -->
</div>
</body>
MainController:
angular.module('DemoApp')
.controller('MainController', ['$scope', function ($scope) {
$scope.isLoggedIn = false;
}]);
LoginController
angular.module('DemoApp')
.controller('LoginController', ['$scope', '$location', function ($scope, $location) {
$scope.login = function () {
if($scope.loginCredentials.username === 'username' && $scope.loginCredentials.password === 'password') {
$scope.parent.isLoggedIn = true; /* here, how to modify this variable */
$location.path('/home');
}
};
}]);
All I want to do is change the variables of MainController, which is isLoggedIn, from my nested controllers. I used $scope.parent, but it shows unknow provider parent. How to achieve this?
You need to use $parent to get the parent controller scope, then various methods and properties can be accessed.
$scope.$parent.isLoggedIn = true;
I am a total newbie in AngularJs, so please be patient with me.
I have the following angular App, which contains two controllers
(function () {
angular.module("app-machines", ['ngFlatDatepicker'])
.controller('mainController', ['$scope', mainController])
.controller("machinesController", machinesController);;
function mainController($scope) {
$scope.datepickerConfig_From = {
allowFuture: true,
dateFormat: 'DD.MM.YYYY',
minDate: moment.utc('2015-09-13'),
maxDate: moment.utc('2015-09-17')
};
$scope.datepickerConfig_To = {
allowFuture: true,
dateFormat: 'DD.MM.YYYY',
minDate: moment.utc('2015-09-13'),
maxDate: moment.utc('2015-09-17')
};
$scope.date_from = "14.09.2015";
$scope.date_to = "15.09.2015";
$scope.change = function () {
//somehow execute machinesController get function
};
}
function machinesController($http) {
var vm = this;
vm.errorMessage = "";
vm.machines = [];
$http.get("/api/machine/2015-09-14_2015-09-16")
.then(function (response) {
//success
angular.copy(response.data, vm.machines);
}, function (error) {
//failure
vm.errorMessage = "Failed to load data:" + error;
});
}
})();
my machinesController is supposed to call a GET function with parameters. Here parameters are 2015-09-14 and second one is 2015-09-16 (for now they are hard coded).
What I would like to achieve is, that I have a two input controls on my main page, which trigger $scope.change function (located at the bottom of the first mainController). Here I would like to pass values of date_from and date_to to the GET function, so that I can retrieve certain values.
What I can do (in the end, if nothing works) is to copy the ode from machinesController into my mainController and that would solve the problem.
However I would like to learn how to work with this a bit better, therefore I would like to learn how to do it the proper way (in this case calling one module from the other).
What do I need to change in order to achieve this?
EDIT:
The reason why I have machinesController is, as was mentioned, to donwload the json data and show it to the user. So in the end in my html code I have the following:
<div ng-controller="machinesController as vm" class="col-md-6 col-md-offset-3">
<div class="text-danger" ng-show="vm.errorMessage"> {{ vm.errorMessage }}</div>
<table class="table table-responsive table-striped">
<tr ng-repeat="machine in vm.machines">
<td> {{ machine.name }}</td>
</tr>
</table>
</div>
Which displays a table with machine names.
you can active this is two way:
First : $broadcast and $on
//PUBLISHER
angular.module('myApp').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {
$rootScope.$broadcast('topic', 'message');
}]);
//SUBSCRIBER
angular.module('myApp').controller('ctrlSubscribe', ['$scope',
function ($scope) {
var unbind = $scope.$on('topic', function (event, arg) {
$scope.receiver = 'got your ' + arg;
});
$scope.$on('$destroy', unbind);
}]);
Second : Through common service
angular.module('myApp', [], function($provide) {
$provide.factory('msgBus', ['$rootScope', function($rootScope) {
var msgBus = {};
msgBus.emitMsg = function(msg) {
$rootScope.$emit(msg);
};
msgBus.onMsg = function(msg, scope, func) {
var unbind = $rootScope.$on(msg, func);
scope.$on('$destroy', unbind);
};
return msgBus;
}]);
});
and use it in controller like this:
controller 1
function($scope, msgBus) {
$scope.sendmsg = function() {
msgBus.emitMsg('somemsg')
}
}
controller 2
function($scope, msgBus) {
msgBus.onMsg('somemsg', $scope, function() {
// your logic
});
}
From : Post
To takes care of downloading the data you should use a factory.
Look at this answer for further details about good practices.
I modified your code to use a factory.
angular.module("app-machines", ['ngFlatDatepicker'])
.factory('MachinesService', ['$http', MachinesService])
.controller('mainController', ['$scope', 'MachinesService', mainController]);
function mainController($scope, MachinesService) {
// date pickers config...
$scope.date_from = "14.09.2015";
$scope.date_to = "15.09.2015";
$scope.change = function () {
MachinesService.getMachines($scope.date_from, $scope.date_to).then(function (response) {
vm.machines = response.data;
}, function (error) {
vm.errorMessage = "Failed to load data:" + error;
});
};
}
function MachinesService($http) {
return {
getMachines: getMachines
};
function getMachines(from, to) {
return $http.get("/api/machine/" + from + "_" + to);
}
}
Why dont u create a service instead of second controller and inject it into your main controller and use it.
May be you can refer this :
http://ilikekillnerds.com/2014/11/angularjs-call-controller-another-controller/
Newbie Question
Have been watching this great Angular Beginners course but got stuck in the register process.
Code project (plnkr.co)
index.html
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="github.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ countdown }}
<form name="searchUser" ng-submit="search(username)">
<input type="search" required placeholder="Username to find" ng-model="username"/>
<input type="submit" value="Search">
</form>
<div ng-include="'userdetails.html'" ng-show="user"> </div>
</body>
</html>
github.js
(function() {
var github = function($http) { // requires the service $http
// Private implementation details //
var gettingUser = function(username) {
return $http.get("https://api.github.com/users/" + username)
.then(function(response) {
return response.data;
});
/* returning the promise that already comes with
the function to perform the data extration
*/
};
var gettingRepos = function(user) {
return $http.get(user.repos_url)
.then(function(response) {
return response.data;
});
/* returning a promise that it will return the data
- so the controller doesn't have to. */
};
// Public API //
return {
gettingUser: gettingUser,
gettingRepos: gettingRepos
};
// returns an object (github service)
};
var module = angular.module("githubViewer");
/* Not creating a module, just getting the reference
to the one created in script.js So no need to list
the dependencies in a list after githubViewer*/
// Register the Service
module.factory("$github", github);
}());
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function(
$scope, $github, $interval, $log,
$anchorScroll, $location) {
var onUserComplete = function(data) {
$scope.user = data;
$github.gettingRepos($scope.user)
.then(onRepos, onError);
};
var onRepos = function(data){
$scope.repos = data;
$anchorScroll( $location.hash("userDetails") );
}
var onError = function(reason) {
$scope.error = "Could not fetch data";
};
var decrementCountdown = function(){
$scope.countdown -= 1;
if($scope.countdown < 1){
$scope.search($scope.username);
}
}
$scope.search = function(username) {
$log.info("Searching for "+ username);
$github.gettingUser(username).then(onUserComplete, onError);
if(countdownIntervalObj){
$interval.cancel(countdownIntervalObj);
$scope.countdown = null;
}
};
var countdownInterval = null;
var startCountdown = function(){
countdownIntervalObj = $interval(decrementCountdown, 1000, $scope.countdown);
}
$scope.username = "angular";
$scope.message = "GitHub Viewer";
$scope.repoSortOrder = "-stargazers_count";
$scope.countdown = 5;
startCountdown();
};
app.controller("MainController",
["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
}());
The console keeps saying that the $github.gettingUser is not a function. What am I doing wrong?
Watch out for the order when you inject your dependencies as you are injecting seven but just passing six to the controller in the wrong order. You need to pass $http and put $github at the end.
var MainController = function($scope, $http, $interval, $log, $anchorScroll, $location, $github)
app.controller("MainController", ["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
When you inject resources into your controller
app.controller("MainController", ["$scope", "$http", "$interval", "$log", "$anchorScroll", "$location", "$github", MainController]);
order et type must match your controller function declaration
var MainController = function(
$scope, $github, $interval, $log,
$anchorScroll, $location) {
So here what $github contains is the $http module :)
Here is a corrected version of your plunkr
http://plnkr.co/edit/9UyNHDKiXDZAZt8PPEPy?p=preview
However I prefer this syntax, I find it more clear: http://plnkr.co/edit/byhQ7ST8AZlQ6oMYIMeV?p=preview
You should take a look to https://github.com/johnpapa/angular-styleguide
A styleguide were using at work, filled with best practices.
Have fun with angular
because the order of providers are not the same in the array ["scope", "github", etc] with the controller's. your service corresponds to another provider which is minified, even if it is not, it does not matter. you have to pass the injectors in the same order you define in the provider array
Here is my url
For Login - http://localhost/ang/#/login
For Dashboard - http://localhost/ang/#/dashboard
Here is my html for body tag
If this is current url is http://localhost/ang/#/login then the body should have the class="login-layout" tag i.e.,
<body ng-cloak="" class="login-layout>
else it should have
<body ng-cloak="" class="no-skin">
I tried to take do this in php by i can't take the url after # like said here
Is this possible to do in AngularJS itself ?
Update :
I tried to do this in AngularJS
From the controller i can get the url after #
var nextUrl = next.$$route.originalPath;
but how can i change the class name..
this is how i would do
<body class="{{currentclass}}" ng-cloak>
now in login controller just do
$rootScope.currentclass = "login-layout";
and in every other controller just do
$rootScope.currentclass = "no-skin";
OR
in app.run just check for the login path.
app.run(function($rootScope, $location){
rootScope.$on('$routeChangeStart', function(event, next, current){
if ($location.path() == '/login') {
$rootScope.currentclass = "login-layout";
}
else{
$rootScope.currentclass = "no-skin";
}
});
I need to do this in a project and this is how I achieved it:
inside my main app controller I have:
// Inject the $location service in your controller
// so it is available to be used and assigned to $scope
.controller('AppCtrl', ["$scope", "$location",...
// this_route() will be the variable you can use
// inside angular templates to retrieve the classname
// use it like class="{{this_route}}-layout"
// this will give you -> e.g. class="dashboard-layout"
$scope.this_route = function(){
return $location.path().replace('/', '');
};
Which exposes the current route name on the scope.
then my body tag simply reads this like:
<body ng-controller="AppCtrl" class="{{this_route()}}-view" ng-cloak>
You can similarly use this with $state and read the $state.current.url and assing it to scope
You can do it like in my example below
<body ng-cloak="" ng-class="bodyClass" class="login-layout>
$scope.bodyClass = "mainClass"
var nextUrl = next.$$route.originalPath;
if (..) {
$scope.bodyClass = "sometAnotherMainClass";
}
Shoud controller should look like this
angular.module('youAppName').controller('yourController', [ "$scope", function($scope) {
$scope.bodyClass = "mainClass"
var nextUrl = next.$$route.originalPath;
if (..) {
$scope.bodyClass = "sometAnotherMainClass";
}
}]);
I think that the most "Angular" way to solve it is using a directive. The biggest benefit is that you don't have to set a scope variable in every controller you use.
This is how it would look:
app.directive('classByLocation', ['$location', function($location) {
var link = function(scope, element) {
scope.$on('$routeChangeSuccess', function() {
if ($location.path() == '/login') {
element.removeClass('no-skin').addClass('login');
}
else{
element.removeClass('login').addClass('no-skin');
}
});
};
return {
restrict: 'A',
link: link
};
}]);
And in your HTML:
<body class-by-location>
Here is a working plunker: http://plnkr.co/edit/zT5l6x9KYOT1qeMOxtQU?p=preview
I have the Controller
function loginController($scope, $http, $cookieStore, $location) {
var token = $cookieStore.get('token');
var conId = $cookieStore.get('Cont_Id');
var exId = $cookieStore.get('ex_Id');
$scope.log_me = function() {
$scope.login_me = [];
var login_un = $scope.uservals;
var login_pwd = $scope.passvals;
var logs_me = "api call here";
$http.get(logs_me)
.success(function(response) {
$cookieStore.put('token', response.token);
$cookieStore.put('ex_Id', response.ExId);
$cookieStore.put('Cont_Id', response.contactId);
$cookieStore.put('email', response.email);
$cookieStore.put('name', response.name);
$scope.log_sess = response;
$scope.sess_id= response.ss_id;
alert($scope.sess_id);
if (response.status == "failure, invalid username or password") {
$('.login_error').show();
$('.login_error').html('Invalid username or password');
$('.login_error').delay(4000).fadeOut();
$('.loading').hide();
} else {
$location.path('/dashboard');
}
});
}
}
I have used the above controller in my login page and it is working fine. Now i want to use the same controller in another template and retrieve the value "$scope.sess_id"
My Template is
<div class="page" >
<style>
#report_loader object {
width: 100%;
min-height: 700px;
width:100%;
height:100%;
}
</style>
<div class="loading"> </div>
<section class="panel panel-default" data-ng-controller="loginController">
<div class="panel-body" style=" position: relative;">
<div id="report_loader" style="min-height:600px;">
{{sess_id}}
<script type="text/javascript">
$("#report_loader").html('<object data="https://sampleurl/contact/reports/members/sorted_list.html?ss_id=' + sess_id+' />');
</script>
</div>
</div>
</section>
</div>
I am unable to retrieve the value {{sess_id}} here. What should be done so that i can bring this value in my template
You're routing the user to the "dashboard" route upon successful log in. Even though it might feel like you're using the same "loginController" for both login and dashboard, it will be an entirely new instance of both the controller and $scope. Which is why the {{sess_id}} is not displaying on the dashboard template.
If you're following an MVC-like pattern of AngularJS, ideally you want to be creating a new controller for your dashboard template. See explanation: https://docs.angularjs.org/guide/controller#using-controllers-correctly
So, I would create a DashboardCtrl and share the sess_id between the two. There are plenty of examples out there of how to share data between controllers:
You can use a factory: Share data between AngularJS controllers
You can use $rootScope: How do I use $rootScope in Angular to store variables?
Hope it helps.
I would use the rootScope approach, but an easier way to do that is to simply create a 'global' variable.
In your main controller (not your login controller), define a global scope variable like this:
$scope.global = {};
Then in your login controller, modify your session id to use the global variable:
$scope.global.sess_id= response.ss_id;
alert($scope.global.sess_id);
Then in your html:
<div id="report_loader" style="min-height:600px;">
{{global.sess_id}}
It's simple and works like champ.
I would create a service :
services.sessionService = function(){
var sessionID = null;
this.setSessionID = function(id){
sessionID = id;
}
this.getSessionID = function(){
return sessionID;
}
}
then in your controller :
$scope.sess_id= response.ss_id;
alert($scope.sess_id);
sessionService.setSessionID( $scope.sess_id );
and in your dashboard controller :
$scope.sess_id = sessionService.getSessionID();
Approaches
Your question's answer has many approach. They are:
Using value or service, you can call it wherever your controllers need them.
Using $rootScope, this is very common and easy to use. Just define your $rootScope inside your main controller or whatever controller that called first and then you can call it from other controllers like any $scope behavior.
Using $controller service or usually called controller inheritance. Define this in controller function's parameter, then type $controller('ControllerNameThatIWantToInheritance', {$scope:$scope});
Maybe any other approach can be use to it. Each of them have strength and weakness.
Examples:
using value
.value('MyValue', {
key: null
})
.controller('MyCtrl', function ($scope, MyValue) {
$scope.myValue = MyValue;
})
you can modified MyValue from service too
using $rootScope
.controller('FirstCtrl', function ($scope, $rootScope) {
$rootScope.key = 'Hello world!';
})
.controller('SecondCtrl', function ($scope, $rootScope) {
console.log($rootScope.key);
})
will print 'Hello World', you can also use it in view <div>{{key}}</div>
using $controller
.controller('FirstCtrl', function ($scope) {
$scope.key = 'Hello world!';
})
.controller('SecondCtrl', function ($scope, $controller) {
$controller('FirstCtrl', {$scope:$scope});
})
Second controller will have $scope like first controller.
Conclusion
In your problem, you can split your controller for convenient. But if you dont' want to, try to define $scope.sess_id first. It will tell the Angular that your sess_id is a defined model, and angular will watch them (if you not define it first, it will be 'undefined' and will be ignored).
function loginController($scope, $http, $cookieStore, $location) {
var token = $cookieStore.get('token');
var conId = $cookieStore.get('Cont_Id');
var exId = $cookieStore.get('ex_Id');
$scope.sess_id = null //<- add this
$scope.log_me = function() {
$scope.login_me = [];
var login_un = $scope.uservals;
var login_pwd = $scope.passvals;
var logs_me = "api call here";
$http.get(logs_me)
.success(function(response) {
$cookieStore.put('token', response.token);
$cookieStore.put('ex_Id', response.ExId);
$cookieStore.put('Cont_Id', response.contactId);
$cookieStore.put('email', response.email);
$cookieStore.put('name', response.name);
$scope.log_sess = response;
$scope.sess_id= response.ss_id;
alert($scope.sess_id);
if (response.status == "failure, invalid username or password") {
$('.login_error').show();
$('.login_error').html('Invalid username or password');
$('.login_error').delay(4000).fadeOut();
$('.loading').hide();
} else {
$location.path('/dashboard');
}
});
}
}