AngularJS - Bootstrap popover with different tooltip on hover and click - angularjs

Is there an easy way to have one tooltip for hovering and then another one for when you click it?
On hover:
<span data-toggle="popover" data-trigger="hover" data-content="Click to show details">{{ someData }}</span>
On click:
<span data-toggle="popover" title="More details" data-trigger="hover" data-html="true" data-content="{{ someDetailedData }}">{{ someData }}</span>
Just using this directive to wrap the boostrap popover:
(function() {
"use strict";
angular
.module("app.utils")
.directive("toggle", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (attrs.toggle == "tooltip") {
$(element).tooltip();
}
if (attrs.toggle == "popover") {
$(element).popover();
}
}
};
});
})();

You can use on ng-mousedown="mouseov = false" and ng-mouseover="mouseov = true" attribute
Than in title you can do something like
<span>< data-toggle="popover" title="{{mouseov
? 'title on mouseover true'
: 'title on mousedown leave'}}"
data-trigger="hover" data-content="Click to show details">{{ someData }}
</span>

Related

Angular moment picker in fancybox

When I click on datapicker (angular moment picker) after load it in inline fancybox, it output empty window.
But if I click on datapicker input directly - all works fine.
I use fancybox as directive:
.directive('fancybox', function ($compile, $http) {
return {
scope: true,
restrict: 'EA',
link: function(scope, element, attrs) {
scope.openFancybox = function (href) {
scope.curHosterUID = angular.fromJson(attrs.hoster);
//console.log(scope.chEvent);
//scope.curHosterUID = href.replace('#viewEvent', '');
console.log(scope.curHosterUID);
var template = angular.element(href);
var compiledTemplate = $compile(template);
compiledTemplate(scope);
$.fancybox.open();
$.fancybox.open({ href: href, type: 'inline' });
};
}
};
})
<div class="input-group" moment-picker="ctrl.timepicker" format="HH:mm:ss">
<span class="input-group-addon">
<i class="fa fa-clock-o"></i>
</span>
<input id="event_start" class="form-control"
placeholder="Select a time"
ng-model="ctrl.timepicker"
ng-model-options="{ updateOn: 'blur' }">
</div>
How I can force datapicker in fancybox?

Popover close when click on its body,How to disable?

Popover content always close when click to focus cursor on Popover body
here my popover directive
angular.module('collect').directive('popover', function($timeout){
return {
restrict : 'E',
replace : true,
link: function(scope, element, attrs) {
var popover = null;
// define popover for this element
$timeout(function() {
// TODO: maybe can continue using $(element) or just element instead of saving popover var
popover = $(element).popover({
html: true,
placement: scope.placement || "top",
// grab popover content from the next element
content: $(element).siblings(".pop-content").contents(),
});
popover.on('show.bs.popover', function($event) {
//hide any visible popover
$('.popover').not($(element)).popover('hide');
});
},0 , false);
var unbinder = scope.$on(
"$destroy",
function handleDestroyEvent() {
if (popover) {
popover.off('show.bs.popover');
popover = null;
}
$(element).off('.popover.data-api'); // TODO: I think this is only for jquery, not bootstrap
$(element).popover('destroy');
element.remove();
unbinder();
}
);
$("body").on("click touchstart", '.popover', function() {
$(this).popover("show");
$('.popover').not(this).popover("hide"); // hide other popovers
return false;
});
}
};
});
and this one is how I use popover
<span>
<popover class="tbl-act-btn action-column action-column-ic popover-btn" title="Comments">
<span title="{{columnName}}">
<i class="fa" ng-class="{'fa-comments-o' : !isComment(commentContentTemp), 'fa-comments' : isComment(commentContentTemp)}"></i>
</span>
</popover>
<div ng-hide="true" class="pop-content">
<div class="form-group">
<textarea class="popover-textarea form-control" name="comment" ng-model="commentContentTemp"></textarea>
<div class="popover-footer">
<button type="button"
class="glyphicon glyphicon-ok btn btn-primary popover-submit" aria-hidden="true" ng-click="updateComment($event)"></button>
<button type="button" class="glyphicon glyphicon-remove btn btn-default popover-cancel" aria-hidden="true" ng-click="cancelUpdateComment($event)"></button>
</div>
</div>
</div>
It always close Popover when I click on textArea to edit text. I want it close whenever click on update, cancel, or outside Popover.

Can't create a popover with custom template

First I tried using angular-ui
<span popover-template="removePopover.html" popover-title="Remove?" class="glyphicon glyphicon-remove cursor-select"></span>
here the template is not included and no errors are provided in console. As I undestood from previous questions this capability is still in development (using v0.13.0).
Then I tried using bootstrap's popover
<span delete-popover row-index={{$index}} data-placement="left" class="glyphicon glyphicon-remove cursor-select"></span>
This is included to popover
<div id="removePopover" style="display: none">
<button id="remove" type="button" ng-click="removeElement()" class="btn btn-danger">Remove</button>
<button type="button" ng-click="cancelElement()" class="btn btn-warning">Cancel</button>
</div>
This is the managing directive
app.directive('deletePopover', function(){
return{
link: function(scope, element, attrs) {
$(element).popover({
html : true,
container : element,
content: function() {
return $('#removePopover').html();
}
});
scope.removeElement = function(){
console.log("remove"); //does not get here
}
scope.cancelElement = function(){
console.log("cancel"); //does not get here
}
}
};
});
In case of bootstrap's popover the scope is messed up. cancelElement() call does not arrive in directive neither the parent controller.
If anyone could help me get atleast on of these working it would be great.

ng-disabled active/inactive

http://jsfiddle.net/zjqz6wjL/
I have 3 buttons, when you click on a button they all become disabled.
It would be nice if only the button I click becomes disabled and the other two remain active. When clicking on another button that one becomes disabled and in turn reactivating the previously disabled button back to active state.
<button ng-click="disableClick()" ng-disabled="isDisabled" ng-model="isDisabled">Disable ng-click 1</button>
You can do this :
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.btns = [
{name:'1',isDisabled:false},
{name:'2',isDisabled:false},
{name:'3',isDisabled:false}
];
$scope.disableClick = function(btn) {
alert("Clicked!");
angular.forEach($scope.btns,function(_btn){
_btn.isDisabled = false;
});
btn.isDisabled = true;
return false;
}
}]);
With this template :
<body ng-app="ngToggle">
<div ng-controller="AppCtrl">
<button ng-repeat="btn in btns" ng-click="disableClick(btn)" ng-disabled="btn.isDisabled">Disable ng-click {{btn.name}}</button>
</div>
</body>
See here : https://jsfiddle.net/dy7g0snx/
You don't need the ng-model directive here (it was unsed though).
Use your btns as objects
Get it as array
Use ng-repeat directive to loop on it
Pass the btn object in disableClick method
Disable all buttons in the method
Then enable the passed button
EDIT
Inspired by the comment then the answer of Joaozito Polo, here an alternative if you don' want to use objects. It is not recommended in most case but with a use case with only 2 or 3 buttons, non-paramtric, it is acceptable.
In a such situation, you didn't need the $scope.disableClick() thus, no more need the controller too.
Just declare your angular module js-side :
angular.module('ngToggle', []);
And use ng-click then ng-disable directives in content corelations :
<body ng-app="ngToggle">
<button ng-click="disabled = 1" ng-disabled="disabled == 1">Disable ng-click 1</button>
<button ng-click="disabled = 2" ng-disabled="disabled == 2">Disable ng-click 2</button>
<button ng-click="disabled = 3" ng-disabled="disabled == 3">Disable ng-click 3</button>
</body>
Note that I removed the ng-controller directive too, because it will not defined js side now.
See the demo here
You can choose to extract to independent directives. There are two directives: buttonGroup and myButton. In buttonGroup, the property disabledBtnName stores the name of the only disabled button. In ng-repeat, only the button with name disabledBtnName will be disabled. It is easy to be reused, say, in many different pages.
angular.module('ngToggle', [])
.directive('buttonGroup', [function () {
return {
restrict: 'A',
transclude: true,
scope: {},
template:
'<div>' +
'<button ng-repeat="btn in buttons" ng-disabled="btn.name == disabledBtnName" ng-click="disableMe(btn)" ng-bind="btn.text"></button>' +
'<div ng-transclude></div>' +
'</div>',
controller: ['$scope', function ($scope) {
$scope.buttons = [];
this.addButton = function (btn) {
$scope.buttons.push(btn);
};
$scope.disableMe = function (btn) {
$scope.disabledBtnName = btn.name;
};
}]
};
}])
.directive('myButton', [function () {
return {
restrict: 'A',
scope: {
name: '#',
text: '#'
},
require: '^buttonGroup',
link: function (scope, iElement, attrs, btnGroupCtrl) {
btnGroupCtrl.addButton(scope);
}
};
}]);
Simply use it like:
<body ng-app="ngToggle">
<div button-group>
<div my-button name="one" text="Button One"></div>
<div my-button name="twp" text="Button Two"></div>
<div my-button name="three" text="Button Three"></div>
</div>
</body>
Check the online working demo: http://jsfiddle.net/zjqz6wjL/4/
You can store the last clicked button information, and check on ngDisabled:
<button ng-click="click(1)" ng-disabled="lastClicked == 1">Disable ng-click 1</button>
and your action:
$scope.click = function(btn) {
alert("Clicked!");
$scope.lastClicked = btn;
return false;
}
You can see on jsfiddle
Here is what I have managed to do without use of controllers :
<body ng-app="ngToggle">
<div ng-controller="AppCtrl" ng-init = "disabled=0">
<button ng-click = "disabled = disabled == 1 ? 0 : 1" ng-disabled="disabled == 1" ng-model="isDisabled">Disable ng-click 1</button>
<button ng-click="disabled = disabled=== 2 ? 0 : 2" ng-disabled="disabled == 2" ng-model="isDisabled">Disable ng-click 2</button>
<button ng-click="disabled = disabled=== 3 ? 0 : 3" ng-disabled="disabled == 3" ng-model="isDisabled">Disable ng-click 3</button>
</div>
here is the fiddle : http://jsfiddle.net/zjqz6wjL/8/

Ng-click not getting fired on triggering click from another module in angular

I have a form carousel created and injected in my module.
In the form carousel there is a button used to navigate to next field.
From my app i want to call this button when tab out of my field.
Here is my code.
var testFile = angular.module('testModule',['new-form-carousel','ngAnimate']);
testFile.controller('mainController',['$scope',function(s){
s.data = {'name':'','password':''}
s.pintThem = function(){
console.log(s.data);
}
s.callNext = function(){
setTimeout(function() {
console.log($('a[ng-click="next()"]'));
$('a[ng-click="next()"]').trigger('click');
},10);
}
}]);
here is my controller.
Here is the field i want to call the next method from
<div>
Name: <input type="text" ng-model="data.name" ng-blur="callNext()">
</div>
new-form-carousel starts here
Here is the form carousel directive:
formCarousel.directive('carousel', [function() {
return {
restrict: 'EA',
transclude: true,
replace: true,
controller: 'CarouselController',
require: 'carousel',
templateUrl: '../app/html/carousel.html',
scope: {
interval: '=',
noTransition: '=',
noPause: '='
},
link:function(scope,element,attrs,controller){
}
};
}]);
Here the html of the above directive:
<a class="left carousel-control" ng-click="prev()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-left"></span></a>
<a class="right carousel-control" ng-click="next()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-right"></span></a>
Onblur from my html i want to call the next() method of the carousel.
I have fixed the issue that i was facing.
Instead of using jquery selector and trigger i used angular selector and triggerhandler and it is working fine.
Here is the fix:
setTimeout(function() {
angular.element( document.querySelector('a[ng-click="next()"]')).triggerHandler('click');
},10);

Resources