this not work for me (i use v2.0.0-beta.4)
var popover = document.body.querySelector('.popover');
angular.element(popover).scope().$destroy();
here my full code:
angular.element(document.body).bind('click', function(e){
if (e.target.classList.contains('popover-link')) {
return;
}
var popover = document.body.querySelector('.popover');
if (!popover) {
return;
}
popover = angular.element(popover);
if (popover.find(e.target).length) {
return;
}
popover.scope().$destroy();
});
what i need todo? how i must close the popover?
This is a duplicate of Close AngularStrap popover
Here is my answer over there :
There is an issue in the angular-strap github project which asks
exactly the feature you want.
Nevertheless, at the moment I'm writing this answer, it's still open.
Related
Sometimes when I want to quickly select the entire text of an input (within a modal), I begin selecting from the end of the text and move the mouse to the left until the entire text is selected and then I release.
Sometimes this release will occur outside the modal because the mouse movement is fast.
Picture describing the movement:
The problem is that the modal is closed when I release outside.
Question: how can I prevent the modal from closing when releasing outside?
I'm okay with the modal being closed with a click outside. But not okay with the release event.
I'm using:
angularjs 1.5.8
angular-bootstrap 2.5.0 (aka bootstrap-ui)
bootstrap 3.3.7 (only css!!! not js, because js is provided by the above)
Update:
I've created a plunkr and a GIF:
https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info
<div class="modal-body">
<div class="form-group">
<label for="">Foo</label>
<input type="text" class="form-control input-sm" ng-model="foo">
<p>Do this: select the text from right to left and release the mouse outside the modal.</p>
</div>
</div>
GIF:
Update 2
I have new information! This started happening after the last Goole Chrome update! I tried with another computer that had the previous version of Chrome and the modal doesn't close.
//prevent modal close when click starts in modal and ends on backdrop
$(document).on('mousedown', '.modal', function(e){
window.clickStartedInModal = $(e.target).is('.modal-dialog *');
});
$(document).on('mouseup', '.modal', function(e){
if(!$(e.target).is('.modal-dialog *') && window.clickStartedInModal) {
window.preventModalClose = true;
}
});
$("#modal").on("hide.bs.modal", function (e) {
if(window.preventModalClose){
window.preventModalClose = false;
return false;
}
});
The original repository has been archived and no contributions are accepted.
I forked a version and added my fixes for those who are interested:
https://github.com/peteriman/bootstrap
The comparison below:
https://github.com/angular-ui/bootstrap/compare/master...peteriman:modal-patch
= // moved from template to fix issue #2280
- element.on('click', scope.close);
+ var ignoreClick = false;
+ element.on('mousedown', function(evt1) {
+ element.one('mouseup', function(evt2) {
+ if (evt1.target !== evt2.target)
+ ignoreClick = true;
+ });
+ });
+ element.on('click', function(){
+ if (ignoreClick) ignoreClick = false;
+ else scope.close.apply(this, arguments);
+ });
As mousedown and mouseup events trigger before click event, the code checks if mousedown and mouseup are on the same element. If on different elements, it sets ignoreClick=true for the click event to not trigger.
Maintains backward compatibility for click event for existing codes that calls element.click() programmatically.
Original problem:
https://plnkr.co/edit/mxDLAdnrQ4p0KKyw?p=info&preview
Solution by me: (plkr, modal.js, line 103-114)
https://plnkr.co/edit/V42G9NcTUnH9n9M4?p=info&preview
I updated only the code referring to "Modal.js" in bootstrap.js and bootstrap.min.js
Corrected version:
* Bootstrap: modal.js v3.4.1
* https://getbootstrap.com/docs/3.4/javascript/#modals
bootstrap.js print
Yes, this started happening again after the last Goole Chrome update Version 74.0.3729.169, is this a bug with Chrome we can't fix and that we'll just have to wait for a Chrome update for it to be resolved?
or a bootstrap maintainer will update the code for fixing this?
Issue url: https://github.com/twbs/bootstrap/issues/28844
This problem is not recent is already mentioned on github
https://github.com/angular-ui/bootstrap/issues/5810
the following solution works very well with small improvements if necessary.
$rootScope.$watch(() => document.querySelectorAll('.modal').length, val => {
//everytime the number of modals changes
for (let modal of document.querySelectorAll('.modal')) {
if ($uibModalStack.getTop().value.backdrop !== 'static') { // Testing if the
modal is supposed to be static before attaching the event
modal.addEventListener('mousedown', e => {
if (e.which === 1) {
$uibModalStack.getTop().key.dismiss()
}
})
modal.querySelector('.modal-content').addEventListener('mousedown', e => {
e.stopPropagation()
})
}
}
if (val > 0) {
$uibModalStack.getTop().value.backdrop = 'static'
}
})
Another solution on the same principle that keeps the draggrable footer and header of the modal
$rootScope.$watch(function () {
return $document.find('.modal').length;
}, function (val) {
if(openedWindows.top() ) {
var modal = $document.find('.modal');
angular.forEach(modal, function(value) {
if ($modalStack.getTop().value.backdrop !== 'static') {
value.addEventListener('mousedown', function (e) {
if (value === e.target && e.which === 1 && openedWindows.top()) {
$modalStack.getTop().key.dismiss();
}
});
}
});
if (val>0) {
$modalStack.getTop().value.backdrop = 'static';
}
}
});
I'm using Bootstrap v3.0.0 and ran into the same problem. In the end, I had to change a click event to a mousedown event.
In my bootstrap.js file, under the modal.js section, I changed this.$element.on('click.dismiss.modal', $.proxy(function (e) to this.$element.on('mousedown.dismiss.modal', $.proxy(function (e). and everything appears to be working. You may also have to change this in the bootstrap.min.js file.
Note, this will immediately close the modal on mouse down of backdrop so if for some reason you want a user to be able to click down on the backdrop, then drag the mouse and release on the modal, this will not work.
Have you tried using backdrop: 'static'. I think that should do the trick. It is present in the documentation here
Add css padding around modal window and resize it larger. Click outside still works but releasing mouse while dragging over the edge won't close it.
I had a similar situation with range slider. leaving click during slide outside the modal closes it. so I removed data-toggle="modal" and data-target="#mymodal" and added a click event with extra parameters
jQuery('button#modal_toggler').click(function(){
jQuery('#myModal').modal({
backdrop: 'static',
keyboard: false
})
})
backdrop to disable modal close on clicking outside
keyboard this is for my scenario, to disable keyboard entry for closing modal
I have figured out different way to solve the problem, idk if it will cause a problem later but anyway it works, so basically, I put modal-dialog to another <div> object (I call it modal-helper) and then put it to modal. The modal-helper element width and height are inherited (100%) as default but there is small space on top so you can use some margin and padding to close it.
<div class="modal fade" id="login-modal" tabindex="-1" aria-labelledby="loginModalLabel" style="display: none;" aria-hidden="true">
<div id="modal-helper" style="pointer-events: auto;">
<div class="modal-dialog">
...
</div>
</div>
</div>
Then I have used some JS to hide modal when modal-helper (as backdrop) is clicked (by the 'clicked' I mean when pointerup event triggered after pointerdown event on modal-helper).
The code below sets the value of isPointerDownToModalHelper true when pointerdown event triggered on modal-helper, then when the pointerup event triggered on any object it hides the modal and sets the value of isPointerDownToModalHelper back to false:
var login_modal_helper = document.getElementById('modal-helper')
var isPointerDownToModalHelper = false;
addEventListener('pointerdown', (event) => {
var objectID = event['path']['0']['id'];
if (objectID === login_modal_helper.id) { // if pointer was over modal-helper
isPointerDownToModalHelper = true;
}
});
addEventListener('pointerup', (event) => {
if (isPointerDownToModalHelper === true) {
isPointerDownToModalHelper = false;
$('#login-modal').modal('hide'); // hide the modal
}
});
It seems to work fine for now, I hope it can help someone :).
Is there any direct way to get dialog object of all components which are dragged on page.
For ex: when we load page and if there is any component like text, image are on page, I can get dialog. Please suggest?
Yes, it is possible. Attach a listener which listens to the editablesready event fired by WCM. Get all the editables on the page using the #getEditables() method of CQ.WCM and then get the dialog of each editable if it is present.
Sample code below.
CQ.WCM.on('editablesready', function() {
var editables = CQ.WCM.getEditables();
for(var path in editables) {
var editable = editables[path];
try {
console.log(editable.getEditDialog());
//Do stuff
} catch(e) { }
}
});
We are working on an application in which we are using Angularjs + webapi and making a Single Page App.
We have quite few Modal Pop-ups from Bootstrap used in the app, but we are facing an issue
-> on click of the modal button, the backdrop initializes and then is stuck with no modal. and we have to force refresh the browser. We are pulling the templates from other files into the modals.
initially for closing the modal, I've used $(".modal.in").hide(); and the close is fine with out the "Stuck" on grey screen.
then later for init the modal itself it started to appear then I removed the fade class and removed the animations from the css but didn't help much.
Really need a promising fix.
$.support.transition = (function () {
var thisBody = document.body || document.documentElement
, thisStyle = thisBody.style
, support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.OTransition !== undefined
return support
})()
// set CSS transition event type
if ( $.support.transition ) {
transitionEnd = "TransitionEnd"
if ( $.browser.webkit ) {
transitionEnd = "webkitTransitionEnd"
} else if ( $.browser.mozilla || $.browser.msie ) {
transitionEnd = "transitionend"
} else if ( $.browser.opera ) {
transitionEnd = "oTransitionEnd"
}
}
The above code snippet was advised in some forums.
But in the Bootstrap.js Bootstrap v3.2.0 (http://getbootstrap.com)
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
return false // explicit for ie8 ( ._.)
}
You can create a directive that includes the templates you want and launch and then control the boostrap modals from with in that directive. the external communication can be achieved in many ways my favorite using custom events watched by the directive to know when to hide or show the modals that way you can use all the bootstrap code you already have from INSIDE your directive. this can also be done through a service, not my favorite solution, but is also accepted. for more ideas look at the angular-ui project and the modal service
http://angular-ui.github.io/bootstrap/
I am trying to hide extjs date-field on clicking anywhere on DOM except date-field. while clicking anywhere in dom bodyClick function get called.On basis of page co-ordinates element object get retrieved and then this element object get compared with date-field object.This works fine but problem comes whenever i am clicking on date-picker again "date-field" get hide.
sample code -
bodyClick: function(e){
var me = this, elem, t;
var flag =true;
elem = me.getEl();
for(t = Ext.dom.Element.fromPoint(e.getX(), e.getY()); t && t != null;){
if (Ext.fly(elem ).contains(t)){
flag =false;
}
}
if(flag ){
me.hide();
}
}
Any Suggestions for hiding datefield while clicking anywhere in DOM (extJs).
You can try this in afterRender of the panel or container in which your component is in.
this.mon(Ext.getBody().getEl(), 'click', this.yourFunction, this);
yourFunction:function(e){
var comp = Ext.ComponentQuery.query('datepicker')[0];//Get your datepicker component
if (Ext.fly(e.getTarget()) != comp) { //get the target using Ext.fly
comp.hide(); //Hide the component if the target is not the datepicker
}
}
Hope this helps you.
I am working with Twitter Bootstrap and ran into something I could not fix when testing on iPad and iPhone. On mobile (at least those devices) you need to click to engage the tip or popover (as expected). The issue is that you can never close it once you do. I added a listener to close it if you click it again, but I find it hard to believe that the default behavior would not be to click to remove it. Is this a bug in Bootstrap popover and tooltip?? My code is below - it seems to work, but ONLY if you click the same item that created the tip or popover - not anywhere on the page (could not get that to work).
Code to fire:
$(function () {
//Remove the title bar (adjust the template)
$(".Example").popover({
offset: 10,
animate: false,
html: true,
placement: 'top',
template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
//<h3 class="popover-title"></h3>
//Need to have this click check since the tooltip will not close on mobile
}).click(function(e) {
jQuery(document).one("click", function() {
$('.Example').popover('hide')
});
});
});
HTML:
<a href="javascript:void(0);" class="Example" rel="popover" data-content="This is the Data Content" data-original-title="This is the title (hidden in this example)">
Thanks in advance!
Dennis
I tried dozens of solutions posted to stackoverflow and other various corners of the web, and the following is the only one that worked for me!
Explanation
As noted here, you can a CSS-directive the element in order to make it touch-device-clickable. I can't tell you why that works or what's going on there, but that seems to be the case. So, I want to make the entire document aka body clickable on mobile devices, which will allow me to touch anywhere to dismiss the popover.
Popover JS
$(function () {
$('[data-toggle="popover"]').popover({ trigger: "hover"}})
});
Directions
1. Install Modernizr
I'm using rails, so I used the gem.
gem 'modernizr-rails'
2. Create a touch class with a css-directive
Add the following to your CSS:
.touch {
cursor: pointer
}
3. On touch devices only, add the touch class to the body
If you want other elements to be clickable, instead of the entire body, add the touch class to them.
if (Modernizr.touch) {
$( "body" ).addClass( "touch" );
}
That's it! Now, you can use your popover normally on desktop (even with hover-trigger) and it will be touch-dismissible on mobile.
I had the same problem with my IPad. But in browser it works fine. Solution for me was adding listeners for all possible element that i can hide tooltip:
$('*').bind('touchend', function(e){
if ($(e.target).attr('rel') !== 'tooltip' && ($('div.tooltip.in').length > 0)){
$('[rel=tooltip]').mouseleave();
e.stopPropagation();
} else {
$(e.target).mouseenter();
}
});
Yes, it's small overhead to send event for all tooltips, but you can't define which element tooltip is showing.
Main concept is that make popover manually on mobile device
$(document).ready(function() {
if ('ontouchstart' in window) {
$('[data-toggle="popover"]').popover({
'trigger': 'manual'
});
}
});
Refer following code snippet to get it works:
$('[data-toggle="popover"]').popover();
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
This is the easiest way of detecting clicks on the body and close all the tooltips on the page.
You can check the live example here
Solution on this jsfiddle,
test on iOS (iPad and iPhone), Android and Windows.
$(document).ready(function(){
var toolOptions;
var toolOptions2;
var isOS = /iPad|iPhone|iPod/.test(navigator.platform);
var isAndroid = /(android)/i.test(navigator.userAgent);
///////////////////////////////////////// if OS
if (isOS){
toolOptions = {
animation: false,
placement:"bottom",
container:"body"
};
$('.customtooltip').tooltip(toolOptions);
$('.customtooltip').css( 'cursor', 'pointer' );
$('body').on("touchstart", function(e){
$(".customtooltip").each(function () {
// hide any open tooltips when the anywhere else in the body is clicked
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.tooltip').has(e.target).length === 0) {
$(this).tooltip('hide');
}////end if
});
});
///////////////////////////////////////// if Android
} else if(isAndroid){
toolOptions = {
animation: false,
placement:"bottom",
container:"body"
};
toolOptions2 = {
animation: false,
placement:"left",
container:"body"
};
$('.c_tool1').tooltip(toolOptions);
$('.c_tool2').tooltip(toolOptions);
$('.c_tool3').tooltip(toolOptions2);
///////////////////////////////////////// if another system
} else {
toolOptions = {
animation: true,
placement:"bottom",
container:"body"
};
$('.customtooltip').tooltip(toolOptions);
}//end if system
document.getElementById("demo").innerHTML = "Sys: "+navigator.platform+" - isOS: "+isOS+" - isAndroid: "+isAndroid;
});
<h6>
first tooltip
Second tooltip
third tooltip
</h6>
<p id="demo"></p>
Bootstap-tooltip v3.3.7
Actual: tooltip on hover doesn't work with touch devices in our project
Solution: Subscribe to tooltip's show event and call mouseenter
$body = $('body');
$body.tooltip({selector: '.js-tooltip'});
// fix for touch device.
if (Modernizr.touch) { // to detect you can use https://modernizr.com
var hideTooltip = function(e) {
tooltipClicked = !!$(e.target).closest('.tooltip').length;
if (tooltipClicked) { return; }
$('.js-tooltip').tooltip('hide');
}
var emulateClickOnTooltip = function(e) {
tooltipsVisible = !!$('.tooltip.in').length;
if (tooltipsVisible) { return; }
$(e.target).mouseenter();
}
var onTooltipShow = function(e) {
tooltipClicked = !!$(e.target).closest('.tooltip').length;
if (tooltipClicked) { return; }
$body.on('touchend', hideTooltip);
}
var onTooltipHide = function() {
$body.off('touchend', hideTooltip);
}
$body
.on('touchend', '.js-tooltip', emulateClickOnTooltip)
.on('show.bs.tooltip', onTooltipShow)
.on('hide.bs.tooltip', onTooltipHide);
}