We're using fancybox 2 to launch a donation process in our app. Upon completion, the modal closes and opens up another "thank you" modal. We're seeing some odd behavior if you close that "thank you" modal and click on the "Donate" button again. The modal background overlay briefly appears and then disappears, and the modal doesn't show up. But, if you click it again, it works just fine.
I haven't been able to find any references to this happening to anyone else. We have a live demo where you can see the behavior here: https://demo.donordrive.com/index.cfm?fuseaction=donorDrive.participant&participantID=8558#donate
(The donation modal should open automatically, but if not, click "Support Me") Make a donation using a test credit card number (e.g., 4111111111111111) -- obviously, this won't actually charge you anything.
The relevant javascript code starts at line 162 if you view source. (I'll also include it at the end of this post).
I thought maybe it was because I wasn't explicitly closing any fancybox modals prior to opening the new ones, but that didn't change anything. So, I'm open to suggestions on what may be causing this. It's very weird.
Thanks!
Relevant JS:
<script type="text/javascript">
jQuery(function($) {
openExpressDonate = function() {
$.fancybox({
closeBtn: false,
closeEffect: 'none',
helpers : {
overlay : {
closeClick: false,
css: {'background-color': 'rgba(0, 0, 0, 0.60'},
locked: true
}
},
href: 'https://demo.donordrive.com/index.cfm?fuseaction=expressDonate.modalparticipant&ParticipantID=8558',
margin: 0,
maxWidth: 400,
height: 'auto',
openEffect: 'none',
padding: 1,
scrolling: 'no',
type: 'iframe'
});
}
$('.js-express-donate').on('click', function(e) {
e.preventDefault();
if (window.ga) {
ga('send', {
hitType: 'event',
eventCategory: 'Express Donate - Participant',
eventAction: 'Donation Started',
eventLabel: 'Event 1183'
});
}
openExpressDonate();
});
if (location.hash && location.hash == '#donate') {
$('.js-express-donate').click();
}
resizeExpressDonateModal = function() {
$.fancybox.update();
}
showExpressDonateThankYou = function(target, data) {
$.fancybox({
afterShow: function () {
fancyParent = $('.fancybox-wrap').parents(); // normally html and body
fancyParent.on('click.modalThanks', function () {
$.fancybox.close();
fancyParent.off('click.modalThanks');
});
$('.fancybox-wrap').on('click', function (event) {
// prevents closing when clicking inside the fancybox wrap
event.stopPropagation();
});
},
helpers : {
overlay : {
closeClick: false,
css: {'background-color': 'rgba(0, 0, 0, 0.60'},
locked: true
}
},
href: 'https://demo.donordrive.com/index.cfm?fuseaction=donorDrive.modal' + target + 'ExpressDonateThanks&donorID=' + data.values.donorID + '&CSRFToken=' + data.values.CSRFToken + '&n=' + data.values.isNewConstituent,
margin: 0,
maxWidth: 400,
minHeight: 300,
modal: 1,
openEffect: 'none',
padding: 1,
scrolling: 'no',
type: 'iframe'
});
}
});
</script>
We've solved this. A fresh set of eyes found that we had an explicit fancybox.close() call that was firing when clicking on the "thank you" modal's parent (a holdover from another feature where we have such a modal, but the user can't re-open it from that same page). We removed that and it appears to be fixed.
Related
So I've setup a fancybox with boxslider.
I have some problems with the boxslider when opening the fancybox again after closing it the first time.
website (please note that the onclick is only applied to the first block (top row, most left))
The fancybox is called by the code below:
<div class="img-spacer" onclick="$.fancybox({href : '#portfolio-1', width: 1040, margin: 0, padding: 0, closeBtn: false}); $('.bxslider').bxSlider({auto: true,controls: false,pager: false});">
This code works just fine when opening the fancybox for the first time but when I close the fancybox and open it again the boxslider is not working anymore like it is supposed to. It will skip some photo's and won't slide smoothly.
Any suggestions on how to fix this?
Like I mentioned in my comment, you need to move the fancybox init out of the inline click handler, in into your JS file.
$(document).ready(function() {
// Attach fancybox to every .image-spacer div
$("img-spacer").fancybox({
href : '#portfolio-1',
width: 1040,
margin: 0,
padding: 0,
closeBtn: false,
onUpdate: function() {
alert('update!');
},
onCancel: function() {
alert('cancel!');
},
onPlayStart: function() {
alert('play start!');
},
onPlayEnd: function() {
alert('play end!');
},
beforeClose: function() {
alert('before close!');
},
afterClose: function() {
alert('after close!');
},
beforeShow: function() {
alert('before show!');
},
afterShow: function() {
alert('after show!');
},
beforeLoad: function() {
alert('before load!');
},
afterLoad: function() {
alert('after load!');
}
});
// On clicking a .img-spacer div, attach a bxSlider
$(".portfolio").click(function(){
$('.bxslider').bxSlider({
auto: true,
controls: false,
pager: false
});
});
});
And for the HTML
<div class="img-spacer"></div>
Give this a shot and let me know how it went. If you place it on the live site I can take a look at it there.
I am dynamically appending a <div> to the body of my webpage. This <div> does not exist on my .html page.
Within this <div> I am creating a Jquery UI YES NO box. Quite simply, it will 'do something' and close the box when YES, and just close the box when NO.
I have a working piece of code to create this box. However, frequently it takes two clicks of the YES button to work, which is very confusing. You'll see I have used a variety of methods to close the box.
$(function () {
$('body').append('<div id="dialog-confirm"></div>').click(function (e) {
e.preventDefault();
$("#dialog-confirm").dialog("open");
});
$("#dialog-confirm").dialog({
autoOpen: true,
height: 200,
width: 200,
modal: true,
title: 'Choose item?',
buttons:
{
'YES': function () {
$(this).dialog("close");
//$("#dialog-confirm").dialog("close");
//$('body').remove('#dialog-confirm');
$('#dialog-confirm').remove();
},
'NO': function () {
$(this).dialog("close");
//$("#dialog-confirm").dialog("close");
//$('body').remove('#dialog-confirm');
$('#dialog-confirm').remove();
}
}
});
});
The problem is that there is a race condition between your adding the div and attaching the click handler. Sometimes it happens before, sometimes after. That's why you get inconsistent click behavior. Try the following:
$(function() {
$('body').append('<div id="dialog-confirm"></div>');
$("#dialog-confirm").dialog({
autoOpen : true,
height : 200,
width : 200,
modal : true,
title : 'Choose item?',
buttons : {
'YES' : function() {
$(this).dialog("close");
// $("#dialog-confirm").dialog("close");
// $('body').remove('#dialog-confirm');
$('#dialog-confirm').remove();
},
'NO' : function() {
$(this).dialog("close");
// $("#dialog-confirm").dialog("close");
// $('body').remove('#dialog-confirm');
$('#dialog-confirm').remove();
}
}
});
$('#dialog-confirm').click(function(e) {
e.preventDefault();
$("#dialog-confirm").dialog("open");
});
});
I have some sample code up at http://defyordie.com/testbed/
This is for my portfolio and I'm working on replacing my old plugin with fancybox. My issue is with the responsiveness of the work sample popups. Scroll down to my 'work' section and click on one of the top 3 boxes since those are finished.
I'm working on a big cinema display, so I've noticed that as i expand my window, the royalslider running the slideshow expands horizontally but doesnt expand vertically until i make the browser window almost entirely fill my screen. I had hoped that it would scale proportionally. I've either initalized the fancybox incorrectly, royalslider incorrectly, or I have some sort of CSS issue.
The code :
$(document).ready(function () {
$('.fancybox').fancybox({
beforeShow: function () {
$(window).on({
'resize.fancybox': function () {
$.fancybox.update();
}
});
},
afterClose: function () {
$(window).off('resize.fancybox');
},
padding: 0,
margin: [60, 15, 0, 15],
nextEffect: 'fade',
prevEffect: 'none',
helpers: {
overlay: {
locked: false
}
},
afterLoad: function () {
$.extend(this, {
type: 'html',
width: '95%',
height: '100%',
minWidth: '930px'
});
}
});
});
I am very dissapointed because I can't get rid of this issue! I have a product view and an "Add to Cart" button. If I click on the button, the form will be submitted (productAddToCartForm.submit(this)) and following function will be called:
var myAjaxify = function(button) {
button.prop('disabled', true);
if (this.validator.validate()) {
$(this.form).request({
onComplete: function(response) {
var responseData = JSON.parse(response.responseText);
if (responseData.success === 'true') {
Dialog.confirm(
responseData.message,
{
className: 'openit',
width: 385,
height: 220,
destroyOnClose: true,
id: 'ajax-add-result',
closable: true,
zIndex: 100,
title: 'Added to Your Cart',
okLabel: 'Continue Shopping',
cancelLabel: 'Proceed to Cart',
onCancel: function() {
window.location = '/checkout/cart';
},
buttonClass: 'action-btn'
}
);
...
But it takes a few seconds till the popup shows up. And if I click on the "Add to Cart" button multiple times in the meanwhile, the popup appears more than once. If I don't close the popup fast enough I also get the error "ajax-add-result is already registered in the DOM". I tried to disable the button ($(this).prop('disabled', true);), but all my solutions break the script :(
Can anyone help me?
Every help is much appreciated.
Best, Hannes.
Unset the button :)
$( "#yourbutton").unbind( "click" );
After everything is loaded you can bind the event back.
I've been working on a custom alert box that has the same style as the rest of the website via jquery-ui. It was working well except that it wouldn't open more than once. As I was trying to fix that, I broke the whole thing some how, and now I get this error:
Node cannot be inserted at the specified point in the hierarchy" code: "3
Below is the code. doAlert() is a simple replacement for alert(). Later it will have more features. show_support() creates dialog box in a similar way to doAlert(), except that it works perfectly.
function doAlert(msg, title) {
var alert_box = $('body').append('<div id="alert_box" class="centered" style="padding:.5em;vertical-align:middle;display:none;"><p>' + msg + '</p></div>');
title = typeof(title) != 'undefined' ? title : 'Message';
alert_box.dialog({
modal: true,
title: title,
width: 400,
height: 150,
resizable: false,
overlay: {
opacity: 0.5,
background: 'black'
},
buttons: {
'Ok': function() {
$(this).dialog('close');
}
},
close: function() {
$(this).dialog('destroy').remove();
}
});
}
function show_support() {
var dialog = $('body').append('<div id="dialog_support" style="display:none;"></div>');
$('#dialog_support').load('/supporttracker', {action:'get_dialog'})
.dialog({
modal: true,
title: "Support",
width: 620,
height: 400,
buttons: {
"Send": function() {
if (!$('#issue_message').val()) {
doAlert('Your message cannot be blank. Please enter your message.');
return;
}
$.ajax({
type: 'POST',
url: '/supporttracker',
data: 'action=add_simple&'+$('#issue').serialize(),
success: function(msg){
doAlert('Thank you. We will get to your question/issue as soon as we can. Usualy within 24 hours.');
$('#dialog_support').dialog('close');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
doAlert('An error accured: '+textStatus);
}
});
},
"Cancel": function() {$(this).dialog('close');}
},
close: function() {
$(this).remove();
}
});
}
Anyone have any ideas of how I messed up doAlert?
Look at the close method. doAlert seems to be doing a dialog('destroy'), then calling remove on it. show_support is simply removing the dialog from the DOM. I don't know what the dialog method returns so it may be that the DOM element isn't actually getting removed and thus reinserting it fails -- since you can't have to elements with the same id.
If it were me I'd create the dialog on page load (hidden), then simply update a message when it needs to be shown, and use open/close to reuse the element rather than recreating it.
<div id="alert_box" class="alert-dialog" style="display: none;">
<p id="alert_message">An error occurred.</p>
</div>
<script type="text/javascript">
$(function() {
$('#alert_box').dialog({
modal: true,
width: 400,
height: 150,
resizable: false,
overlay: {
opacity: 0.5,
background: 'black'
},
buttons: {
'Ok': function() {
$(this).dialog('close');
}
}
});
});
function doAlert( msg, title )
{
$('#alert_message').html(msg);
$('#alert_box').attr( 'title', title )
.dialog('open');
}
</script>