Loading route into dynamically named view? - javascript

I'm trying to build accordion style navigation for an app with Meteor and Angular JS. I have a list of articles like so:
State:
$stateProvider
.state('articles', {
url: '/articles',
template: '<articles></articles>'
});
<articles>:
<div class="article-entry" ng-repeat="article in articles.list" slug="{{article.slug}}">
<div class="inner">
//...
<div ui-view="{{article.slug}}"></div>
<a ui-sref="article.content({slug: article.slug})">View article</a>
</div>
</div>
And then the article content:
$stateProvider
.state('articles.content', {
url: '/:slug',
template: '<content></content>'
});
<content> is just, you guessed it, the article content.
Is it possible to get <content> to show up in the ui-view associated with it when someone visits the articles.content state? How would I do this?

Related

default state in nested ui-view in ui-router

I am working on a project where I have a created a directive for a multi step form. Essentially trying to replicate this. The project layout has a header,navigation, a content page (which includes a ui-view) depending on the tab selected on the navigation tab.
Now there is a form tab which when clicked routes to a HTML page which includes this form directive. The directive calls the template (which includes another ui-view) loads the html content but failed to load the nested state. How do I set the default state?
The project directory looks like
src
main
app
directive
formData
formData.js
formData.tpl.html
formInterest.tpl.html
formProfile.tpl.html
formFinal.tpl.html
views
header.html
leftNavigation.html
appRun.html
app.js
index.html
The app.js file has states defined as
$stateProvider
.state('landingPage', {
url: '/landingPage',
templateUrl: 'views/landingPage.html'
})
.state('appRun', {
url: '/appRun',
templateUrl: 'views/appRun.html'
})
.state('appRun.first', {
url: '/first',
templateUrl: 'directives/formData/formProfile.tpl.html'
})
.state('appRun.second', {
url: '/second',
templateUrl: 'directives/formData/formInterest.tpl.html'
})
.state('appRun.third', {
url: '/third',
templateUrl: 'directives/formData/formFinal.tpl.html'
});
The appRun.html looks like
<form-data></form-data>
The formData.js directive looks like
var formData = angular.module('formData',[]);
formData.directive('formData',function(){
return {
restrict: 'EA',
scope: {},
replace: true,
link: function($scope, element, attributes){
},
controller: function($scope,$attrs,$http){
$scope.processForm = function(){
console.log("processFrom");
}
},
templateUrl: 'directives/formData/formData.tpl.html'
}
});
the formData.tpl.html looks like
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-container">
<div class="page-header text-center">
<h2>Let's Be Friends</h2>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".first"><span>1</span> Profile</a>
<a ui-sref-active="active" ui-sref=".second"><span>2</span> Interests</a>
<a ui-sref-active="active" ui-sref=".third"><span>3</span> final</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div ui-view></div>
</form>
</div>
<!-- show our formData as it is being typed -->
<pre>
{{ formData }}
</pre>
</div>
</div>
When I click on appRun state it shows up the content in formData.html but ui-view doesn't show a default state. How do I add a default state such that when the formData.html is loaded it also shows appRun.first state?
Use
<ng-include="'directives/formData/formProfile.tpl.html'"/>
Inside <div ui-view></div>. This will be the default page.
The other option:
Mark state appRun abstract.
Whenever linking to appRun link to appRun.first instead.

Angular Routing - Load data into parent page before first route

I am using angular routing for a admin panel project. Following is my angular js code.
app.js
(function() {
var app = angular.module("app", [
"ngRoute",
"app.dashboard",
"app.calendar",
"app.event"
]);
var dashboard = angular.module("app.dashboard");
dashboard
.config(function($routeProvider) {
$routeProvider.
when('/dashboard', {
templateUrl: '/views/dashboard/dashboard.html',
controller: 'DashBoardIndexController as ctrl'
}).
when('/dashboard/detail', {
templateUrl: "/views/dashboard/detailgraph.html",
controller: "DashBoardDetailController as ctrl"
})
});
......
......
//Controllers related to dashboard module
var calendar = angular.module("app.calendar");
calendar
.config(function($routeProvider) {
$routeProvider.
when('/calendar', {
templateUrl: '/views/calendar/calendar.html',
controller: 'CalendarIndexController as ctrl'
}).
when('/calendar/markevent', {
templateUrl: "/views/calendar/markevent.html",
controller: "CalendarEventController as ctrl"
})
});
......
......
//Controllers related to calendar module
}());
For better code management, I am dividing various module of application and including them in main app module.
After login, the first route loaded will be of dashboard (/dashboard). But before route provider initialized and dashboard loaded, I need to fetch the user's rights level and accordingly create the side navigation menus in parent page. Below is my parent page:
home.html
<body ng-app="app">
<header>
<nav id="mynav" class="bold z-depth-1" role="navigation">
<div class="nav-wrapper container">
<a id="logo-container" href="#" class="brand-logo text-darken-1">Logo</a>
<div class="container">
<a href="#" data-activates="slide-out" class="button-collapse top-nav full hide-on-large-only black-text"><i
class="mdi-navigation-menu"></i></a>
</div>
</div>
</nav>
<ul id="slide-out" class="side-nav fixed center-align">
<!-- This side menu items should be created based on user's rights --!>
</ul>
</header>
<main class="grey lighten-4">
<div id="main-container" class="container z-depth-1 ">
<div ng-view=""></div>
</div>
</main>
As you can see, before ng-view is loaded with first route (/dashboard), I need to make server call to fetch the user's rights. I am relatively new to angular and I think we can do this by resolve promise. But here two modules are different (app and app.dashboard).
What could be the correct way to solve this problem?

Angular UI route states are not showing up

so i have been following a tutorial on how to use AngularJS ui route. I manage to get the views working just fine. However in trying to get the states to work and its just not working. I followed the tutorial exactly but for some reason my states to just show up. Hopefully someone can help me out.
Scirpt.js
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'homeCtrl'
})
.state('home.list', {
url: '/list',
templateUrl: 'views/partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
.state('about', {
url: '/about',
templateUrl: 'views/about.html',
controller: 'aboutCtrl'
})
.state('/views/about', {
// Figure out later
});
});
index.html
<!-- Page Content -->
<div id="page-content-wrapper" ng-app="routerApp">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1>Content Page</h1>
<p>This is where the template of the vast amount of pages will be loaded. This will keep it a single page applcatino. The
main page will inject the html that needs to be loaded to the user. While the top nav bar will allow the user to
view the rest of the website, which will be separate pages
</p>
<p>Make sure to keep all page content within the <code>#page-content-wrapper</code>.</p>
Toggle Menu
</div>
</div>
</div>
<!-- Angular Template, this is where content will be injected -->
<div ng-include="pages"></div>
<div ui-view></div>
</div>
</div>
home.html
<div class="jumbotron text-center">
<h1>The Homey Page</h1>
<p>This page demonstrates <span class="text-danger">nested</span> views.</p>
<a ui-sref=".list" class="btn btn-primary">List</a>
<a ui-sref=".paragraph" class="btn btn-danger">Paragraph</a>
</div>
partial-home-list.html
<div>
<ul>
<li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
</div>
Plunker
http://plnkr.co/edit/cN5uM1m20DHGps8cZgzt
Since you are using nested states and views ("home.list" is nested inside "home"), you need to include <div ui-view></div> in your home.html as well.
For further information: https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views
Good luck! :)

Compile an html template with data from my controller

In Angular,I am building a web app for an hotel that has different rooms. I want to be able to click on a tab in the navbar (or anywhere on the page.) and populate the html view with public data about the room that I have stored in the controller.
what is the best way to go about this? I am using ui-routing. I have yet to find an exhaustive answer on stack overflow.
Below is an example of what my app looks like.
This is my app.js
var appBB = angular
.module('appBB', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', MainRouter]);
function MainRouter(states, router) {
states
.state( 'home', {
url:'/',
templateUrl: 'home.html'
}).state( 'show',{
url:'/show',
templateUrl:'show.html'
});
router.otherwise('/');
}
This is my controller
appBB.controller("BBController", BBController());
function BBController() {
var self = this;
self.apartments = [
{
name: "apt1",
image: "imag1.jpg"
amenities: ["blablabal", "bhuhuih", "hvjf"]
},
{
name: "apt2",
image: "img2.jpg",
amenities: ["blablabla", "bkjhkg", "lkhug"]
},
{
name: "apt3",
image: "img3.jpg",
amenities: ["blablabla", "jgfkhgc","jgvkhg"]
}
]
}
This is an example of the view template that I want to fill:
<div ng-controller="BBController as bbs">
<div>
<h4>{{this should show the apt name}}</h4>
</div>
<div class="row">
<div class="col-sm-8">
<img ng-src="{{this should show the image of the apt that i clicked on}}" />
</div>
<div class="col-sm-4">
<ul>
<li ng-repeat="looping over the apt amenities">{{amenity}}</li> </ul>
</div>
</div>
</div>
Any help will be greatly appreciated.
What you are doing looks good but you need some improvement in it.I would suggest you to use $routeParams on Nav-bar clicks. something like:
<div ng-controller="BBController as bbs">
<div>
<h4>{{this should show the apt name}}</h4>
</div>
<div class="row">
<div class="col-sm-8">
<img ng-src="{{this should show the image of the apt that i clicked on}}" />
</div>
<div class="col-sm-4">
<ul>
<li ng-repeat="amemity in amenities">
<a ng-href="#amemityList/{{ amemity.id }}"> {{amemity.name}} </a>
</li>
</ul>
</div>
</div>
Now, you can use this amenity.id to pass to YourController and accordingly fetch respective view with all the info of that "clicked" amenity.id
.when('/amemityList/:navBar', {
templateUrl: "AmenityView.html",
controller: "YourController"
})
In this way, you will be able to use single view AmenityView.html and its info can be as per your amenity.id which has been passed to the controller like
var navBarSelection_id = $routeParams.navBar;
Maybe, you could add the info at the url like /show/apt1 and use apt1 to find the information on the controller.
Edit:
A little explanation: https://docs.angularjs.org/tutorial/step_07

In Angular ui-router nested state url changes,but template is not loading

I am using ui-router for nested states & views. When I click on the link, the URL changes to the URL for the substate, but the template does not load.
For example, when the URL changes to the substate project/settings, the corresponding template project.settings.html is not loading.
Here is an SSCCE courtesy of Plunkr
Below is my code as well:
app.js
myApp.config(function ($stateProvider, $urlRouterProvider){
$stateProvider
.state('project', {
url: "/project",
views:{
"content":{templateUrl: "partials/project.html"},
"header":{templateUrl: "partials/header"}
}
})
.state('project.settings', {
url: "/settings",
views:{
"content":{templateUrl: "partials/project.settings.html"},
"header":{templateUrl: "partials/header"}
}
})
$urlRouterProvider.otherwise("/")
});
/* cheching whether the user is authentic or not*/
myApp.run(function($rootScope,$location,$cookieStore,validateCookie,$state) {
$rootScope.$on('$stateChangeStart',function(event,toState,toParams,fromState){
if($cookieStore.get('user')){
validateCookie.authService(function(result,error){
if(!result){
$location.path("/");
}else{
$state.go('project.settings');
}
});
}
else{
$location.path("/");
}
});
});
index.html
<div ng-controller="userController">
<div ui-view="header"></div>
<div class="container" ui-view="content"></div>
</div>
project.html
<div ng-controller="userController">
<div class="details">
<a ui-sref=".settings" class="btn btn-primary">Settings</a>
</div>
</div>
project.settings.html
<h1>Project Setting -State test</h1>
Your nested project.settings state needs to address the view in the higher state explicitly using an '#' suffix, ie.:
.state('project.settings', {
url: "/settings",
views:{
"content#":{templateUrl: "partials/project.settings.html"},
"header#":{templateUrl: "partials/header"}
}
})
See more details here https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#view-names---relative-vs-absolute-names
First of all change file name project.settings.html in templateurl and file name to projectSettings.html (remove dot).
.state('project.settings', {
url: "/settings",
views:{
"content":{templateUrl: "partials/projectSettings.html"},
"header":{templateUrl: "partials/header"}
}
})
Add two divs in the project template to load the sub pages (header abd projectSettings)
Note: Any content in this divs will be replaced with the page loaded here.
project.html
<div ng-controller="userController">
<div class="details">
<a ui-sref=".settings" class="btn btn-primary">Settings</a>
</div>
<div ui-view="header">( Project Page header will replace with projectSettings header )</div>
<div class="container" ui-view="content">( Project Page content will replace with projectSettings Content )</div>
</div>
I had the same issue and the solution was to place ui-view to your parent's template. Because your partials also need a too, if they will be loading a template from a child state.
See here https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#issue-my-templates-are-not-appearing--loading--showing
If using nested views with UI-router, be sure to add ui-view into the html of the parent page and include specific named views.
I had the same issue, the solution was; open the project.html file (which is the parent page) and wrap everything within <ui-view>
So, replace these:
<div ng-controller="userController">
<div class="details">
<a ui-sref=".settings" class="btn btn-primary">Settings</a>
</div>
</div>
with these:
<ui-view>
<div ng-controller="userController">
<div class="details">
<a ui-sref=".settings" class="btn btn-primary">Settings</a>
</div>
</div>
</ui-view>
and you will be good to go ;)
Use ui-sref="project.settings" for link in project.html template.

Categories

Resources