Search code examples
jquerysimplemodal

JQuery SimpleModal can not bind to onShow


Seeking some help to determine what the heck is the issue as to why I am not able to bind an event from my modal box to the onShow. I can see the onShow is being triggered if I just put in an alert message. But what I really want to do is capture the the Reset event and use that to trigger an ajax call back to the service to send out an email to the user.

I use the following to create the modal:

<li class="actions-text"><a class="modal-s" href="modal/modal-password.jsp">Forgot Password?</a></li>

This will then trigger the following java script:

    $('.modal-s').click(function (e) {
        $.modal('<iframe src="' + this.href + '" height="230" width="480" scrolling="no">', {
            overlayClose:true,
            onOpen: function (dialog) { 
                dialog.overlay.fadeIn('slow', function () { 
                    dialog.container.slideDown('slow', function () {
                        dialog.data.fadeIn('slow');
                    });
                });
            },
            onClose: function (dialog){ 
                dialog.data.fadeOut('slow', function () {   
                    dialog.container.slideUp('slow', function () {
                        dialog.overlay.fadeOut('slow', function () {
                            $.modal.close(); 
                        });
                    });
                });
            },
            onShow: function (dialog) {
                $("form", dialog.data).submit(function () {
            alert('submitting the form');
            parent.jQuery.modal.close();
                });
            }
        });
        return false;
    }); 

The modal is:

            <form name="resetPasswordForm" id="resetPasswordForm">
            <dl class="form">
                <dt><label>Email:</label></dt>
            <dd><input type="email" id="passwordResetEmail" name="passwordResetEmail"/></dd>
            <dd class="clear">&nbsp;</dd>
                </dl>
            <ul class="actions">
                <li class="actions-submit"><input type="submit" class="button" value="Reset" id="submitPasswordReset" name="submitPasswordReset"/></li>
                </ul>
            </form>

Solution

  • The core of the problem is the use of the iframe to load an external file. When you add this selector to SimpleModal's onShow:

    $("form", dialog.data) 
    

    ...it evaluates to:

    $('div#simplemodal-data.simplemodal-data form')
    

    But because of the iframe your DOM is actually:

    <div id="simplemodal-data" class="simplemodal-data" style="">
      <iframe width="480" scrolling="no" height="230" src="http://192.168.0.189:8082/sm/modal-password.php"></iframe>
    </div>
    

    Which means that if it was possible you would really be needing a selector like:

    div#simplemodal-data.simplemodal-data > iframe > html > body > form
    

    Of course you cannot access an iframe that way, and similarly, you can not capture a click in the iframe and have the event bubble up to the parent page.

    I'm surprised this is SimpleModal's solution to external content.

    Two solutions I can think of are 1) add the external content to a hidden div on the same page or 2) use jQuery's load() method to populate an empty div on the page and then show the modal.

    Option 1 looks like this:

    <a class="modal-s" href="#">Forgot Password?</a>
    <!-- hide this div in css -->
    <div id="modal-content">
      <form name="resetPasswordForm" id="resetPasswordForm">
        <dl class="form">
          <dt>
            <label>
              Email:
            </label>
          </dt>
          <dd>
            <input type="email" id="passwordResetEmail" name="passwordResetEmail"/>
          </dd>
          <dd class="clear">
            &nbsp;
          </dd>
        </dl>
        <ul class="actions">
          <li class="actions-submit">
            <input type="submit" class="button" value="Reset" id="submitPasswordReset" name="submitPasswordReset"/>
          </li>
        </ul>
      </form>
    </div>
    

    JS:

    $('.modal-s').click(function(e){
      $('#modal-content').modal({
        overlayClose: true,
        onOpen: function(dialog){
          dialog.overlay.fadeIn('slow', function(){
            dialog.container.slideDown('slow', function(){
              dialog.data.fadeIn('slow');
            });
          });
        },
        onClose: function(dialog){
          dialog.data.fadeOut('slow', function(){
            dialog.container.slideUp('slow', function(){
              dialog.overlay.fadeOut('slow', function(){
                $.modal.close();
              });
            });
          });
        },
        onShow: function(dialog){
          $("form", dialog.data).submit(function(){
            alert('submitting the form');
            parent.jQuery.modal.close();
          });
        }
      });
      return false;
    });
    

    Option 2:

    <a class="modal-s" href="#">Forgot Password?</a>
    <!-- hide this div in css -->
    <div id="modal-content"></div>
    

    JS:

    $('.modal-s').click(function(e){
      //note use of load()
      $('#modal-content').load('modal-password.php', function(){
        $('#modal-content').modal({
          overlayClose: true,
          onOpen: function(dialog){
            dialog.overlay.fadeIn('slow', function(){
              dialog.container.slideDown('slow', function(){
                dialog.data.fadeIn('slow');
              });
            });
          },
          onClose: function(dialog){
            dialog.data.fadeOut('slow', function(){
              dialog.container.slideUp('slow', function(){
                dialog.overlay.fadeOut('slow', function(){
                  $.modal.close();
                });
              });
            });
          },
          onShow: function(dialog){
            $("form", dialog.data).submit(function(){
              alert('submitting the form');
              parent.jQuery.modal.close();
            });
          }
        });
      });
      return false;
    });
    

    Note: this is clunky because it will pull the external data every time the triggering link is clicked. It might be wiser to see if it has already loaded and save the extra calls, but you get the idea.