angularjs route - jump to specific page section on route link - html

I am trying to make some kind of a mix between an Angular anchor and routing...
I do have it working in the home page, since the anchor sections are there, however, if I am in another page, it does not.
Can anyone point me in the right direction on how to do it correctly, please?
Here´s what I have so far
freddoApp.config(function($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home/home.html',
controller : 'mainController'
})
// route for the productos page
.when('/productos', {
templateUrl : 'pages/home/home.html',
controller : 'mainController'
})
// route for the unico page
.when('/unico', {
templateUrl : 'pages/home/home.html',
controller : 'mainController'
})
// route for the sabores page
.when('/sabores', {
templateUrl : 'pages/home/home.html',
controller : 'mainController'
})
// route for the locales page
.when('/locales', {
templateUrl : 'pages/locales/locales.html',
controller : 'storeController'
})
// route for the servicios page
.when('/servicios', {
templateUrl : 'pages/servicios/servicios.html',
controller : 'servicesController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact/contact.html',
controller : 'contactController'
});
// use the HTML5 History API
$locationProvider.html5Mode(true);
});
/............................./
freddoApp.controller('mainController', function($scope, $location, $anchorScroll) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
};
/............................./
(HTML)
<div id="freedo-nav-bar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a ng-click="scrollTo('productos')">Productos</a></li>
<li><a ng-click="scrollTo('unico')"> Freddo Único</a></li>
<li><a ng-click="scrollTo('sabores')"> Sabores</a></li>
<li> Locales</li>
<li> Servicios</li>
<li> Nosotros</li>
<li> Contacto</li>
</ul>
</div>
Thanks!

If i understand you right, i think you could solve this with resolve.
First add a resolve function to your routing:
.when('productos/', {
templateUrl : 'pages/home/home.html',
controller : 'mainController',
resolve: {
anchorname: function() { {
// anchor name
return 'productos'
}
}
})
In your controller pass the resolve object and add some function for the scrolling
freddoApp.controller('mainController', function($scope, $location, $anchorScroll, anchorname) {
if(anchorname){
$location.hash(anchorname);
$anchorScroll();
}
})
This should immediately scroll to the anchor after you selecting the route.
EDIT: Its working, see here: https://jsfiddle.net/326f44xu/

Best approach for you is using routing url params like /home/:section. If you do it in that way, you are able to access from any other page. PLUNKER
ROUTE CONFIG
app.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/home/:section?', {
templateUrl: 'home.html',
controller: 'mainController'
}) //You don't need to repeat your .when() multiple times
$routeProvider.otherwise({
redirectTo: '/home'
});
});
HOME CTRL (mainController)
app.controller('mainController', function($routeParams, $location, $anchorScroll) {
//wrap this on $onInit or activate() function if you want
$location.hash($routeParams.section);
$anchorScroll();
});
HOME.HTML
<div><!-- HOME --></div>
<div id="productos"><!-- Productos--></div>
<div id="unico"><!-- unico--></div>
<div id="sabores"><!-- sabores--></div>
INDEX.HTML
<body>
<div>
<a ng-href="#/home">Home</a>
<a ng-href="#/home/productos">productos</a>
<a ng-href="#/home/unico">Unicos</a>
<a ng-href="#/home/sabores">Sabores</a>
</div>
<div ng-view></div>
</body>
** You can use empty route with optional params like /:section?, but I added /home to make it clear. The ? at the end of url param is to make it optional.

Related

Disable routing on page refresh in angular js

I have a route provider like this
app.config(function ($routeProvider, $locationProvider){
$locationProvider.hashPrefix('');
$routeProvider
.when('/', {
templateUrl: 'login.html',
controller: 'loginCtrl'
})
.when('/home', {
resolve:{
"check":function($location, $rootScope){
if(!$rootScope.loggedIn){
$location.path('/');
}
}
},
templateUrl:'home.html',
controller: 'homeCtrl'
})
.otherwise({
redirectTo: '/'
});
});
login.html is the first page of my app.
But after login, on reloading any page that will ends up in the login.html page
I want other pages keep alive on refresh and login.html as my opening page
Reloading page will recreate $rootScope every time. So you need to store login details in any storage like localstorage.
http://blog.teamtreehouse.com/storing-data-on-the-client-with-localstorage
This link might help you. you need to store data once you successfully logged in. and get stored data and validate the use while resolving url.
scotchApp.config(function($stateProvider, $urlRouterProvider, $compileProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$compileProvider.debugInfoEnabled(false);
// route for the home page
$stateProvider
.state('home', {
url: '/home',
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.state('about', {
url: '/about',
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.state('contact', {
url: '/contact',
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
$urlRouterProvider.otherwise('home');
});
Try something like this.

Dynamic routing in angularjs using single html page?

I'm working with an application in angular where I have items in an array, and when I click on each item, details should be displayed in details page,I want to achieve this by displaying details of all items in the same details page dynamically, how do I do this?
Here is my code
<body ng-app="myApp" ng-controller="mobileController">
search:<p><inpu type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter :test" >
<a href=#/> {{ x }}</a>
</li>
</ul>
<div ng-view></div>
var app = angular.module("myApp",[]);
app.controller('mobileController', function($scope) {
$scope.names = ['iphone', 'Moto', 'Oneplus'];
});
</body>
I want to display the details of iPhone ,moto,oneplus in same details page,when user clicks on iPhone iPhone details should be displayed and same for others.
Here's a plunkr on how to do what you want using UI-Router
You can use two states to do what you want by having two states: one for the list view and one for the details view.
$stateProvider
.state('items', {
url: '/',
controller: 'ItemsListCtrl',
templateUrl: 'items-list.html',
resolve: {
Items: function (ItemsService) {
return ItemsService.getAll();
}
}
})
.state('items.details', {
url: ':itemId/',
controller: 'ItemDetailsCtrl',
templateUrl: 'item-details.html',
resolve: {
Item: function (ItemsService, $stateParams) {
return ItemsService.getById($stateParams.itemId);
}
}
})
When someone clicks on an item you send them to a url with the itemId as a stateParam and resolve that item as you load the view within the view you have currently rendered (these are called nested/child views in ui-router).
Then in the controllers you just inject the items/item you resolved at the state level, and can manipulate them or assign them to your scope.
.controller('ItemsListCtrl', function ($scope, Items, $state) {
$scope.Items = Items;
$scope.viewItemDetails = function (item) {
$state.go('items.details', {itemId: item.id});
};
})
.controller('ItemDetailsCtrl', function ($scope, Item, $state) {
console.log(Item);
$scope.Item = Item;
$scope.closeDetails = function () {
$state.go('items');
};
})
I'd recommend checking out UI-Router's docs https://github.com/angular-ui/ui-router/wiki

Show/Hide elements on website for certain pages

I am using AngularUI Router to navigate content on my website. I have some webpages that show the header/footer navigation and some that do not. I want to be able to detect what my current page is and insert the HTML for the header/footer if needed.
Here is my current router
angular.module('app', ['ui.router'])
.config(['$urlRouterProvider', '$stateProvider',
function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/home.html',
controller: 'homeCtrl'
})
.state('about', {
url: '/about',
templateUrl: 'partials/about.html',
controller: 'aboutCtrl'
})
.state('contact', {
url: '/contact',
templateUrl: 'partials/contact.html',
controller: 'contactCtrl'
})
.state('create', {
url: '/create',
templateUrl: 'partials/create.html',
controller: 'createCtrl'
})
.state('login', {
url: '/login',
templateUrl: 'partials/login.html',
controller: 'loginCtrl'
})
}]);
For the html I have this
<html ng-app="app">
<body>
<!-- *********** HEADER ************* -->
<div ng-include=""></div>
<!-- ********** CONTENT *********** -->
<div ui-view></div>
<!-- **************** FOOTER ****************** -->
<div ng-include="'partials/standard_footer.html'"></div>
</body
</html>
For the webpages create and login I do not want to show the header and footer, but I am not sure how to do that.
I want to do something like this,
<div ng-if="!login && !create" ng-include="'standard_header.html'"></div>
How can I achieve this?
You can expose $state on the $rootScope and that will make it accessible in your webpage.
You can then simply check for state.current.name != 'login'
Like below:
Exposing the current state name with ui router
Edit:
Working Plunker of what i meant: https://plnkr.co/edit/JDpCo3fTePobuX9Qoxjn
You're almost there. Just add a flag in the params of the appropriate states:
.state('create', {
url: '/create',
templateUrl: 'partials/create.html',
controller: 'createCtrl',
params: {
hideHeaderAndFooter: true
}
})
.state('login', {
url: '/login',
templateUrl: 'partials/login.html',
controller: 'loginCtrl',
params: {
hideHeaderAndFooter: true
}
})
And then inject the $stateParams service in your controllers. Every property of the params object will be exposed as a property of the object this service returns:
loginCtrl.$inject = ['$scope', '$stateParams']
function loginCtrl($scope, $stateParams) {
$scope.hideHeaderAndFooter = $stateParams.hideHeaderAndFooter
}
Then you can use ng-if just the way you meant to use it:
<div ng-if="!hideHeaderAndFooter" ng-include="'standard_header.html'"></div>

Edit HTML outside ng-view on route change

I want to change some HTML in the navbar upon a route change, using the routing information. I can almost get it to work with the code below, but the data is not parsed as HTML when arriving in the DOM. I tried using the $sce service, but that didn't really get me anywhere.
If there are any other (better) ways of editing the HTML on route change, then please let me know.
HTML:
<nav>
<div ng-controller="BrandCtrl">
<div class="nav-brand">
{{brand}}
</div>
</div>
</nav>
<div ng-view></div>
JS:
var app = angular.module("app", ['ngRoute']);
app.controller("BrandCtrl", function($scope, $route) {
$scope.$on('$routeChangeSuccess', function() {
var html = $route.current.html;
$scope.brand = html;
});
});
app.config(function ($routeProvider) {
$routeProvider
.when('/next-page', {
templateUrl: 'partials/next-page.html',
controller: 'BrandCtrl',
html: '<h3>New brand</h3>'
});
You should be changing the HTML via the 'views' in the routes.
$stateProvider.state('app',{url: 'someurl',
views: {
'topnav': { templateUrl: 'path/to/some/html',
controller: 'navcontroller'},
'mainContent': {templateUrl: 'path/to/some/other/html',
controller: 'contentcontroller'} }
});
In your HTML you would have multiple views:
<div ui-view="topnav"></div>
<div ui-view="mainContent"></div>

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) {
} ]);