Two clicks needed to fire modal

Hi all,

I’m using a plugin which gives me the option to use a modal type popup. Works ok. The problem is, It takes two clicks before it fires in my setup.

I also need to keep the document object for event delegation as I’m using a template engine, this is required.

$(document).on('click', '.popup', function(e){
  $(this).magnificPopup({
    midClick: !0,
    removalDelay: 200,
    mainClass: "fade",
    prependTo: $("body"),
    type: "iframe"
  });
  e.preventDefault();
});

Example fiddle
The video doesn’t load, though by clicking the link you’ll see that two clicks are needed.

Great if somebody could suggest a solution how this can work with one click?

Thanks, Barry

a quick glance at the popup documentation spells it out for me:

(EDIT: To quote specifically:
"Popup initialization code should be executed after document ready, for example:

$(document).ready(function() {
  $('.image-link').magnificPopup({type:'image'});
});

"
It seems that the magnificPopup() function is a setup function. You call it when your document loads, and it sets up its own event handlers to handle the onclick.
So why did it take 2? clicking the link the first time fires the setup events, but doesnt activate the modal. The next time you click, you’re actually invoking BOTH your own handler (again) and the handler that the setup event set up on the item.

2 Likes

Arrh, I did read somewhere that some plugins have their own click event built in (magnificPopup() function is a setup function).

So we know what is happening, how do we fix it using my code? :slight_smile:

As mentioned…

I need to keep the document part of the click event for it to work with my template
$(document).on('click', '.popup', function(e){}

Barry

you cant use a $(document).ready ?

I already have

$(function() {
"use strict";

$(document).on('click', '.popup', function(e){
  $(this).magnificPopup({
    midClick: !0,
    removalDelay: 200,
    mainClass: "fade",
    prependTo: $("body"),
    type: "iframe"
  });
  e.preventDefault();
});
});

The below does not work on its own
$('.image-link').magnificPopup({type:'image'});

Something I ran into a few weeks back using the Mustache template engine. I need to wrap all my click events with the document part $(document).on('click', '.popup', function(e){} for it to work.

?

Thanks,
Barry

Yeah, but this ISNT a click event.

What happens if you replace the word ‘click’ in your code with the word ‘ready’ ?

Well that wont work because your link is classed popup, not image-link.

Yes I was just using that as an example.

Ok, I’ve just ran some tests, hence small dely :slight_smile:

What happens if you replace the word ‘click’ in your code with the word ‘ready’ ?

Update
As mentioned below, this now doesn’t fire.

Barry

Do you have a link to the actual version of the page that we could reach? PM if necessary.

Sorry @m_hutley, backtrack!

I just realised the ready doesn’t work.

I left the below snippet in the codepen :upside_down:

$(document).ready(function() {
  $('.popup').magnificPopup({type:'iframe'});
});

As you can see in the updated codepen the ready has no effect.

Cheers, Barry

I think we need a way of combining the below together.

$(document).on('click', '.popup', function(e){
  $(this).magnificPopup({
    ...
  })
})

But how?

Thanks in advance,

Barry

The click event isn’t needed. You just need to run the magnificPopup method on the elements that you want to associate it with.

That’s demonstrated in the documentation:

$(document).ready(function() {
  $('.image-link').magnificPopup({type:'image'});
});

and is applied to your example as follows:

$(function() {
"use strict";

  // Magnific modal
  $('.popup').magnificPopup({
    midClick: !0,
    removalDelay: 200,
    mainClass: "fade",
    prependTo: $("body"),
    type: "iframe"
  });
});

ready doesn’t take a second parameter. Plus it’s already inside a document.ready wrapper.

$(function() {…}) === $(document).ready(function() {…});

If it helps, the following jQuery ready syntax:

$(document).ready(function () {
    ...
});

is exactly the same as the following condensed jQuery syntax:

$(function () {
    ...
});

You can learn more about this from the jQuery documentation about the jQuery callback where it says:
This function behaves just like $( document ).ready()

Thanks @m_hutley, @Paul_Wilkins

I understand the document ready regarding the short hand with jquery. The problem is trying to use this plugin and fire it on single click within the Mustache template engine.

As outlined in an older thread using a diffrent plugin, I had the same issue which @m3g4p0p described as event delegation.

Example

This works when not using MustacheJS
$('.popup').magnificPopup({});

But when using MustacheJS - I need to add $(document)
$(document).on('click', '.popup', function(e){}

I’ve updated/created a new jsfiddle so you can see the Mustache template working with the popup needing 2 clicks.

Hope this makes sense.

Thanks,
Barry

I applied my same solution from before by removing the click event - what do you think?

Thanks Paul, I did try this before and new this would be tested :slight_smile:
It looks like things work, though on the bigger sacle and after much testing this does not work within my setup. I’m sure of it.

When I use this snippet within the CMS running Musatche and other frameworks, the video just opens in a new window. The popup dose’t fire.

I’ve already done lots of testing with this and know that every click handler used has needed $(document) to function within the Mustache template engine.

Just wondering though, is it not possible to set this up using $(document) somehow as mention in my last post?

Cheers, Barry

Did you know that your jsfiddle example already has a secret document.ready javascript code wrapper?
If you click on the JavaScript + jQuery 2.1.3 dropdown, you’ll see that the Load Type is On DOM Ready which puts all of your JavaScript code inside of $(document).ready(...)

Here’s an update of the JSFiddle that removes the secret onready wrap from the code, so that you can use it more clearly within the code with:

$(document).ready(function ($) {
  $(".popup").magnificPopup({
    ...
  });
});

Did you know that your jsfiddle example already has a secret document.ready javascript code wrapper?

Thanks Paul, I am aware of this. This is just for testing. In my dev setup I have lots of functions already running within the dom ready. This is not the problem.

The problem which I’ve just realised is that I’m using AJAX and loading JSON.

If you have a look at the new codepen (from an old thread) and fire up a video, you’ll see it works in the first istance. Now close the video and change the result using the dropdown and try opening a video again - this is the problem.

Now if we change your suggestion and revert back to my orignal snippet, it works everytime. But needs 2 clicks.

$(document).on('click', '.popup', function(e){
  $(this).magnificPopup({
    midClick: !0,
    removalDelay: 200,
    mainClass: "fade",
    prependTo: $("body"),
    type: "iframe"
  });
  e.preventDefault();
});
});

Cheers, Barry