I have created a directive using bootstrap custom popover. That works taking an input from a user for a group name and it has two buttons for apply that value to model and show that value on tooltip and a button to close the popover. I am using popover java script events , Problem is that single popover works perfectly but when I open another one this popover not closing itself. Need help in closing other popovers while one is open. Here is the plnk showing the directive.
Here is the code
var app = angular.module('myApp',[]);
app.directive('customEditPopover', function () {
return {
restrict: 'A',
template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>',
scope: {
'myModel': '=',
},
link: function (scope, el, attrs) {
scope.label = attrs.popoverLabel;
var btnsave = '#' + attrs.popoverSave;
var btncancel = '#' + attrs.popoverCancel;
var index = attrs.index;
$(el).tooltip({
title: '' + (scope.myModel == undefined) ? "" : scope.myModel,
container: 'body',
placement: 'top'
});
$(el).popover({
trigger: 'click',
html: true,
content: attrs.popoverHtml,
placement: attrs.popoverPlacement,
container: 'body'
})
.on('inserted.bs.popover', function (e) {
bindevents();
$('#popovertext' + index).val(scope.myModel);
}).on('hidden.bs.popover', function () {
Unbindevents();
});
function bindevents() {
$(btnsave).bind('click', function () {
var text = $('#popovertext' + index).val();
scope.myModel = text;
$(el).tooltip('hide')
.attr('data-original-title', text)
.tooltip('fixTitle')
toggle();
});
$(btncancel).bind('click', function () {
toggle();
});
}
function Unbindevents() {
$(btnsave).unbind('click');
$(btncancel).unbind('click');
}
function toggle() {
$(el).popover('hide');
$(el).click();
}
}
};
});
app.controller('MyController',['$scope',function($scope){
$scope.list=[
{
name:'ABC'
},
{
name:'DEF'
},
{
name:'GHI'
},
{
name:'KLM'
}
];
}]);
Need help closing other popover while opening next one.
You can close the other popovers when show.bs.popover
is triggered as shown below : Updated Plunkr
$(el).popover({
trigger: 'click',
html: true,
content: attrs.popoverHtml,
placement: attrs.popoverPlacement,
container: 'body'
})
.on('show.bs.popover', function () {
var siblings = $(el).parent().parent().siblings();
siblings.each(function (each){
$(siblings[each]).find('span').popover('hide');
});
});
IMO, the most modular way would be to use a service to track all opened PopUps.
This gives multiple benefits.
You can extend the service to track different types of popups, allowing you to close all or open all or do whatever you need
It removes the logic from the controls and directives on keeping track of popups. Thus they can focus on 1 specific thing. You can also run multiple controllers and popups on a page allowing each controller/popup to be a discrete unit of work and not needing to worry about other controllers/popups stomping on their items.
The cons of doing this
ng-bootstrap
directives.JQUERY
events seems to become unresponsive when you click 8+ times. I do not have an answer for why that is, but the overall idea of using a service to keep track is still a valid one.You shoudl be able to cut and paste this code into the plnkr or your dev box and it will work.
// Code goes here
var app = angular.module('myApp',[]);
app.factory('popUpService', function() {
var activePopups = [];
// factory function body that constructs shinyNewServiceInstance
return {
AddPopup : function(el)
{
activePopups.push(el);
},
CloseAllPopups : function(closeFunction){
for (var i = 0; i < activePopups.length; i++)
{
closeFunction(activePopups[i])
}
}
}
});
app.directive('customEditPopover',['popUpService', function (popUpService) {
return {
restrict: 'A',
template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>',
scope: {
'myModel': '=',
},
link: function (scope, el, attrs) {
scope.label = attrs.popoverLabel;
var btnsave = '#' + attrs.popoverSave;
var btncancel = '#' + attrs.popoverCancel;
var index = attrs.index;
$(el).tooltip({
title: '' + (scope.myModel == undefined) ? "" : scope.myModel,
container: 'body',
placement: 'top'
});
$(el).popover({
trigger: 'click',
html: true,
content: attrs.popoverHtml,
placement: attrs.popoverPlacement,
container: 'body'
})
.on('inserted.bs.popover', function (e) {
bindevents();
$('#popovertext' + index).val(scope.myModel);
}).on('hidden.bs.popover', function () {
Unbindevents();
});
function bindevents() {
CloseAll();
popUpService.AddPopup($(el));
$(btnsave).bind('click', function () {
var text = $('#popovertext' + index).val();
scope.myModel = text;
$(el).tooltip('hide')
.attr('data-original-title', text)
.tooltip('fixTitle')
closeCurrent();
});
$(btncancel).bind('click', function () {
closeCurrent();
});
}
function Unbindevents() {
$(btnsave).unbind('click');
$(btncancel).unbind('click');
}
function closeCurrent(){
$(el).popover('hide');
// $(el).click();
}
function CloseAll() {
popUpService.CloseAllPopups(function(popup){
popup.popover('hide');
// popup.click();
});
}
}
}
}]);
app.controller('MyController',['$scope',function($scope){
$scope.list=[
{
name:'ABC'
},
{
name:'DEF'
},
{
name:'GHI'
},
{
name:'KLM'
}
];
}]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With