First off, thanks so much for such a cool contribution. The functionality is great and the api is very clean and flexible.

I'm having a strange behaviour and just can't seem to get a handle on..

I have a view that, in addition to the node data, has "edit node" links that I have successfully hooked into the modal api. So say I have a view with 5 nodes in the list. There are 5 edit node links.

If I click on an edit node link, the node form comes up nicely in a modal. Save the node, the modal closes. Perfect. The problem is if I go to open another node from the view -- they won't open in a modal, they open in a new page. If I refresh the view, the modals work again.

I've looked in the page code. When the view first loads up the "edit node"links look as follows:

<a class="vendor-modal-child vendor-modal-size[600,400] vendor-modal-processed" href="/vendors-admin/2645/edit">Edit</a>

When I save the node and the modal closes, the same link looks like this:

<a class="vendor-modal-child vendor-modal-size[600,400]" href="/vendors-admin/2645/edit">Edit</a>

When I refresh, it returns to the first state and the modal link works again. Seems to have something to do with that "vendor-modal-processed" class.

Any ideas?

Comments

jghyde’s picture

Can you copy your javascript code in here? Looks like jquery is resetting the class declarations.

mpaler’s picture

Thanks for looking


// $Id: modalframe_example.js,v 1.1.2.7 2009/12/28 02:21:20 markuspetrux Exp $

(function ($) {

Drupal.behaviors.vendorsModal = function() {
  $('.vendor-modal-child:not(.vendor-modal-processed)').addClass('vendor-modal-processed').click(function() {
    var element = this;

    // This is our onSubmit callback that will be called from the child window
    // when it is requested by a call to modalframe_close_dialog() performed
    // from server-side submit handlers.
    function onVendorSubmitCallback(args, statusMessages) {
      // Display status messages generated during submit processing.

      if (args && args.product_id) {
        // Provide a simple feedback alert deferred a little.
        // product id is sent from cs_vendors_admin_form_submit()
        setTimeout(
          function() {
            var refreshUrl = '/vendors-admin/refresh-vendors/' + args.product_id;

          // This function will get exceuted after the ajax request is completed successfully
          var updateVendors = function(data) {
            // The data parameter is a JSON object. The “products” property is the list of 
            // products items that was returned from the server response to the ajax request.
            $('.view-cs-vendor-price-objects').html(data.vpos);
          }
          $.ajax({
            type: 'POST',
            url: refreshUrl , // Which url should be handle the ajax request. This is the url defined in the <a> html tag
            success: updateVendors, // The js function that will be called upon success request
            dataType: 'json', //define the type of data that is going to get back from the server
            data: 'js=1' //Pass a key/value pair
          });
          //return false;  // return false so the navigation stops here and not continue to the page in the link
        }, 300);
      }
      
      if (statusMessages) {
        $('.vendor-modal-messages').hide().html(statusMessages).show('slow');
      }
      
    }

    // Hide the messages are before opening a new dialog.
    $('.vendor-modal-messages').hide('fast');

    // Build modal frame options.
    var modalOptions = {
      url: $(element).attr('href'),
      autoFit: true,
      onSubmit: onVendorSubmitCallback
    };

    // Try to obtain the dialog size from the className of the element.
    var regExp = /^.*vendor-modal-size\[\s*([0-9]*\s*,\s*[0-9]*)\s*\].*$/;
    if (typeof element.className == 'string' && regExp.test(element.className)) {
      var size = element.className.replace(regExp, '$1').split(',');
      modalOptions.width = parseInt(size[0].replace(/ /g, ''));
      modalOptions.height = parseInt(size[1].replace(/ /g, ''));
    }

    // Open the modal frame dialog.
    Drupal.modalFrame.open(modalOptions);

    // Prevent default action of the link click event.
    return false;
  });
};

})(jQuery);
jghyde’s picture

Maybe get more specific in the selector:
$('a.vendor-modal-child:not(a.vendor-modal-processed)').addClass('vendor-modal-processed').click(function() ...

mpaler’s picture

Status: Active » Closed (fixed)

In my case, the view was being dynamically refreshed with data submitted by the modal form. As such I needed to put a Drupal.attachBehaviors(); function into the javascript so the newly loaded html would have the modal javascript attached to it.

    function onVendorSubmitCallback(args, statusMessages) {
      // Display status messages generated during submit processing.

      if (args && args.product_id) {
        // Provide a simple feedback alert deferred a little.
        // product id is sent from cs_vendors_admin_form_submit()
        setTimeout(
          function() {
            var refreshUrl = '/vendors-admin/refresh-vendors/' + args.product_id;
            // This function will get exceuted after the ajax request is completed successfully
            var updateVendors = function(data) {
              // The data parameter is a JSON object. The “products” property is the list of 
              // products items that was returned from the server response to the ajax request.
              $('.view-cs-vendor-price-objects').html(data.vpos);
              $('.view-cs-vendor-price-objects tbody tr').effect("highlight", {}, 1200); 
              Drupal.attachBehaviors();  // <--- needed this here.
            }
            $.ajax({
              type: 'POST',
              url: refreshUrl , // Which url should be handle the ajax request. This is the url defined in the <a> html tag
              success: updateVendors, // The js function that will be called upon success request
              dataType: 'json', //define the type of data that is going to get back from the server
              data: 'js=1' //Pass a key/value pair
            });
            //return false;  // return false so the navigation stops here and not continue to the page in the link
          }, 100);
        }
        if (statusMessages) {
          $('.vendor-modal-messages').hide().html(statusMessages).show('slow');
        }
      }