AngularJS: Load CSS based on data retrieved from the controller - angularjs

I'm trying to load specific CSS file using AngularJS controller.
HTML code looks like
<html lang="en" ng-app="CPCplusLunchLink" ng-controller="mainController">
<head>
<meta charset="UTF-8">
<script src="js/lib/angularjs/angular.min.js"></script>
<script src="js/lib/angularjs/angular-route.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/main.js"></script>
<script src="js/controllers/events.js"></script>
<script src="js/services/events.js"></script>
<link rel="stylesheet" ng-href="css/{{ css }}.css">
app.js related part
.when('/', {
templateUrl: 'views/home.html',
controller: 'EventsController'
})
mainContorller
myApp.controller('mainController', ['$scope', function($scope){
// set the default css
$scope.css = 'style';
}]);
and controller where I have set value for the CSS
myApp.controller('EventsController', ['$scope','events','$rootScope', function($scope, events, $rootScope){
// set dedicated CSS
$rootScope.css = 'style2';
events.then(function(data) {
$scope.eventsList = data.evets;
console.log($scope.eventsList);
});
}]);
but I'm not able to change default CSS value based on loaded controller.
Any clue what I have missed?

You have to let angular know about the dynamic CSS variable which is defined inside the controller. So you have to define the controller on HTML tag
<html lang="en" ng-app="myApp" ng-controller="EventsController">

Related

'Angular is not defined'

I have my files setup right now out of which one them is my index.html file and another is a app.javascript file. For some reason I keep getting error saying" Angular is not defined" which I unsure why as my script files look placed properly too. Below is how my index file and app.js file look like
index.html
<html>
<head>
<meta charset="utf-8">
<!Stylesheet>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/darkly/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<!Javascript>
<!-- load angular, nganimate, and ui-router -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script>
<script src="app.js"></script>
</head>
<!MainAngularApp>
<body ng-app="OnboardingApp">
<div class="container">
<!Injecting all the views here>
<div ui-view></div>
</div>
</body>
</html>
app.js
//Creating our Angular App injecting ngAnimate, UIRouter
angular.module('OnboardingApp', ['ngAnimate', 'ui.router'])
//Configuring the routes
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
//Route followed to show our form
.state('form',{
url:'/form',
templateUrl: 'form.html',
controller: 'formController'
})
//Nested States where each will have their own view
//Nesting the sign up form
.state('form.signup',{
url:'/signup',
templateURL:'form-signup.html'
})
//Nesting the Question form
.state('form.questions',{
url:'/questions',
templateUrl:'form-questions.html'
})
//Nesting the Finish form
.state('form.finish',{
url:'/finish',
templateUrl:'form-finish.html'
});
$urlRouterProvider.otherwise('/form/signup');
})
.controller('formcontroller', function($scope){
//Storing all the form data into the form data object
$scope.formData= {};
//Function to process form data
$scope.processData = function(){
alert('Sign up is successful')
};
});
You need to define ng-app in your view so that angularjs app gets initiatied,
<div class="container" ng-app="OnboardingApp">

Routing Function in AngularJS Does Not Get Executed

Newbie with AngularJS here.
I have an index.html file below, which references an Javascript file named app.js. The index.html file is as below:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#*" data-semver="1.2.22" src="https://code.angularjs.org/1.2.22/angular.js"></script>
<script data-require="angular-route#*" data-semver="1.2.20" src="https://code.angularjs.org/1.2.20/angular-route.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
<script src="controller1.js"></script>
</head>
<body>
<h1>Github Viewers</h1>
<div ng-view></div>
</body>
</html>
In my app.js file, I have the following codes:
(function(){
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider){
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "controller1"
})
.otherwise({redirectTo: "/main"});
});
}());
I've set breakpoints (in Chrome Dev Tools) on the line:
templateUrl: "main.html",
But I am unable to get into this line.
Console Window shows no errors, so I am a little stumped.
Appreciate any insight on where to look further on this.
You are using the wrong app name.
Change <html ng-app="myApp"> to <html ng-app="githubViewer">
Edit
You cannot put a breakpoint in that line (templateUrl: "main.html"). Note that's an Object definition and not a function:
{
templateUrl: "main.html",
controller: "controller1"
}
And like all Objects, they are defined in an atomic operation. It's like if all its properties were created at once, meaning that you cannot "break" the execution for a specific property.
I've tested with Chrome dev tools and it doesn't even allow me to set a breakpoint in that line. Not sure how you did it...
If you want to check if the "main.html" template is being loaded, watch the network tab of the Chrome dev tools.
I think your dependency injection is missing controller1 module..
if you managing controllers in different module you have to inject it in your app.js
//controller1.js
angular.module('controllers',[])
.controller('controller1',function(....)
//app.js
var app = angular.module("myApp", ["controllers","ngRoute"]);
...
//index.html
...
<script src="controller1.js"></script>
<script src="app.js"></script>
...

How to inherit page appearance?

I have a few pages in my website.
I have a general frame for my website: Top, bottom, and general css are the same for all pages.
What is the convenient way to share the frame between all pages, so that they all look the same.
The AngularJS way to achieve this is by the use of ng-view and routes.
For this, you must include the angular-route file and inject ngRoute in your app. Follow the example:
index.html
<!DOCTYPE html>
<html ata-ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<header><h1> Header for all pages </h1></header>
<div data-ng-view></div> <!-- your files will be rendered here -->
<footer>...</footer>
<script src="path/to/angular.min.js"></script>
<script src="path/to/angular-route.min.js"></script>
<script src="path/to/app.js"></script>
</body>
</html>
app.js
angular.module('myApp', ['ngRoute'])
.controller('PageCtrl', ['$scope', function($scope) {
$scope.title = "The Title";
}])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when("/", {
templateUrl: "path/to/page.html",
controller: "PageCtrl"
}).
}]);
page.html
<h3> {{ scope.title }} </h3>

Using Zurb Foundation Interchange with AngularJS

I'm working on an AngularJS project that uses Zurb Foundation as its CSS framework. I'm trying to figure out how to using Foundation's data interchange within the context of an AngularJS view. Is this even possible, I can't seem to get it to work. This is what I currently have:
index.html
<!DOCTYPE html>
<html ng-app='app' xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="foundation/normalize.css" />
<link rel="stylesheet" href="foundation/foundation.min.css" />
<link rel="stylesheet" href="app.css" />
</head>
<body>
<div id="view" ng-view></div>
<script type="text/javascript" src="jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript" src="foundation/foundation.min.js"></script>
<script type="text/javascript" src="angularjs/1.2.7/angular.min.js"></script>
<script type="text/javascript" src="angularjs/1.2.7/angular-route.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
app.js
angular.module('app', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.otherwise({ templateUrl: '/views/interchange.html', controller: myCtrl });
})
.run(function ($rootScope, $location) {
$rootScope.$on('$viewContentLoaded', function () {
$(document).foundation();
});
})
;
function myCtrl() {
console.log('loading controller');
}
interchange.html
<article>
testing interchange
<div data-interchange="[phone.html, (small)], [portrait.html, (medium)], [landscape.html, (large)]"></div>
</article>
When I load my app, I can see 'testing interchange'. However, the content (phone.html, portrait.html, landscape.html) based on the size of the screen is not shown. Phone.html, Portrait.html, and landscape.html just have text inside DIV elements that say 'Phone', 'Portrait', and 'Landscape' effectively.
Is there a way to leverage Foundation's data interchange stuff inside of a AngularJS ng-view? If so, how? Thank you
The main point here is that the data-interchange feature of Zurb runs on DOMContentLoad event, and the load of AngularJS' views is async. So, the event already happened.
To get over this, you need to trigger the data-interchange manually using $(document).foundation('interchange', 'reflow'); or $(document).foundation('reflow'); to reflow all components.
To trigger this on the right place, you need to listen to a special event on AngularJS routing system called $routeChangeSuccess. Something like this:
module.run(function ($rootScope) {
$rootScope.$on('$routeChangeSuccess', function () {
$(document).foundation('reflow');
});
});
Hope this help you.

ng view not working with custom directive

I have recently started learning angularJS and ran into an issue with ng-view directive. Apologies if this question is too naive.
This is my index.html file. As you can see, I am using ng-view directive to abstract out some html code from index.html file.
<!doctype html>
<html lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/directives.js"> </script>
<script src="js/controllers.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
This is my app.js file. I am using the same partial template for all the urls.
angular.module('phonecat', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl}).
otherwise({templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl});
}]);
and this is my searchbox.html
<div id="container">
<input type="text" name="s" id="s" float-up="{perspective: '100px', x: '150%'}"/>
</div>
and finally this is my directives.js file:
'use strict';
var myAppModule = angular.module('phonecat', []);
myAppModule.directive('floatUp', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function($scope, element, attrs) {
console.log("test successful");
}
};
});
When I run this in the browser, the link function of my floatUp directive is never invoked.
When I see the rendered html of my index.html page, I get this (Note that ng-view didn't substitute the searchbox html):
<!DOCTYPE html>
<html class="ng-scope" lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js">
<style type="text/css">
<script src="js/app.js">
<script src="js/directives.js">
</head>
<body>
<div ng-view=""></div>
</body>
</html>
Other observations:
When I remove the directives.js from the index.html file ng-view works perfect and searchbox shows up fine.
When I copy paste the searchbox.html content to the index.html file, the link function is invoked properly.
Is this a known issue? Do custom directives mess up with ng-view and make it futile. I assure you I did extensive googling before posting my question here but couldn't find any appropriate answer.
Move this line from the directives.js
var myAppModule = angular.module('phonecat', []);
to the top of app.js
That way you're always working with the same angular module instance instead of creating new instances of it.
All your controllers, directives, and configs will then be myApModule.controller (or .config, or .directive)
Also in the app.js the references to controller in the routes should be strings controller: 'PhoneListCtrl' as PhoneListCtrl is not defined yet.
Your controllers.js wasn't provided but could look something like this:
myAppModule.controller('PhoneListCtrl', ['$scope', function($scope) {
//Controller code here
}]);
apps.js would now look like this:
myAppModule.
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'}).
otherwise({templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'});
}]);

Resources