9

I am trying to get a confirm box to pop up ONLY if a user has made change to the form inside the magnific popup that shows it's content in an iframe.

<a href="#" class="opener-class" data-mfp-src="/whatever.asp" data-lightbox="iframe" data-plugin-options='{"type":"iframe"}'>

code:

$('.opener-class').magnificPopup({
   type:'iframe',
   change: function() {
      $.magnificPopup.instance.close = function () {
         if (!confirm("Are you sure?")) {
            return;
         }
         $.magnificPopup.proto.close.call(this);
      };                                    
   }
});

Change does not seem to work. I tried to bind the form inside open: like we do on the rest of our site, but that did not work either.

$(':input', document.myForm).bind("change", function() {
      //confirm here
   }
);

HTML for Form Sample on the page in whatever.asp that gets submitted - if anything is changed in that textbox, I want the confirm close to appear:

<form class="validate" action="/whatever.asp" method="post">
    <label>Notes</label>
    <textarea class="form-control input-sm required" name="Notes" id="Notes" rows="3"></textarea>
</form>

I think the issue is that the code is on the parent page and then opens a magnific popup content in an iFrame.

Any help would be appreciated!

I have been playing around with all these options and none seem to work. Here's the issue - the "change" is not firing for a form. "change" is firing for the popup, but if I wrap the check for a change in a form item with console logs, they are fine, but the cosole log inside the form change does not fire. The issue here has to be with accessing the form items since they are in an iframe!!! So, I ended up just not using the default close button, using modal=true, and created my own close button inside the iframe that I programmatically control myself onclick on the button class and parent.$.magnificPopup.close(); from inside the iframe - works like a charm.

Dennis
  • 708
  • 2
  • 10
  • 25

3 Answers3

4

I have made a CodePen for what I believe you are trying to accomplish.

http://codepen.io/gbhojraj/pen/VaVPRM?editors=1010

The relevant code is as follows:

$('#open-popup').magnificPopup({
  type:'iframe',
  callbacks: {
        open: function() {

            contents = $('#Notes').val();

            $.magnificPopup.instance.close = function () {
                 if(contents != $('#Notes').val()){
                     if (!confirm("Are you sure?")) {
                     return;
                  }
              }
       $.magnificPopup.proto.close.call(this);
  };

}

What I did was fill the contents variable with the value from the text input when the Open event fires. Then, when Close is called, it checks to see if the value of the text input is the same as the value of contents, which has not changed since it was initialized.

The important thing is to nest the open parameter within callbacks, which doesn't appear in your original code.

Gibryon Bhojraj
  • 755
  • 5
  • 12
  • I need this to be generic - not specify a field. The code needs to work for any field. See my bind example above. Remember - the form is in the popup iframe too, is the callback out of scope then?? – Dennis May 02 '16 at 00:22
  • Try running `console.log(this)` from within the callback on your code. I can see my form element within `this.content`. If you can, then you can run your generic binding from within the callback on that element. – Gibryon Bhojraj May 02 '16 at 01:45
  • this has the same issues as the ones below - the iframe messes it up. Have a full working example? – Dennis May 09 '16 at 11:58
1

According to the code above, I made an example suited to your case. This means it will work for any text input aswell as textarea.

$('#open-popup').magnificPopup({
  type:'iframe',
  iframe: {
    markup: '<form class="validate" action="/whatever.asp" method="post"><label>Notes</label><textarea class="form-control input-sm required" name="Notes" id="Notes" rows="3"></textarea></form>'
  },
  callbacks: {
    change: function() {
      var $form = $(this.content[0]),
          values = {},
          changed = [];
      $form.find('input[type=\'text\'], textarea').each(function() {
        values[this] = this.value;
      });
      $form.on('change', function(e) {
        var input = e.target, 
            index = changed.indexOf(input);
        if (input in values) {
          if (input.value !== values[input] && index === -1) { 
            changed.push(e.target);
          } else if (e.target.value === values[e.target] && index !== -1) {
            changed.splice(index, 1);
          }
        }
      });
      $.magnificPopup.instance.close = function () {
        if (changed.length && !confirm('Are you sure?')) {
          return;
        }
        $.magnificPopup.proto.close.call(this);
      };
    }
  }
});
Jakub Rożek
  • 2,110
  • 11
  • 12
1

use hidden input like this

<input id="hf1" type="hidden" value="" />
<input id="hf2" type="hidden" value="" />

then in your javacripts use this :

$('#hf2').val($('#Notes').val());
 $('#Notes').on('change', function () {
     $('#hf1').val($(this).val());
 });

then call :

    $('#open-popup').magnificPopup({
  type:'iframe',
  callbacks: {
        open: function() {

            $.magnificPopup.instance.close = function () {
                 if($('#hf1').val() != $('#hf2').val()){
                     if (!confirm("Are you sure?")) {
                     return;
                  }
              }
       $.magnificPopup.proto.close.call(this);
       }
,  iframe: {
   markup: '<form class="validate" action="/whatever.asp" method="post">'+
           '<label>Notes</label><textarea class="form-control'+
           'input-sm required" name="Notes" id="Notes" rows="3">'+
           '</textarea></form>'
          }    
   });
Ali Gh
  • 680
  • 7
  • 9
  • This will not work since the popup content is in an iframe - it loses scope back to the parent. The issue here seems to be that you have to check for content changes inside an iframe that is not talking back to the parent page. Unless you have this working through an example? – Dennis May 09 '16 at 11:57