AngularJS + Bootstrap-UI: tooltip not hidden when button is disabled - angularjs

I'm creating a web app using AngularJS + Twitter Bootstrap and Bootstrap-UI. When I place a tooltip on a button, it shows as expected; but if the button gets disabled (by the underlying controller) after being clicked, and the tooltip was being shown, the tooltip is not hidden and stays there forever. Here's a repro:
Plunker: http://embed.plnkr.co/numlaAuLOxh3a03Z7O85/preview
Just hover the button to make the tooltip appear, and then click it. The button is disabled, and the tooltip stays there. How can I avoid this behavior and have my tips correctly hidden?

I found that using simply replacing buttons with anchor tags worked perfectly for me.
<a role="button" type="button" class="btn btn-danger"
ng-click="someAction()" tooltip="Tooltip" ng-disabled="isDisabled">
<span class="glyphicon glyphicon-minus"></span>
</a>

Searching through GitHub issues I found the suggestion (seems to be related to the issue opened by you?) to use wrapping element that has a tooltip around the element: http://jsfiddle.net/RWZmu/
<div style="display: inline-block;" tooltip="My Tooltip">
<button class="navbar-btn btn-danger" ng-click="test()" ng-disabled="isDisabled" tooltip="Here's the tip">
<i class="glyphicon glyphicon-forward"></i>
</button>
</div>

Use the following logic here
HTML
<div ng-app="someApp" ng-controller="MainCtrl"
class="likes" tooltip="show favorites" tooltip-trigger="mouseenter"
ng-click="doSomething()">{{likes}}</div>
JS
var app = angular.module('someApp', ['ui.bootstrap']);
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.setTriggers({
'mouseenter': 'mouseleave',
'click': 'click',
'focus': 'blur',
'hideonclick': 'click'
});
}]);
app.controller('MainCtrl', function ($scope) {
$scope.likes = 999;
$scope.doSomething = function(){
//hide the tooltip
$scope.tt_isOpen = false;
};
})
Souce
Hide angular-ui tooltip on custom event
http://jsfiddle.net/3ywMd/10/

Related

ng-select button opens file system dialogue twice

So I am tracking down a bug that I can't quite get a handle around. The problem is this, if you have a button with ng-select on it, unfocus the browser (click on desktop) and then double click on the button, it opens up the browser file system dialogue twice, throwing away the first input. The question is how to force it to only ever open the file dialogue once.
The relevant code:
<!-- Table Buttons -->
<div class="container dashboard__table__action-items-container" ng-if="user.Welcomed">
<button class="btn btn-primary" ngf-select="onFileSelect($files)" ngf-multiple="true" style="margin-right: 15px;">
<i class="fa fa-cloud-upload fa-3" style="margin-right: 4px"></i> Upload Meeting
</button>
...
</div>
Edit:
I tested this behavoir with several browsers and it doesn't happen (firefox, safari, opera). This only happens on chrome. Version for ng-file-upload is 12.2.9, chrome Version 52.0.2743.116.
So I ended up "solving" this by hacking around it, but I still think it is a bug with chrome and/or ng-file-select. For posterity, if you wrap the button in a div that has the ngf-select, you can manually debounce the event propagation.
Relevant code:
html:
<div ngf-select="onFileSelect($files)" ngf-multiple="true" style="width: 0;">
<button class="btn btn-primary" ng-click="debounceMeetingCreation($event)" style="margin-right: 15px;">
<i class="fa fa-cloud-upload fa-3" style="margin-right: 4px"></i> Upload Meeting
</button>
</div>
in the controller:
var meetingCreationClicked;
$scope.debounceMeetingCreation = function ($event) {
if (meetingCreationClicked) {
$event.preventDefault();
$event.stopPropagation();
return false;
}
meetingCreationClicked = true;
$timeout(function(){
meetingCreationClicked = false;
}, 1000);
};

Follow download link and dismiss modal?

I have inherited a GUI written with Angular, and at the moment I don't even know enough to trim it down to a fiddle. So I'm hoping this is more straightforward than it appeared on a quick Google.
I have a modal dialog created using Bootstrap that is basically the same as the live demo here: http://getbootstrap.com/javascript/
A copy of the source from that link:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
The main difference in my case is that the "Save Changes" button is actually a link - to a resource which is downloaded without leaving the page. It looks like this:
<a ng-href="{{downloadUrl}}" class="btn btn-primary">Download</a>
My goal is to have the above modal dialog dismissed when the link is clicked, while still downloading the file. If I use data-dismiss, the download doesn't happen.
If I need to go digging around the code, that's fine, but I'm hoping there's a simple change to the template that will do the trick. Any suggestions?
First, when using with AngularJS 1.x, always use Bootstrap UI.
When using Bootstrap UI's $uibModal, it is way easier to manipulate the modal, and pass data between the view and the modal. The reason the link does not work, is because the modal should be closed first.
You can create a simple function which replaces href or ng-href: It closes the modal first, and goes to the link second.
And, remember, please do not use jQuery, and always try to use AngularJS dependencies like $window instead of window, when they're available. This also goes for onclick. always use ng-click, and handle the logic in your controller.
In your template, add the controller, and an ng-click-attribute:
<div ng-controller="MyCtrl as $ctrl">
<a href target="_blank" class="btn btn-primary" ng-click="$ctrl.go('#/some/url')"> Go </a>
</div>
In your controller, add the logic, for closing the modal, and following the link:
app.controller('MyCtrl', function($uibModalStack, $window) {
this.go = function(path) {
$uibModalStack.dismissAll();
$window.location.href = path;
}
})
You have to close the modal yourself. Here is a bootstrap.js only solution without angular. In angular you would open the modal with angular-bootstrap and close it also that way.
<a ng-href="some-reosource-url" target="_blank" class="btn btn-primary" onClick="closeModal()">Download</a>
function closeModal() {
$('#myModal').modal('hide');
}
http://plnkr.co/edit/0sRb5VdT9isEFdJ66Rxe?p=preview
Here's a working Plunker.
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.hideAndDownload = function() {
$('#myModal').modal('hide');
var link = document.createElement("a");
link.download = "data:text/html";
link.href = "http://code.jquery.com/jquery-1.11.3.min.js";
link.click();
}
});
Markup
<button type="button" class="btn btn-primary" ng-click="hideAndDownload()">Save changes</button>

How to show preloader inside button instead text Angular JS?

I use Angular JS library ngActivityIndicator.
I tried to show preloader inside element div instead text when button is pushed:
<div ng-activity-indicator="CircledDark">
<div ng-click="Add();" class="btn shareBtn">
<div ng-view></div>
<span>Text</span>
</div>
</div>
I posted <div ng-view></div> inside and have added directive ng-activity-indicator="CircledDark" to parent element.
When I click button, I call function that display preloader:
$activityIndicator.startAnimating();
But preloader is created outside of button:
<div ng-show="AILoading" class="ai-circled ai-indicator ai-dark-spin"></div>
This is official documantation, from here I have taken example:
https://github.com/voronianski/ngActivityIndicator#directive
How to show preloader inside button instead text Angular JS?
I think the only solution is to separate your ng-view and button, at least they do something similar in their sample page. So, in your markup you could do something like this:
<div ng-click="add()" class="btn btn-default" ng-activity-indicator="CircledDark">
<span ng-show="!AILoading">Add</span>
</div>
<div ng-view ng-show="!AILoading">{{ delayedText }}</div>
And in your controller:
$scope.delayedText = "";
$scope.add = function() {
$activityIndicator.startAnimating();
$timeout(function() {
$scope.delayedText = "Here we are!";
$activityIndicator.stopAnimating();
}, 3000);
};
Here is full Demo, you can play with CSS a little so the size of the button won't change when text is replaced by icon.

Element with popover and tooltip

In a large form, I'm using popovers to display error messages from the validation (I know, not best practice).
Now, I also want to add tooltips to display detailed explanation of the input.
However, using both, the tooltip and the popover directive (and their associated -trigger and -placement directives), the behavior is odd/buggy: Both, tooltip and popover are placed based on the popover-placement directive (ignoring the tooltip-placement) - and display the text provided for the popover.
<button class="btn btn-default"
popover="Popover" popover-trigger="mouseenter" popover-placement="right"
tooltip="Tooltip" tooltip-trigger="mouseenter" tooltip-placement="top" >
Label</button>
See this plunkr.
Any idea how to make this work?
They actually infact use the same placement function.
From the docs on popover:
The popover directive also supports various default configurations through the $tooltipProvider. See the tooltip section for more information.
Meaning if you had the following code:
app.config(['$tooltipProvider', function($tooltipProvider){
$tooltipProvider.options({
'placement': 'right'
});
}]);
It would change the default for both tooltips and popovers.
Best I can think of is it have some sort of wrapper around the element so you can do each in turn.
<button class="btn btn-default sampleBtn"
popover="Popover" popover-trigger="mouseenter" popover-placement="right">
<span tooltip="Tooltip" tooltip-trigger="mouseenter" tooltip-placement="top">
Tooltip + Popover
</span>
</button>
Demo in Plunker
A very Simple Way..Just Make a parent Span for the button and attach those properties with that Span. I have Some Code for that too
<span title="Popover title" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Some content in Popover on bottom">
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="right" title="Tooltip on right">Tooltip on right</button>
</span>
Here is the JS Fiddle for that too
http://jsfiddle.net/h75k1fzj/

AngularJS ng-click event isn't fired in Bootstrap popover

The AngularJS ng-click event isn't fired in a Boostrap popover.
<button id="delAnnot" type="button" class="btn btn-default"
data-toggle="popover" data-html="true" data-placement="bottom" data-content="
<button type='button' class='btn btn-danger' ng-click='vm.removeAnnotation(scenevm.sharedService.curAnnotation.ID)'>delete</button>">
<span class="glyphicon glyphicon-trash"></span>
</button>
I initialized my popover with a container so that the popover is within my angular controller:
$(".btn").popover({
placement: 'bottom',
trigger: 'click',
container: '#sceneCtrl'
})
For sure 'ng-lick' is not going to work try 'ng-click'. You can try as well using bootstrap directives http://angular-ui.github.io/bootstrap/ instead doing that in jQuery way.
Regards
Sylwester
Checkout this thread: AngularJS ng-click broken inside a popover
And here is the code that worked for me:
//Initialize & config popover controls
$('[data-toggle="popover"]').popover({ html : true })
.click(function(ev) {
//this is workaround needed in order to make ng-click work inside of popover
$compile($('.popover.in').contents())($scope);
});
And don't forget to include $compile and $scope as dependency in your module.

Resources