I am building a simple gallery with Angular and I am trying to have a template shown on some route, which is very easy with angular.
some.site/#/gallery
is done with
App.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/gallery', {
templateUrl: 'js/views/gallery/main.htm',
controller: 'galleryCtrl',
controllerAs: 'gallery'
})
.otherwise({
redirectTo: '/'
});
}
]);
But then I want to have a div popup when user clicks on thing and goes to
some.site/#/gallery/thing/1
Note that I still want my gallery to be on the background.
My initial idea was to have that div always hidden unless there's */thing so that I could just get the id like so */thing/:id when needed, but this approach seems rather ugly, because why have that thing hanging in there all the time?
Are there any other, better ways of doing that?
What you can do is set a $routeParam depending on your route, let's say:
if url is /gallery, then 'showPopup' = false
if url is /gallery/thing/:id, then 'showPopup' = true
and then in your html you bind the popup state to $routeParams.showPopup.
To do so, you can set the params directly in your mapping:
App.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/gallery', {
templateUrl: 'js/views/gallery/main.htm',
controller: 'galleryCtrl',
controllerAs: 'gallery',
resolve: {
ignored: function ($route) {
$route.current.params.showPopup = false;
}
}
})
.when('/gallery/thing/:id', {
templateUrl: 'js/views/gallery/main.htm',
controller: 'galleryCtrl',
controllerAs: 'gallery',
resolve: {
ignored: function ($route) {
$route.current.params.showPopup = true;
}
}
})
.otherwise({
redirectTo: '/'
});
}
]);
Hope I helped !
Related
I am using routes and would like to change my background image when I am on a specific route. For some reason the background image does not change/is not reading the value of my rootScope. I make the value true in my controller for the route that needs the different background image. Anyone know what I am doing wrong here? Can I not use $rootScope in my routes to change the class of my body?
HTML:
<body ng-app="ciscoImaDashboardApp" dynamicBodyBg ng-controller="navCtrl" >
JS:
.directive('dynamicBodyBg', function($rootScope, $route){
return {
restrict: 'A',
link: function($scope, el){
$rootScope.$on('$routeChangeSuccess',
function() {
if ($route.current.locals.needToChange()){
el.css({background: url('images/background-bark#2x.jpg')});
}
else {
el.css({background: url('images/background#2x.jpg')});
}
}
);
}
}
});
Routes:
angular.module('ciscoImaDashboardApp', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/welcome.html',
controller: 'welcomeCtrl'
})
.when('/overall-results', {
templateUrl: 'views/overall.html',
controller: 'overallCtrl'
})
.when('/swim-lane-results', {
templateUrl: 'views/swim-lane.html',
controller: 'swimlaneCtrl'
})
.when('/key-exemplifiers', {
templateUrl: 'views/key-exemplifiers.html',
controller: 'petalCtrl'
})
.when('/key-exemplifiers/:exemplifier', {
templateUrl: 'views/single-exemplifier.html',
controller: 'keyCtrl',
resolve: {
needToChange: function(){
return true; //or false
}
}
})
.otherwise({
redirectTo: '/'
});
});
If you are using ng-route, you can do the following:
Add this directive to your body element.
app.directive('dynamicBodyBg', function($rootScope, $route){
return {
link: function($scope, el){
$rootScope.$on('$routeChangeSuccess',
function() {
//your router has changed and u can change the background
//add the logic here
if ($route.current.locals.needToChange){
el.css({background: url('//whatever background u want'});
}
else {
el.css({background: url('//restore'});
}
}
);
}
}
});
In your $routeProvider
$routeProvider
.when('/', {
templateUrl: 'views/welcome.html',
controller: 'welcomeCtrl',
resolve: {
needToChange: function(){
return true; //or false
}
}
})
P.S Suggest you to switch to ui-router, which is much easier to understand and maintain.
Solved this by creating a rootScope and changing it for all the views.
$rootScope.backgroundImg = "url('../images/background#2x.jpg')";
And then using it in my view like this:
<body ng-app="ciscoImaDashboardApp" ng-controller="navCtrl" ng-style="
{'background-image': backgroundImg}" >
I'm trying to handle the 'wheel click' and 'right-click > open in new tab/window' in order to load the targeted view in the new tab/window.
Let's say in one of my view, I have something like this :
<li>Time Tracking</li>
<li>Dashboard</li>
The changeView() function in my controller looks like this :
this.changeView = function(viewPath) {
$location.path(viewPath);
};
And the route configuration like this :
// Routes configuration
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'requests/requestsList.html',
controller: 'requestsController',
controllerAs: 'r'
})
.when('/requests', {
templateUrl: 'requests/requestsList.html',
controller: 'requestsController',
controllerAs: 'r'
})
.when('/projects', {
templateUrl: 'projects/projectsList.html',
controller: 'projectsController',
controllerAs: 'p'
})
.otherwise({
redirectTo: '/'
});
}]);
How could I handle the displaying of a new view in a different tab/window ?
Also, is there a syntax in my $routeProvider that allows me to combine the / and /requests in the same when(...) ?
Simple HTMl will help you there. Add in your HTML code a target="_blank"
Try using $window service:
this.changeView = function(viewPath) {
$window.open(viewPath, '_blank');
};
So I'm trying to use angular routing in my application. The problem is that the route "/" does not get initialized automatically. So I first go to "/" and the main content of the page is empty (the template is not loaded at all), I click the link to /settings and settings are loaded, then I click a link to "/" and this time the template is initialized correctly. So how do I make the thing initialized at the beginning?
Here's my routing configuration:
app.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '/profile.html',
controller: 'ProfileController',
}).when('/profile', {
templateUrl: '/profile.html',
controller: 'ProfileController',
}).when('/settings', {
templateUrl: '/settings.html',
controller: 'SettingsController'
});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
I tried calling $location.url("/profile") from a controller and it did help, but the url has to be changed and I would rather keep the "/"
use otherwise({ redirectTo: "/" })
Update : here how it should be
$routeProvider
.when('/', {
templateUrl: '/profile.html',
controller: 'ProfileController',
}).when('/profile', {
templateUrl: '/profile.html',
controller: 'ProfileController',
}).when('/settings', {
templateUrl: '/settings.html',
controller: 'SettingsController'
}).otherwise({ redirectTo: '/' });
I ask them to help solve this problem, follows the code :
Controller
angular.module('tareasApp')
.controller('HumorCtrl', function ($scope, $route, $location) {
$scope.pageName = $route.current.params.pageName;
$scope.items =[
{
href:'/humor/smile-today',
img:'smile.jpg',
descricao:'Those Relaxing Sounds of Waves'
}
];
});
angular.module('tareasApp')
.controller('NewsCtrl', function ($scope, $route, $location) {
$scope.pageName = $route.current.params.pageName;
$scope.items =[
{
href:'/news/news-today',
img:'news.jpg',
descricao:'Those Relaxing Sounds of Waves'
}
];
});
App.js
myApp.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
title: 'Home Page',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/humor/:pageName', {
templateUrl: 'views/wizard.html',
controller: 'HumorCtrl'
})
.when('/news/:pageName', {
templateUrl: 'views/wizard.html',
controller: 'NewsCtrl'
})
.otherwise({
redirectTo: '/'
});
});
When I type any route that does not exist right after the bar, eg:
domain.com/hhhoedr
returns to the start page .
The problem is in the sub-directory, which contains the $routeParams, typing a page that does not exist , eg:
domain.com/humor/hhhoedr
is not redirecting to index.html or to 404.html.
I would like to adapt this code, I found in another answer, to my app.
myApp.constant('EXISTING_PAGES', [
'page1',
'page2',
...
]);
resolve: {
exists: function ($location, $route) {
if (EXISTING_PAGES.indexOf($route.current.params.page) === -1) {
$location.path('/error/404');
}
return true;
}
}
.when('/error/404', {
templateUrl: '404.html'
})
.otherwise({
redirectTo: '/error/404'
});
how can I do it?
When you are typing any route e.g-domain.com/hhhoedr,It is returning to starting page because check you last part of your code,you are setting it like below.
.otherwise({
redirectTo: '/'
});
If you will set anything except from your all .when part it will simple redirect to the starting page.Try to set it for redirecting to any other page as per your requirement.
Ok,Now you can write it like below.
.otherwise({
redirectTo: '/here give your destination path(e.g-404.html...etc)'
});
I am trying to do what was essentially answered here Unable to open bootstrap modal window as a route
Yet my solution just will not work. I get an error
Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal
My app has the ui.bootstrap module injected - here is my application config
var app = angular.module('app', ['ui.router', 'ui.bootstrap','ui.bootstrap.tpls', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
// Gets executed during the provider registrations and configuration phase. Only providers and constants can be
// injected here. This is to prevent accidental instantiation of services before they have been fully configured.
.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
// UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router
// ------------------------------------------------------------------------------------------------------------
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
.state('transactions', {
url: '/transactions',
templateUrl: '/views/transactions',
controller: 'TransactionsCtrl'
})
.state('login', {
url: "/login",
templateUrl: '/views/login',
controller: 'LoginCtrl'
})
.state('otherwise', {
url: '*path',
templateUrl: '/views/404',
controller: 'Error404Ctrl'
});
$locationProvider.html5Mode(true);
}])
I have reduced my controller to the following:
appControllers.controller('LoginCtrl', ['$scope', '$modal', function($scope, $modal) {
$modal.open({templateUrl:'modal.html'});
}]);
Ultimately, what I am hoping to achieve is when login is required not actually GO to the login page, but bring up a dialog.
I have also tried using the onEnter function in the ui-router state method. Couldn't get this working either.
Any ideas?
UPDATE
Ok - so as it turns out, having both ui-bootstrap.js AND ui-bootstrap-tpls breaks this - After reading the docs I thought you needed the templates to work WITH the ui-bootstrap. though it seems all the plunkers only load in the ..tpls file - once I removed the ui-bootstrap file my modal works...Am i blind? or doesn't it not really say which one you need in the docs on github? -
Now i just need to figure out how to prevent my url from actually going to /login, rather than just show the modal :)
update 2
Ok, so by calling $state.go('login') in a service does this for me.
Hi I had a hard time getting through the similar problem.
However, I was able to resolve it.
This is what you would probably need.
app.config(function($stateProvider) {
$stateProvider.state("managerState", {
url: "/ManagerRecord",
controller: "myController",
templateUrl: 'index.html'
})
.state("employeeState", {
url: "empRecords",
parent: "managerState",
params: {
empId: 0
},
onEnter: [
"$modal",
function($modal) {
$modal.open({
controller: "EmpDetailsController",
controllerAs: "empDetails",
templateUrl: 'empDetails.html',
size: 'sm'
}).result.finally(function() {
$stateProvider.go('^');
});
}
]
});
});
Click here for plunker. Hope it helps.
I'm working on something similar and this is my solution.
HTML code
<a ui-sref="home.modal({path: 'login'})" class="btn btn-default" ng-click="openModal()">Login</a>
State configuration
$stateProvider
// assuming we want to open the modal on home page
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
// create a nested state
.state('home.modal', {
url: ':path/'
});
Home controller
//... other code
$scope.openModal = function(){
$modal.open({
templateUrl: 'path/to/page.html',
resolve: {
newPath: function(){
return 'home'
},
oldPath: function(){
return 'home.modal'
}
},
controller: 'ModalInstanceController'
});
};
//... other code
Finally, the modal instance controller.
This controller synchronizes the modal events (open/close) with URL path changes.
angular.module("app").controller('ModalInstanceController', function($scope, $modalInstance, $state, newPath, oldPath) {
$modalInstance.opened.then(function(){
$state.go(newPath);
});
$modalInstance.result.then(null,function(){
$state.go(oldPath);
});
$scope.$on('$stateChangeSuccess', function () {
if($state.current.name != newPath){
$modalInstance.dismiss('cancel')
}
});
});
You may create a state with the same templateUrl and controller as your page where you want to show the modal, adding params object to it
$stateProvider
.state('root.start-page', {
url: '/',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl'
})
.state('root.login', {
url: '/login',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl',
params: {
openLoginModal: true
}
})
And in controller of the page, use this parameter to open the modal
.controller("StartPageCtrl", function($scope, $stateParams) {
if ($stateParams.openLoginModal) {
$scope.openLoginModal();
}
I found a handy hint to get this working. There are probably caveats, but it works for me. You can pass a result still but I have no need for one.
Using finally instead of the then promise resolve sorted this for me. I also had to store the previous state on rootScope so we knew what to go back to.
Save previous state to $rootScope
$rootScope.previousState = 'home';
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams){
$rootScope.previousState = from.name;
})
State using onEnter
$stateProvider.state('contact', {
url: '/contact',
onEnter: function ($state, $modal, $rootScope){
$modal.open({
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).result.finally(function(){
$state.go($rootScope.previousState);
})
}
});