Why is the dismissable alert not being dismissed? - angularjs

I'm building an app in Angular JS and Bootstrap.
http://numerology.andrewgolightly.com/
Enter some details and look at the results. There is a dismissable alert on the results page that is not being dismissed when the cross is clicked on.
I basically copied the code from http://getbootstrap.com/components/#alerts-dismissable
<div class="alert alert-info alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<span class="glyphicon glyphicon-info-sign"></span> This number represents who you are at birth and the native traits that you will carry with you through life. The most important number that will be discussed here is your Life Path number. The Life Path describes the nature of this journey through life.
</div>
Anyone know why it isn't being dismissed on my site?

You have only included the Bootstrap css, but for the dismissable functionality (and lots of other functionality in Bootstrap) you also need to include the js file.

You have to add jquery.js and bootstrap.js
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.1/js/bootstrap.min.js"></script>
in your head section

Related

jQueryUI Accordion treats <script> as part of output

Consider this code snippet:
<div id="accordion">
<h3>TEST</h3>
<p>Lorem ipsum</p>
<script>some JS code </script>
</div>
Once accordion is initialised, JS code is becoming a part of output. I can see that is being added some accordion attributes. How do I make accordion to ignore as part of visible data and keep it as a script instead?
My code is auto-generating each accordion panel and some JS functionality is built as part of it, hence the problem.
Thanks,
Rudolf
Why is it one comes up with an answer right posting on the forum?
Anyway, my solution is:
<div id="accordion">
<h3>TEST</h3>
<p>Lorem ipsum</p>
<script class="ignore">some JS code </script>
</div>
<script>
$( function() {
$( "#accordion" ).accordion({
header:'h3:not(.ignore)'
});
Not sure if this is a good way, but seem to work.
I am open to suggestions on a better way to implement what I need.
Rudolf

Finding elements in AngularJS using Protractor

I'm writing some automated tests on an AngularJS application. I'm trying to click a button but whatever method I try and use, Selenium refuses to find the element.
<div class="row" _ngcontent-c24="">
<div class="column-12 column-center" _ngcontent-c24="">
<div class="buttons column-center" _ngcontent-c24="">
<div class="buttons-container-centred tablet-up" _ngcontent-c35="">
<div _ngcontent-c35="">
<kf-button _ngcontent-c35="" btnstyle="secondary no-outline btn-big" _nghost-c8="">
<button class="secondary no-outline btn-big" _ngcontent-c8="" title="" type="">
<span _ngcontent-c8="">Use a demo room</span>
</button>
</kf-button>
<span _ngcontent-c35="">Instant access</span>
</div>
This is html around the button - button text is "Use a demo room"
I've tried:
element(by.xpath(" full path from FirePath ").click()
element(by. buttonText("Use a demo room").click()
element(by.xpath('//span[#ngcontent("Use a demo room"]')).click
...to mention a few.
Usual error message stating the element cannot be found once the timeout is reached.
Other similar buttons work fine with a full xpath.
Would be really grateful for advice!
Thanks
David

Why module 'ui.bootstrap' is not available?

I am trying this simple tutorial to try UI Bootstrap:
https://scotch.io/tutorials/how-to-correctly-use-bootstrapjs-and-angularjs-together
But I am running into two problems.
SyntaxError: expected expression, got '<' at ui-bootstrap-1.3.3.js:5:0
This is the first problem. I have not edited anything in the file, yet it says unexpected token for the very first line <!DOCTYPE html>
And the other one is as below:
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:modulerr] Failed to instantiate module ui.bootstrap due to:
[$injector:nomod] Module 'ui.bootstrap' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
I saw answers to all the related questions, some of them suggesting to include the other dependencies while other suggesting to make sure of the order of the dependencies. Tried everything but no joy.
Below is my html and js code. Please have a look
HTML
<html>
<head>
<style type="text/css">
#import "css/bootstrap.css";
#import "css/style.css";
</style>
<script src="js/angular.js"></script>
<script src="js/angular-animate.js"></script>
<script src="js/angular-touch.js"></script>
<script src="js/ui-bootstrap-1.3.3.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div class="container" ng-app="app" ng-controller="mainController">
<div class="text-center">
<p>Example of Angular and the normal Bootstrap JavaScript components</p>
<p class="text-success">This will work</p>
</div>
<h2>Buttons</h2>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary" ng-model="bigData.breakfast" btn-checkbox>
Breakfast
</label>
<label class="btn btn-primary" ng-model="bigData.lunch" btn-checkbox>
Lunch
</label>
<label class="btn btn-primary" ng-model="bigData.dinner" btn-checkbox>
Dinner
</label>
</div>
<pre><code>{{ bigData | json }}</code></pre>
<h2>Collapse</h2>
<a href="#" class="btn btn-primary" ng-click="isCollapsed = !isCollapsed">
Toggle Panel
</a>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a href="#" ng-click="isCollapsed = !isCollapsed">
Collapsible Group Item #1
</a>
</h4>
</div>
<div collapse="isCollapsed">
<div class="panel-body">Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
</div>
</div>
</div>
<pre><code>{{ isCollapsed }}</code></pre>
</div>
</body>
</html>
JS
angular.module('app', ['ngAnimate', 'ngTouch', 'ui.bootstrap'])
.controller('mainController', function($scope) {
// BUTTONS ======================
// define some random object
$scope.bigData = {};
$scope.bigData.breakfast = false;
$scope.bigData.lunch = false;
$scope.bigData.dinner = false;
// COLLAPSE =====================
$scope.isCollapsed = false;
});
Not sure what's going wrong.
Edit
Version details area as follows
Bootstrap v3.3.6
angular
angular-animate
angular-touch
all are having version AngularJS v1.5.3
Make sure ui-bootstrap-1.3.3 is loaded correctly in your app.
Please find working plunker below:
http://plnkr.co/edit/evG4XQ9ih9Cx0d1WF6YU?p=preview
you are missing ui-bootstrap-tpls.js file.
add this file in your page.
see example working plunkr
In my case, in a legacy application (AngularJS 1.3), it was because I put angular-ui-bootstrap to bower.js rather than package.js.
After I put it to package.js, ran npm install, copied to some source directory, and added to imports, it worked.
import '../js/dependencies/ui-bootstrap-tpls-0.14.3.min'
It is probably not the right way to do it, though.
I think it should be imported from bower_modules.
import '../bower_components/angular-ui-bootstrap/???';
But, the Bower hosting does not work anymore and an attempt to install through bower install fails with HTTP 502.
Also, what's weird, it worked unless I registered a provider:
.config(['$tooltipProvider', function ($tooltipProvider) { ...
This way, Angular started complaining that '$tooltipProvider' is not known.
Hope this helps, although I do not know much about the old AngularJS, so take it as potentially mediocre solution.

MEAN.io animate Angular UI Collapse

I've been playing around with the bootstrap Collapse (angular UI implementation) to show and hide a well in a MEAN.io application. The show and hide code below works but it doesn't animate the transition between the two states. I'd like to get a smooth animated transition but so far everything I've tried hasn't worked. Thanks in advance for any help you can provide.
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
<hr>
<div uib-collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
You are probably missing the dependency to ngAnimate in your Angular application:
angular.module('app', ['ngAnimate', 'ui.bootstrap']);
Remember to load the corresponding JavaScript as well:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>

Using Bootstrap Tooltip with AngularJS

I am trying to use the Bootstrap tooltip in an app of mine. My app is using AngularJS Currently, I have the following:
<button type="button" class="btn btn-default"
data-toggle="tooltip" data-placement="left"
title="Tooltip on left">
Tooltip on left
</button>
I think I need to use
$("[data-toggle=tooltip]").tooltip();
However, I'm not sure. Even when I add the line above though, my code doesn't work. I'm trying to avoid using UI bootstrap as it has more than I need. However, if I had to include just the tooltip piece, I'd be open to that. Yet, I can't figure out how to do that.
Can someone show me how to get the Bootstrap Tooltip working with AngularJS?
In order to get the tooltips to work in the first place, you have to initialize them in your code. Ignoring AngularJS for a second, this is how you would get the tooltips to work in jQuery:
$(document).ready(function(){
$('[data-toggle=tooltip]').hover(function(){
// on mouseenter
$(this).tooltip('show');
}, function(){
// on mouseleave
$(this).tooltip('hide');
});
});
This will also work in an AngularJS app so long as it's not content rendered by Angular (eg: ng-repeat). In that case, you need to write a directive to handle this. Here's a simple directive that worked for me:
app.directive('tooltip', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
element.hover(function(){
// on mouseenter
element.tooltip('show');
}, function(){
// on mouseleave
element.tooltip('hide');
});
}
};
});
Then all you have to do is include the "tooltip" attribute on the element you want the tooltip to appear on:
<a href="#0" title="My Tooltip!" data-toggle="tooltip" data-placement="top" tooltip>My Tooltip Link</a>
The best solution I've been able to come up with is to include an "onmouseenter" attribute on your element like this:
<button type="button" class="btn btn-default"
data-placement="left"
title="Tooltip on left"
onmouseenter="$(this).tooltip('show')">
</button>
Simple Answer - using UI Bootstrap (ui.bootstrap.tooltip)
There seem to be a bunch of very complex answers to this question. Here's what worked for me.
Install UI Bootstrap - $ bower install angular-bootstrap
Inject UI Bootstrap as a dependency - angular.module('myModule', ['ui.bootstrap']);
Use the uib-tooltip directive in your html.
<button class="btn btn-default"
type="button"
uib-tooltip="I'm a tooltip!">
I'm a button!
</button>
If you're building an Angular app, you can use jQuery, but there is a lot of good reasons to try to avoid it in favor of more angular driven paradigms. You can continue to use the styles provided by bootstrap, but replace the jQuery plugins with native angular by using UI Bootstrap
Include the Boostrap CSS files, Angular.js, and ui.Bootstrap.js:
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.angularjs.org/1.2.20/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
Make sure you've injected ui.bootstrap when you create your module like this:
var app = angular.module('plunker', ['ui.bootstrap']);
Then you can use angular directives instead of data attributes picked up by jQuery:
<button type="button" class="btn btn-default"
title="Tooltip on left" data-toggle="tooltip" data-placement="left"
tooltip="Tooltip on left" tooltip-placement="left" >
Tooltip on left
</button>
Demo in Plunker
Avoiding UI Bootstrap
jQuery.min.js (94kb) + Bootstrap.min.js (32kb) is also giving you more than you need, and much more than ui-bootstrap.min.js (41kb).
And time spent downloading the modules is only one aspect of performance.
If you really wanted to only load the modules you needed, you can "Create a Build" and choose tooltips from the Bootstrap-UI website. Or you can explore the source code for tooltips and pick out what you need.
Here a minified custom build with just the tooltips and templates (6kb)
Have you included the Bootstrap JS and jQuery?
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
If you don't already load those, then Angular UI (http://angular-ui.github.io/bootstrap/) may not be much overhead. I use that with my Angular app, and it has a Tooltip directive. Try using tooltip="tiptext"
<button type="button" class="btn btn-default"
data-toggle="tooltip" data-placement="left"
title="Tooltip on left"
tooltip="This is a Bootstrap tooltip"
tooltip-placement="left" >
Tooltip on left
</button>
I wrote a simple Angular Directive that's been working well for us.
Here's a demo: http://jsbin.com/tesido/edit?html,js,output
Directive (for Bootstrap 3):
// registers native Twitter Bootstrap 3 tooltips
app.directive('bootstrapTooltip', function() {
return function(scope, element, attrs) {
attrs.$observe('title',function(title){
// Destroy any existing tooltips (otherwise new ones won't get initialized)
element.tooltip('destroy');
// Only initialize the tooltip if there's text (prevents empty tooltips)
if (jQuery.trim(title)) element.tooltip();
})
element.on('$destroy', function() {
element.tooltip('destroy');
delete attrs.$$observers['title'];
});
}
});
Note: If you're using Bootstrap 4, on lines 6 & 11 above you'll need to replace tooltip('destroy') with tooltip('dispose') (Thanks to user1191559 for this upadate)
Simply add bootstrap-tooltip as an attribute to any element with a title. Angular will monitor for changes to the title but otherwise pass the tooltip handling over to Bootstrap.
This also allows you to use any of the native Bootstrap Tooltip Options as data- attributes in the normal Bootstrap way.
Markup:
<div bootstrap-tooltip data-placement="left" title="Tooltip on left">
Tooltip on left
</div>
Clearly this doesn't have all the elaborate bindings & advanced integration that AngularStrap and UI Bootstrap offer, but it's a good solution if you're already using Bootstrap's JS in your Angular app and you just need a basic tooltip bridge across your entire app without modifying controllers or managing mouse events.
You can use selector option for dynamic single page applications:
jQuery(function($) {
$(document).tooltip({
selector: '[data-toggle="tooltip"]'
});
});
if a selector is provided, tooltip objects will be delegated to the
specified targets. In practice, this is used to enable dynamic HTML
content to have tooltips added.
You can create a simple directive like this:
angular.module('myApp',[])
.directive('myTooltip', function(){
return {
restrict: 'A',
link: function(scope, element){
element.tooltip();
}
}
});
Then, add your custom directive where is necessary:
<button my-tooltip></button>
You can do this with AngularStrap which
is a set of native directives that enables seamless integration of Bootstrap 3.0+ into your AngularJS 1.2+ app."
You can inject the entire library like this:
var app = angular.module('MyApp', ['mgcrea.ngStrap']);
Or only pull in the tooltip feature like this:
var app = angular.module('MyApp', ['mgcrea.ngStrap.tooltip']);
Demo in Stack Snippets
var app = angular.module('MyApp', ['mgcrea.ngStrap']);
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>
<div ng-app="MyApp" class="container" >
<button type="button"
class="btn btn-default"
data-trigger="hover"
data-placement="right"
data-title="Tooltip on right"
bs-tooltip>
MyButton
</button>
</div>
easiest way , add $("[data-toggle=tooltip]").tooltip(); to the concerned controller.
var app = angular.module('MyApp', ['mgcrea.ngStrap']);
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>
<div ng-app="MyApp" class="container" >
<button type="button"
class="btn btn-default"
data-trigger="hover"
data-placement="right"
data-title="Tooltip on right"
bs-tooltip>
MyButton
</button>
</div>
Please remember one thing if you want to use bootstrap tooltip in angularjs is order of your scripts if you are using jquery-ui as well, it should be:
jQuery
jQuery UI
Bootstap
It is tried and tested
Only read this if you are assigning tooltips dynamically
i.e. <div tooltip={{ obj.somePropertyThatMayChange }} ...></div>
I had an issue with dynamic tooltips that were not always updating with the view. For example, I was doing something like this:
This didn't work consistently
<div ng-repeat="person in people">
<span data-toggle="tooltip" data-placement="top" title="{{ person.tooltip }}">
{{ person.name }}
</span>
</div>
And activating it as so:
$timeout(function() {
$(document).tooltip({ selector: '[data-toggle="tooltip"]'});
}, 1500)
However, as my people array would change my tooltips wouldn't always update. I tried every fix in this thread and others with no luck. The glitch seemed to only be happening around 5% of the time, and was nearly impossible to repeat.
Unfortunately, these tooltips are mission critical for my project, and showing an incorrect tooltip could be very bad.
What seemed to be the issue
Bootstrap was copying the value of the title property to a new attribute, data-original-title and removing the title property (sometimes) when I would activate the toooltips. However, when my title={{ person.tooltip }} would change the new value would not always be updated into the property data-original-title. I tried deactivating the tooltips and reactivating them, destroying them, binding to this property directly... everything. However each of these either didn't work or created new issues; such as the title and data-original-title attributes both being removed and un-bound from my object.
What did work
Perhaps the most ugly code I've ever pushed, but it solved this small but substantial problem for me. I run this code each time the tooltip is update with new data:
$timeout(function() {
$('[data-toggle="tooltip"]').each(function(index) {
// sometimes the title is blank for no apparent reason. don't override in these cases.
if ($(this).attr("title").length > 0) {
$( this ).attr("data-original-title", $(this).attr("title"));
}
});
$timeout(function() {
// finally, activate the tooltips
$(document).tooltip({ selector: '[data-toggle="tooltip"]'});
}, 500);
}, 1500);
What's happening here in essence is:
Wait some time (1500 ms) for the digest cycle to complete, and the titles to be updated.
If there's a title property that is not empty (i.e. it has changed), copy it to the data-original-title property so it will be picked up by Bootstrap's toolips.
Reactivate the tooltips
Hope this long answer helps someone who may have been struggling as I was.
Try the Tooltip (ui.bootstrap.tooltip). See Angular directives for Bootstrap
<button type="button" class="btn btn-default"
tooltip-placement="bottom" uib-tooltip="tooltip message">Test</button>
It is recommended to avoid JavaScript code on the top of AngularJS
for getting tooltips to refresh when the model changes, i simply use data-original-title instead of title.
e.g.
<i class="fa fa-gift" data-toggle="tooltip" data-html="true" data-original-title={{getGiftMessage(gift)}} ></i>
note that i'm initializing use of tooltips like this:
<script type="text/javascript">
$(function () {
$("body").tooltip({ selector: '[data-toggle=tooltip]' });
})
</script>
versions:
AngularJS 1.4.10
bootstrap 3.1.1
jquery: 1.11.0
AngularStrap doesn't work in IE8 with angularjs version 1.2.9 so not use this if your application needs to support IE8
impproving #aStewartDesign answer:
.directive('tooltip', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
element.hover(function(){
element.tooltip('show');
}, function(){
element.tooltip('hide');
});
}
};
});
There's no need for jquery, its a late anwser but I figured since is the top voted one, I should point out this.
install the dependencies:
npm install jquery --save
npm install tether --save
npm install bootstrap#version --save;
next, add scripts in your angular-cli.json
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/tether/dist/js/tether.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js",
"script.js"
]
then, create a script.js
$("[data-toggle=tooltip]").tooltip();
now restart your server.
Because of the tooltip function, you have to tell angularJS that you are using jQuery.
This is your directive:
myApp.directive('tooltip', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('mouseenter', function () {
jQuery.noConflict();
(function ($) {
$(element[0]).tooltip('show');
})(jQuery);
});
}
};
});
and this is how to use the directive :
<a href="#" title="ToolTip!" data-toggle="tooltip" tooltip></a>

Resources