Does anyone know where I am going wrong? I am trying to load up a new view on a section of the page in AngularJS.
I have the following code within sidebar.html:
<ul>
<li><a ui-sref="MainPage({themeName:'theme1'})">Theme 1</a></li>
<li><a ui-sref="MainPage({themeName:'theme2'})">Theme 2</a></li>
</ul>
Then my module.js file which contains all my routes looks like this:
var main = {
name: "MainPage",
url: "/:themeName",
views: {
"mainContent": {
controller: "MainPageController",
templateUrl: function($stateParams){
var url = 'modules/main/template/' + $stateParams.themeName + '/home.html';
console.log(url);
return url;
},
},
"sidebar":{
templateUrl: "modules/main/template/sidebar.html",
controller: "SidebarController"
}
}
};
$stateProvider.state(main);
When I look at the console I can see that the urlbeing returned is correct but my view isn't updated on the screen.
Would anyone be able to point out where I'm going wrong, I'm not seeing any errors in my console and the application is loading fine.
Any help is much appreciated
The views I'm trying to load reside in modules/main/template/theme1/home.html and modules/main/template/theme2/home.html
the HTML for these views are as follows:
/theme1/home.html
<h1>This is theme 1</h1>
/theme2/home.html
<h1>This is theme 2</h1>
This is where I am using ui-view:
<body>
<!-- SIDEBAR -->
<div id="sidebar" class="col-md-2 animated fadeIn" ui-view="sidebar" ng-cloak>
<div ng-include="modules/main/template/sidebar.html"></div>
</div>
<!-- HEADER -->
<div id="header" class='col-md-10'>
<img src='assets/images/logo.png' alt='' width='270' />
<ul class="breadcrumb">
<li class="active">{{ 'MAIN.NAVIGATION.LINK1' | translate }}</li>
<li>{{ 'MAIN.NAVIGATION.LINK2' | translate }}</li>
<li><a>{{ 'MAIN.NAVIGATION.LINK3' | translate }}</a></li>
</ul>
</div>
<!-- MAIN CONTENT -->
<div id="main-container" class="col-md-10 animated fadeIn" ui-view="mainContent" ng-cloak></div>
<div id="footer" class="col-md-12"><p>This is a test site</p></div>
<!-- SCRIPTS -->
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
<script src="lib/all.js"></script>
<script src="modules/app.js"></script>
</body>
Ok, so we've established that it looks like a routing problem on NodeJS. I am using gulpJS to start up my server like this:
gulp.task('server', function() {
gulp.src([DIRDEST])
.pipe(webserver({
fallback : 'index.html',
livereload : false,
open : false,
directoryListing: {
enable: true,
path: 'target/index.html'
}
}));
});
Make sure you have defined ui-view where you want to render the template:
<div ui-view="mainContent"></div>
Update
I guess, you should use the template instead of templateUrl:
template: function($stateParams){
var url = 'modules/main/template/' + $stateParams.themeName + '/home.html';
console.log(url);
return url;
}
Tip
Also, if you want to re-execute your MainPageController on view change (since both the states are same, just the parameter is changing) then you have to use ui-sref-opts:
<ul>
<li><a ui-sref="MainPage({themeName:'theme1'})" ui-sref-opts="{reload: true}">Theme 1</a></li>
<li><a ui-sref="MainPage({themeName:'theme2'})" ui-sref-opts="{reload: true}">Theme 2</a></li>
</ul>
Related
I am doing my AngularJS project with ng-route and everything works fine but the problem is I have a CSSC full background slide show which i implemented form this site http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/ which work fine. When I click on other pages the content shows but the slideshow shows up as well moving/transitioning in the background. I want to stop this from happening. I want the slideshow to only show up on the index.html page only. Any solutions would be appreciated.
--- HTML code ---
<body ng-app="bigBlue"> <!--angular directive-->
<div main-page-navbar></div> <!--angular navbar directive-->
<div main-slide-show> </div> <!--angular side show directive-->
<div ng-view ></div>
<!-- Additional Java Script Files -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Angular Files -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular/angular-route/angular-route.js"></script>
<!-- Module/directives -->
<script src="js/app.js"></script>
<script src="js/directives/main-content.js"></script>
</body>
------- navbar directive code --------
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header"><a class="navbar-brand navbar-link" href="#/">Big Blue</a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav navbar-right">
<li class="active" role="presentation">Home </li>
<li role="presentation">Overview </li>
<li role="presentation">Map </li>
</ul>
</div>
</div>
</nav>
------ slide show directive code --------
<ul class="cb-slideshow">
<li><span>Image 01</span><div><h3>endangered</h3></div></li>
<li><span>Image 02</span><div><h3>powerful</h3></div></li>
<li><span>Image 03</span><div><h3>caring</h3></div></li>
<li><span>Image 04</span><div><h3>loyal</h3></div></li>
<li><span>Image 05</span><div><h3>intelligent</h3></div></li>
<li><span>Image 06</span><div><h3>serene</h3></div></li>
</ul>
---- Angular Code ----
var app = angular.module("bigBlue", ["ngRoute"]); /* New module called big blue */
app.config(function($routeProvider) {
$routeProvider
.when('/overview', {
templateUrl : 'overview.html',
controller : 'whaleController'
})
.when('/map', {
templateUrl : 'map.html',
controller : 'MapController',
})
.otherwise({
redirectTo : '/'
});
});
You need to move your slideshow directive into the context of the index instead of the context of the entire application. Something like this:
app.config(function($routeProvider) {
$routeProvider
.when('/', {
template: '<div main-slide-show></div>'
})
.when('/overview', {
templateUrl : 'overview.html',
controller : 'whaleController'
})
.when('/map', {
templateUrl : 'map.html',
controller : 'MapController',
})
.otherwise({
redirectTo : '/'
});
});
And pull the slideshow directive out of the markup.
i have a weird bug in my angular app where the data in my ng-repeat is not displaying but if i refresh the page and navigate to my home page it quickly flickers into view then disappears, im not sure why this is happening can someone help me out?
thanks in advance
appRoutes.js
angular.module('appRoutes', []).config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// home page
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
// characters page that will use the CharactersController
.when('/characters', {
templateUrl: 'views/characters.html',
controller: 'CharactersController'
});
$locationProvider.html5Mode(true);
}]);
CharactersCtrl.js
angular.module('CharactersCtrl', []).controller('CharactersController', function($scope) {
$scope.init = function(){
$scope.getCharacters();
}
$scope.getCharacters = function(){
$.ajax({
url:'https://gateway.marvel.com/v1/public/characters?apikey=APIKEY',
success:function(response){
$scope.characters = response.data.results;
console.log($scope.characters);
},
fail:function(){
}
});
}
$scope.init();
});
characters.js
<div>
<div class="text-center">
<h1>Characters</h1>
</div>
<section id="character-section" class="row">
<figure class="columns small-3" ng-repeat="hero in characters">
<!-- <img ng-src="{{hero.thumbnail.path}}" alt="{{hero.name}}-image"> -->
<figcaption>
{{hero.name}}
</figcaption>
</figure>
</section>
</div>
index.html
<body ng-app="marvelApp">
<!-- HEADER -->
<header>
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" href="/">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li>characters</li>
</ul>
</nav>
</header>
<!-- ANGULAR DYNAMIC CONTENT -->
<main ng-view ></main>
</body>
app.js
angular.module('marvelApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'CharactersCtrl', 'CharactersService']);
You are using jQuery ajax. Angular does not automatically update variable when modified outside the Angular scope (in this case, $scope.characters is modified using jquery ajax);
I sugges you use the $http service provided by angular for making ajax calls.
But if you insist in using jquery ajax, you can wrap this code $scope.characters = response.data.results; with
`$scope.$apply(function(){
})`
Result:
$scope.$apply(function(){
$scope.characters = response.data.results;
})
Here is my current code:
let views = { '': 'app/content.html' };
.state('auto', {
url: '/automated',
redirectToChild: {
state: 'auto.index'
},
views: view
})
.state('auto.index', {
url :'',
templateUrl: '/app/automated/automated.html'
})
.state('auto.visit', {
url: '/visit',
views: {
'': {templateUrl: '/app/automated/visit.html'}
}
})
.state('auto.visit.create', {
url: '/create',
views: {
'': {templateUrl: '/app/automated/_form.html'}
}
})
Here is my html:
// index.html
<ui-view></ui-view>
// content.html
<div class="wrapper">
<div class="container">
<ui-view> </ui-view>
</div>
</div>
// visit.html
<h5>Visit Page</h5>
// form.html
<h5>Visit Form</h5>
Here is the problem: Everything works fine with this code but when I visit auto.visit.create state it show visit.html instead of '_form.html'.
How can I replace visit.html content without changing current routes?
First Tried:
I change my auto.visit.create state to auto.visit-create. This way is working perfectly but I want create is child of auto.visit
Second Tried:
I put new <ui-view></ui-view> on visit.html but when I go to create page it will show visit.html content.
I've tried to follow this http://angular-ui.github.io/ui-router/sample/#/ code. But it's not working.
How are you visiting the nested views? The notation you want works perfectly.
you should include the <ui-view></ui-view>in all parent pages.
See the plunker I created as an example; be sure to open the preview in using the separate page view so that you can see the urls that are being generated
UPDATE
I misunderstood your question, I apologize. Below is the updated code and plunker that achieves what you desire. I don't believe there is any way to accomplish this purely through angular routing so I used jquery to do it. only changes are on first layer and second layer
http://plnkr.co/edit/cxQpu6zS7fifnb0sGvGf?p=preview
Angular Code
(function() {
angular.module("myApp", ["ui.router"]);
angular.module("myApp")
.config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("home", {
url: "/",
templateUrl: "blank.html"
})
.state("first", {
url: "/first",
templateUrl: "firstLayerPage.html"
})
.state("first.second", {
url: "/second",
templateUrl: "secondLayerPage.html"
})
.state("first.second.third1", {
url: "/third_Page1",
templateUrl: "thirdLayerPage1.html"
})
.state("first.second.third2", {
url: "/third_Page2",
templateUrl: "thirdLayerPage2.html"
})
}]); // end of config
})(); //end of enclosure
Index
<body ng-app="myApp">
<ul>
<li><a ui-sref="home">home</a></li>
<li><a ui-sref="first">First Layer</a> </li>
</ul>
<h1>Home Page</h1>
<hr>
<ui-view></ui-view>
</body>
first layer
<p>this is the first layer of pages.</p>
<ul>
<li><a id="showSecondLayer" ui-sref="first.second">Second Layer</a> </li>
</ul>
<hr>
<ui-view></ui-view>
<script type="text/javascript">
$(document).ready(function(){
$("#showSecondLayer").click(function(){
$("#secondLayer").show();
});
});
</script>
second layer
<div id="secondLayer">
<p>This is the second layer</p>
<ul>
<li><a id="thirdP1" ui-sref="first.second.third1">Third Layer Page 1</a> </li>
<li><a id="thirdP2" ui-sref="first.second.third2">Third Layer Page 2</a></li>
</ul>
<hr>
</div>
<ui-view></ui-view>
<script type="text/javascript">
$(document).ready(function(){
$("#thirdP1").click(function(){
$("#secondLayer").hide();
});
$("#thirdP2").click(function(){
$("#secondLayer").hide();
});
});
</script>
third layer p1
<p>This is page one of the third level of children</p>
<hr>
third layer p2
<p>This is page two of the third level of children</p>
<hr>
I am trying to follow up a tutorial and demo that I found here http://jsfiddle.net/scyrizales/pC9dH/
As a result this is the code snippet of what I have done
<div ng-app="GridCambiable" ng-controller="GridCambiableController">
<div class="bar">
<!-- These two buttons switch the layout varaible,
which causes the correct UL to be shown. -->
<a class="list-icon" ng-class="{active: isLayout('list')}" ng-click="setLayout('list')"></a>
<a class="grid-icon" ng-class="{active: isLayout('grid')}" ng-click="setLayout('grid')"></a>
</div>
<!-- We have two layouts. We choose which one to show depending on the "layout" binding -->
<ul ng-show="isLayout('grid')" class="grid">
<!-- A view with big photos and no text -->
<li ng-repeat="p in pics">
<img ng-src="{{p.images.low_resolution.url}}" />
</li>
</ul>
<ul ng-show="isLayout('list')" class="list">
<!-- A compact view smaller photos and titles -->
<li ng-repeat="p in pics">
<img ng-src="{{p.images.thumbnail.url}}" />
<p>{{p.caption.text}}</p>
</li>
</ul>
app.controller('GridCambiableController', ['$scope', 'instagram' ,
function ($scope, instagram){
// Layout por defecto
$scope.layout = 'grid';
$scope.setLayout = function(layout){
$scope.layout = layout;
};
$scope.isLayout = function(layout){
return $scope.layout == layout;
};
When I launch the code, I get this error on my chrome console
Uncaught Error: No module: GridCambiable
I have made a plunk of my attempt
http://plnkr.co/edit/9BYKw45ZrIgVpbixRsAz?p=preview
Please why am I getting this on my console.
Thanks.
You didn't include your script.js after you include angular.min.js
In your index.html:
<!--include angular-->
<script src="script.js"></script>
add this before your controller:
var app = angular.module("GridCambiable", []);
Alternative:
angular.module("GridCambiable", []).controller('GridCambiableController', ['$scope', 'instagram' ,
function ($scope, instagram){
// Layout por defecto
$scope.layout = 'grid';
$scope.setLayout = function(layout){
$scope.layout = layout;
};
$scope.isLayout = function(layout){
return $scope.layout == layout;
};
So, i have this main div, which wrapper the body code:
<main class="main">
</main>
And for which page i have a modifier with the name of the page:
Error page:
<main class="main main--error">
</main>
Events page:
<main class="main main--events">
</main>
Bookings page:
<main class="main main--bookings">
</main>
The main is always in the layout.html, because it will always be present on every page. How can i dynamically insert the class correspondent?
Should i create a MainController just for that? It has some clever way to do this without having to create a controller for just that?
UPDATE --
This is my layout.html:
<main class="main">
<section class="navbar" ng-controller="NavbarCtrl" ng-hide="pageName('Erro')">
<div class="navbar__container">
<div class="navbar__header">
<button class="navbar__toggle navbar__toggle--dashboard" data-sidebar-to="true">
<span class="navbar__icon-bar"></span>
<span class="navbar__icon-bar"></span>
<span class="navbar__icon-bar"></span>
</button>
<form class="navbar__form navbar__form--dashboard" role="search">
<input
class="navbar__search hide--mobile"
type="text" placeholder="Procure por algo...">
</form>
</div>
<ul class="navbar__list">
<li class="navbar__item">
<a class="navbar__link" href="#" title="logout">
<i class="icon icon__sign-out"></i>
<span class="hide--mobile"> Sair </span>
</a>
</li>
</ul>
</div>
</section>
<div
class="breadcrumb"
ng-controller="BreadcrumbCtrl"
ng-hide="pageName('Painel') || pageName('Erro')">
<div class="breadcrumb__container">
<h2 class="breadcrumb__title"> {{ $state.current.name }} </h2>
<ol class="breadcrumb__list">
<li class="breadcrumb__item breadcrumb__item--root"> Painel </li>
<li class="breadcrumb__item"> {{ $state.current.name }} </li>
</ol>
</div>
</div>
<div ui-view></div>
</main>
In the div with the ui-view, the Angular will append my pages, i have 3: error.tmpl.html, events.tmpl.html and bookings.tmpl.html
My generic app.js, where i register the angular module in the routes:
'use strict';
var adminApp = function($stateProvider, $urlRouterProvider) {
/*
* Booking Route
*
*/
var BookingCtrl = {
url: '/',
templateUrl: '/admin/booking/booking.tmpl.html',
controller: 'BookingCtrl'
};
/*
* Event Route
*
*/
var EventCtrl = {
url: '/eventos',
templateUrl: '/admin/event/event.tmpl.html',
controller: 'EventCtrl'
};
/*
* Error Route
*
*/
var ErrorCtrl = {
url: '/erro',
templateUrl: '/admin/error/505.tmpl.html',
controller: 'ErrorCtrl'
};
/*
* Register the states
*
*/
$stateProvider
.state('Bookings', BookingsCtrl)
.state('Eventos', EventCtrl)
.state('Error', ErrorCtrl);
$urlRouterProvider.otherwise('/');
};
angular.module('adminApp', [
'ui.router'
]).config(adminApp);
In my html templates i have this tiny html, which will be append in the ui-view.
The problem is that i need change the , if i access the error page, i need add the class 'main--error', if i access the events page, i need add the class 'main--events' and if i access the bookings page, i need add the class 'main--bookings'
It is conventional to reserve custom elements and attributes to angular directives. The directive will automatically add main class to top-level <main> and main main--statename to the elements belonging to view templates.
app.directive('main', function () {
return {
link: function (scope, element, attrs) {
var view = element.inheritedData('$uiView');
element.addClass('main');
if (!view) return;
element.addClass('main--' + view.state.name.toLowerCase());
}
};
});
Though it looks overengineered to me, there's nothing wrong with writing some classes by hand. If there's too much work with that maybe it is better to change the way the styles are organized.
Looked like directive 'main' will be inside other controllers, so the ng-class variable would be placed there.
In your Main Bookings controller:
$scope.class.name = 'main--bookings';
In your HTML
<main class="main" ng-class="class.name"></main>