ng-routed AngularJS SPA ng-show a Bootstrap Carousel not working - angularjs

PLUNKER
I'm developing an AngularJS SPA, using ng-route and ng-animate. I'm trying to display the Bootstrap Carousel on the index.html#/ using ng-show. Very simple task.
I want the Carousel to show on the index page, but not on the about page or the contact page.
I'm trying to do the logic in my indexController like so:
if ($location.path() == "/") {
$scope.isIndexPage = true;
}
And in my HTML:
<div id="myCarousel" class="carousel slide" data-ride="carousel" ng-show="isIndexPage">
But it does not work as expected: the Carousel does not display. Once the ng-show attribute is removed, the carousel displays, but on all pages.
How can I get the Carousel to display only on the index page? I've tried variations such as ng-include-ing and ng-ifing carousel.htm. Numerous Google searches such as "AngularJS SPA and Bootstrap Carousel" reveal unanswered SO questions.
Thanks in advance for any input. Here's the PLUNKER.

It's a bit strange not to put something that is specific to the home page into the template of the home page, but anyway...
Your code has 2 main problems:
you're trying to access a variable from the indexController scope from a part of the page that is not controlled by this controller. The controller only controls its view. The $scope of the controller is limited to its view.
You're initializing the isIndexPage variable only once. It never changes after.
Solution:
create a controller for the whole body of the page, and put the logic used to control the visibility of the carousel in that controller
use a function that will return true or false based on the current location
See http://plnkr.co/edit/8luxeIbyIPEKy0LkemM0?p=preview for a fork of your plunker (the additional JS code is at the end of script.js):
appname.controller('MainCtrl', function($scope, $location) {
$scope.isIndexPage = function() {
return $location.path() === '/';
}
});
and in the index.html file:
<body ng-controller="MainCtrl">
<div ng-show="isIndexPage()" ...>

Related

Angularjs ng-class condition for window.location

i'm trying to unset/set a css class at a specific path url
I tried writing this code, but without any success
<div ng-class="window.location.toString().includes('ocs')? '' :'icon-home'"></div>
in chrome console i see this:
<div ng-class="window.location.toString().includes('ocs')? '' :'icon-home'" class="icon-home"></div>
I need to create a new angularjs module and scope for do this?
As you are clearing the class if location contains 'ocs', the correct approach should be this:
// in you angularjs controller:
$scope.containesOCS = window.location.toString().includes('ocs');
And in the html:
<div ng-class="{'icon-home': !containesOCS}"></div>
And if you haven't created an angular module or controller, please do so first. Without the
ng-app the angular attributes won't work.

AngularJS + CSS animations to trade out inspector panes

Been struggling on how to tie angular with CSS animations... I'm sure I'm not getting something fundamental.
My goal is to have a list of search results. When you click one, a detail view will slide out from under the list. When you click another, the old detail view slides back, the details for the new one load, and then the detail view slides back in.
I don't have any code to show that even remotely works, but if anyone can point me at an example or offer some basic code, I would be extremely grateful.
Thanks!
You want to use ng-animate for animations.
ng-animate essentially adds CSS classes to elements automatically (often for a short time) during, for example, state transitions, during the population of an ng-repeat, etc.
You do not add the CSS classes to elements yourself this is done by ng-animate.
You do, however, apply the styling for those class in your style-sheet.
Its up to you, in your CSS, to do something with those automatically added CSS classes. Typically, you might want to do a fade in using CSS transitions.
For example ... https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
OR
http://www.nganimate.org/
The ng-animate link details exactly which classes are added when. There are too many to mention here.
You might also want to use ng-fx
ng-fx github is here https://github.com/AngularClass/ng-fx
ng-fx requires ng-animate
ng-fx can be seen at work on its demo page - http://hendrixer.github.io/
This should get you going :)
I would go with ng-show.
var myApp = angular.module('myApp',[]);
myApp.controller('SomeController', ['$scope', function($scope) {
//this can be a service with a ngResource, an ajax call using $http... this is a baaaaasic dummy example.
$scope.yourScopeFunction = function(){
$scope.data = '';
$scope.data = {};
$scope.data.param1 = 'Hello';
$scope.data.param2= 'Jhon';
}
}]);
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="SomeController">
<div >
<div class="elementClass" ng-click="yourScopeFunction()">Element1</div>
<div class="elementClass" ng-click="yourScopeFunction2()">Element1</div>
</div>
<div class="yourClass" ng-show="data != ''">
<div>{{data.param1}}</div>
<div>{{data.param2}}</div>
</div>
</body>
Then, when the ng-show's expression evaluates to true (the data variable has some content), Angular will attach a new class to your yourClass element called
.ng-hide-add and when it evaluates to false, Angular will add the class .ng-hide-remove.
You just have to make the transition (or animation you want) based on the classes your element will have in both those moments. Like in the documentation example.
Something like:
.yourClass.ng-hide-add{
//some transition or animation css
}
.yourClass.ng-hide-remove{
//some transition or animation css
}
Note that my function on the example does a $scope.data = ''; so the angular ng-show expression evaluates to false and the .ng-hide-remove is added.
By the way, you will need to add Angular Animations library.

Render plaintext using Angular route, ui-view

I am using Angular 1.3, creating views using ui-router and ui-view.
I have added the ui-view on index.html file, which has Menu, footer and in the middle ui-view for main content.
I have created whole application using states with $stateProvider.state('state_name')
Now I want to create a page with plain text, no html tags, just plaintext. But the problem is when I create route for that, it includes header and footer, which is correct behavior of Angular. But how can I create a view with no menu, footer included, just plain text which I will add in view file, with route. Any solution?
You can have a service that changes is bond to the main controller. The first answer to this question explains how this can be achived.
I've made a modified Plnkr example for your specific use case here
app.factory('Page', function(){
var visible = true;
return {
visible: function() { return visible; },
setVisible: function(state) { visible = state}
};
});
The factory called Page provides access to a visible variable for both the main controllers and the controllers inside the ng-views.
The aim is to change this visible variable in the controller in order to change the visibility of the main components outside of the ng-view.
function MainCtrl($scope, Page) {
$scope.Page = Page;
}
To this end we have a binding in the main controller that can access the page service.
<html ng-app="myApp" ng-controller="MainCtrl">
<body>
<h1 ng-hide="Page.visible()">Page Header</h1>
<ul>
<li>test1
<li>test2
</ul>
</html>
And in the html, we define that the ng-if is controlled by this visible variable in the MainContorllers Page.
function Test1Ctrl($scope, Page) {
Page.setVisible(false);
}
Finally, we can call the change visibility function from the other views in order to change the visibility of the headers and footers in the Main View.

Theater.js not working on page loaded with Angular ui route

I am trying to make Theater.JS work with Angular application.
If Div in which TheaterJS is supposed to insert dynamically typed contents is on the index page, it works perfectly fine.
But if I keep the same div on the page which is loaded using ui-view (or using ng-view for that matter), TheaterJs throws following exception
Uncaught TypeError: Cannot set property 'innerHTML' of null
I understand its happening because TheaterJs is loaded before main.html page is loaded through ui-view. But I am not sure how to handle this scenario.
Here is the plnkr demo with the example. The TheaterJS works when div is on index page but fails to work when the div is on main.html which is loaded dynamically using ui-view.
In my project, I want to use TheaterJS on a page loaded using ui-view.
By placing the script include into the <head> and moving the call to new TheaterJS() into a directive, you are able to use it in your partials.
Here is a plunker showing your working template:
http://plnkr.co/edit/JAbSmNOAZtUMkc976sh8?p=preview
Directive:
app.directive("theaterDirective", function() {
return {
link: function () {
var theater = new TheaterJS();
theater.describe("text", {speed: .7, accuracy: .7}, "#text");
theater.write("text:It now works in template partials", 600);
theater.write("text:It is no longer restricted to the Index page", 600);
theater.write(function () { theater.play(true); });
}
}
})
HTML partial:
<h1>This is main.html page content</h1>
<h1 theater-directive id="text"><noscript></noscript></h1>

AngularJS load tabbed content directive dynamicly

I have a tabbed navigtion in my webapp that looks like this
Now I want to Change the directive each time the user clicks on one of the Navigation points. My Idea was to init the page with the first template.
$scope.currentDirective = $compile('<div order-Sale></div>');
Then when the user clicks on a tab, I wanted to change and compile the content again with a new directive in it. But for some reason this is not working. How would you proceed in order to archive this dynamic content loading? I really want to only load the content on necessary need and not just to show or hide it. I think using directives is the right way to go for it, but I'm a but stuck at the implementation... Someone any pointer ? (I don't want to use any jQuery)
What I tried [Edit]:
The controller.js
app.controller('pageController',['$scope','$compile', function($scope, $compile){
var templates = ['<div first-template></div>','<div second-template></div>'];
$scope.currentTemplate = $compile(templates[0]);
$scope.changeTemplate = function(id) {
$scope.currentTemplate = $compile(templates[id]);
};
}]);
The HTML
<div ng-controller="pageController">
<li>
<a ng-click="changeTemplate('1')">Change Template</a>
</li>
{{currentTemplate}}
</div>
UPDATE
$compile returns a linking function not a value, you cannot just bind it to your template with interpolation.
You should use ngBindHtml instead of regular bindings ( ngBind & {{ }} ).
ngBindHtml does compiling, linking and watching all out-of-the-box.
With ng-bind-html-unsafe removed, how do I inject HTML?
Here is a plunker
app.controller('pageController',['$scope','$compile','$sce', function($scope, $compile, $sce){
var templates = ['<div>first-template</div>','<div>second-template</div>'];
$scope.currentTemplate = $sce.trustAsHtml(templates[0]);
$scope.changeTemplate = function(id) {
$scope.currentTemplate = $sce.trustAsHtml(templates[id]);
};
}]);
The markup:
<div ng-controller="pageController">
<button ng-click="changeTemplate('1')">Change Template</button>
<div ng-bind-html="currentTemplate"></div>
</div>
For more robust dynamic content loading you have two good alternatives:
ngRoute from angular team.
ui-router from angular-ui team.
If you want to change and compile the content again, well that's exactly what ng-view/ ui-view directives already do for you.
Why not just use a directive:
You probably need to load a different template (html partial) for each tab.
You probably need to change the url based on the tab (and vice versa)
You probably need to instantiate a different controller for each tab.
ngRoute and ui-router come with their own directives.
You can implement your own route module if you want but that's more than just a directive.

Resources