Hey,

I use modal frame API with automodal, and I'm trying for the life of me to redirect to the submitted node AFTER modalframe_close_dialoug(); is envoked. Now, if I try to initiate the redirect, it redirects to the submitted node however it redirects within the modal window.

I can get the redirect to happen a couple of ways. The first is by hacking the modalframe.module - line 204:

function modalframe_form_submit($form, &$form_state) {
  if (!empty($GLOBALS['modalframe_close_dialog'])) {
   //Change from FALSE to TRUE
    $form_state['redirect'] = TRUE;
  }
}

This forces the redirect, but it happens within the modal. I'm not sure where/how to call modalframe_close_dialog() before the $form_state['redirect'].

The other way is by adding the function within automodal, which is essentially just a helper module to load the modal frame window with drupals forms api.


function automodal_form_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Save')) {
    // Tell the parent window to close the modal frame dialog.
    modalframe_close_dialog();
  }
} 

Trying to call the $form_state redirect outside of this function is still possible in automodal's invocation for hook_form_alter(), but again, the redirect will happen in the modal, not after the modal has closed.


function automodal_form_alter(&$form, &$form_state, $form_id) {
	$form['#submit'][] = 'automodal_form_submit';
        //Add in redirect
	$form_state['redirect'] = TRUE;
}

Lastly, it is possible to initiate the redirect through rules.module, but, again, the redirect only happens within the modal - not after it has closed.
Even if I set a rules action to 'execute custom php code' and add in modalframe_close_dialog(), the redirect still happens in the modal window.

I've been banging my head against this for a while, is there anything anyone can suggest to achieve this? The usability of modal frames to add node forms is severely diminished if the user can't be redirected to what they submitted.

Thanks!

Comments

infojunkie’s picture

subscribe

rc2020’s picture

Hey,

I'm really looking for any direction on this that anyone can provide. If you have any suggestions on how I could figure this out it would be really helpful.

Thanks!

iterator’s picture

You could redirect the user via Javascript using the onSubmit method:

onSubmit - Optional. A function that will be called when the dialog is closed by the server-side response to a form submit request. See modalframe_close_dialog($args).

This example will refresh the parent window after closing the child window:

Drupal.modalFrame.open({url: $(this).attr('href'), width: 400, height: 300, onSubmit: refreshSite});

function refreshSite(args, statusMessages) {
  location.reload();
}

You can combine this with rules. Execute custom php after submitting your form (modalframe_close_dialog();)
The child window will close automatically and then the submit handler will be called.

rc2020’s picture

Hey,

I'm having trouble implementing this. I'm wondering if I could possibly hire you for an hour of your time to simply explain how I'd integrate this with rules? I'm pretty capable and have written a few modules myself before, done database queries and the like - I'm just completely clueless with Javascript. An hour or so over Gmail chat should do it -

Please contact me at cmacpher at gmail dot com with your hourly rate if you would like to make some quick bucks for helping me out!

Thanks man.

rc2020’s picture

There is also a bounty to anyone who would can provide me with a solution to this problem, should they wish to do so!

Ideally, in a perfect world I would like the ability to (through rules would be nice) optionally redirect to the submitted node AFTER modal_close_dialog(); has been fired, and the modal closes. So - modal opened - node form filled out and submitted - close modal - if cck field is checked to redirect on the node (true) - redirect to that submitted node.

Anyone who can help me get as close to that as possible should also feel welcome to contact me.

Please let me know!

cmacpher at gmail dot com

infojunkie’s picture

Here's how we very recently implemented this:

1. In some JavaScript file, do the following:

Drupal.behaviors.your_module = function(context) {
  $('a.popup:not(.modalframe-processed)', context).addClass('modalframe-processed').click(function() {

    // 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 onSubmitCallback(args) {
      if (args.redirect) {
        setTimeout(function() { window.location = args.redirect; }, 1);
      }
    }

    Drupal.modalFrame.open({url: $(this).attr('href'), width: 500, height: 300, onSubmit: onSubmitCallback});
    return false;
  });
};

Any link with class 'popup' will open in a modal frame.

2. In your form submit function, do the following:

<?php
function your_module_some_form_submit($form, &$form_state) {
  modalframe_close_dialog(array('redirect' => url('node/' . $some_nid)));
}
?>

The redirect argument will be passed to the JavaScript onSubmit callback.

Hope this helps!

rc2020’s picture

The problem is I use automodal to initiate a lot of the modalframe API's functions, both JS and PHP. Drupal.behaviors.your_module is already invoked by Drupal.behaviors.automodal, and I'm unsure of how to add that in a seperate JS file with Drupal_add_js. I sent you an email I'd still like to see if I could hire you for an hour or two to help explain this to me from a conceptual standpoint so I 'get it' in the future.

Thanks again, so much, for your help.

markus_petrux’s picture

Status: Active » Fixed

There is also documentation here: http://drupal.org/node/700752

PD: Closing this issue, but it can be reopened. I just think the issue here was fixed. Thanks so much, BTW, and sorry for the delay. Too busy.

rc2020’s picture

Status: Fixed » Active

Hey Markus,

I'm sorry but I have read the documentation and this issue is not yet fixed as I have no real clue how to implement this functionality. I don't mind paying for the guide but as written I still have no clue how to implement this.

Thanks.

markus_petrux’s picture

Ok, I have pretty limited time to explain particular use cases here.

I think you should not trigger modal frame API with automodal, but using your own javascript code. This would allow you to use the onSubmit option of the .open() method and there you should be able to react when the modal frame is closed, and redirect, or whatever.

You have an example in #6. Now, all you need is send your javascript file in the correct page so it is available to do the job for the proper links. You should be able to do this from your hook_init() based on the value of $_GET['q'], which is the current site path, for example.

Apfel007’s picture

Hi Infojunkie,
try your user your explanation.. what about closing the modal?
I call a node with it's comment-box in a modal. Now I have to "connect" the submit handler of this form..

How would does it work.. is it right, that I'm must make a "form_alter" in the .module to append the close function to the submit button? Or is it possible to close the modal out of Jquery/JS? How know JS about the closing form function?

function modalframe_example_form_alter(&$form, $form_state, $form_id) {
   $form['#submit'][] = 'modalframe_example_form_submit';
}

function modalframe_example_form_submit($form, &$form_state) {
drupal_set_message(t('CLICK.'));
 
 if ($form_state['values']['op'] == t('Save')) {
    // Tell the parent window to close the modal frame dialog.
    modalframe_close_dialog(array(
      'message' => t('This is an argument sent by the Modal Frame API from the submit handler attached!'),
    ));
  }
}

infojunkie’s picture

@Apfel007:

* You're right: you need to alter your form to introduce a new submit handler, just like you did.

* I didn't try to close the window from JS directly.

* To inform JS about your own closing function, you need to include it in your Drupal.modalFrame.open call. Refer to my example above.

* The drupal_set_message(t('CLICK.')); call will display the message in the modal dialog, just before closing it. It will not appear on the main page.

Apfel007’s picture

@ infojunkie
thanks, but I'm not able to keep this thing on running.. Could you give me a further hint? Could it be, that the Modalframe Api have a problem with comments_form.. cause of the order of the elements? The dsm says, that the alter hook to the submit element is not working. There is only the comment_submit handler.. not my custom...

...
<?php
// $Id: modal_gallery_comment.module,v 1.1.2.3 2009/06/17 12:55:55  Exp $

/**
 * @file
 * 
 */

/**
 * Implementation of hook_perm().
 */
function modal_gallery_comment_perm() {
  return array('access modal gallery comment');
}

function modal_gallery_comment_init() {
  modalframe_parent_js();
  // Add the client-side behaviors for the examples.
  drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/modal_gallery_comment.js');
  drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/jquery.livequery.js');
}

/**
 * Implementation of hook_form_alter().
 *
 * 
 *
 */
function modal_gallery_comment_form_alter(&$form, $form_state, $form_id) {
  // Look for the comment form ....
 
    // Append our submit handler. This is required if we want a chance to
    // close the modal frame dialog.
   $form['#submit'][] = 'modalframe_example_message';
 }
/**
 * Submit handler f
 *
 */
function modal_gallery_comment_form_submit($form, &$form_state) {
  
if ($form['submit']['#value'] == t('Save')) {  // this should work cause of comment form?
    modalframe_close_dialog();
}
}

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


(function ($) {

Drupal.behaviors.modalGalleryComment = function() {
  $('.imagefield-field_gallery_image').addClass('modalframe-gallery-comment-processed').livequery('click', function(event) { 
    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. ??????? What should I write here.... is it needed if I only want to close the modal?
    function onSubmitCallback(args, statusMessages) {
      // Display status messages generated during submit processing.
      if (statusMessages) {
        $('.modal-gallery-comment-messages').hide().html(statusMessages).show('slow');
      }

      if (args && args.message) {
        // Provide a simple feedback alert deferred a little.
        setTimeout(function() { alert(args.message); }, 500);
      }
    }
    function onLoadAction(){        /// don't work... todo
    $('#modalframe-container').remove($(this).css('background'));
    $('.ui-dialog-title').text();
    }
    // Hide the messages are before opening a new dialog.
    $('.modal-gallery-comment-messages').hide('fast'); 
    
    // Build modal frame options.
    var modalOptions = {
      url: $(this).attr('link')+ '/modalframe',
      onSubmit: onSubmitCallback,
      onLoad: onLoadAction,
      width: 800, 
      height: 600
    };

    // Open the modal frame dialog.
    Drupal.modalFrame.open(modalOptions);
    // Prevent default action of the link click event.
    return false;

  });
};

})(jQuery);




that0n3guy’s picture

sub...

infojunkie’s picture

@Apfel007: your custom #submit function is set to modalframe_example_message while the function name is modal_gallery_comment_form_submit. Is that intended?

Apfel007’s picture

@infojunkie , was just a test, but the problem is, that the close modale function seems not to don't work...modal_gallery_comment_form_submit is called, but not modalframe_close_dialog()... something going wrong..

...
<?php
// $Id: modal_gallery_comment.module,v 1.1.2.3 2009/06/17 12:55:55  Exp $

/**
 * @file
 * Example for the Modal Frame module.
 */

/**
 * Implementation of hook_perm().
 */
function modal_gallery_comment_perm() {
  return array('access modal gallery comment');
}

function modal_gallery_comment_init() {
 modalframe_parent_js();

  // Add the client-side behaviors for the examples.
  drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/modal_gallery_comment.js');
  drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/jquery.livequery.js');
}

/**
 * Implementation of hook_form_alter().
 *
 * This function is part of the node edit form example.
 *
 * @see modalframe_example_node_edit_page()
 * @see modalframe_example_form_submit()
 */
function modal_gallery_comment_form_alter(&$form, $form_state, $form_id) {
  // Look for a node edit form.
//  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
  //  $node = &$form['#node'];

    // Is this node the one we are testing?
  //  if (!empty($GLOBALS['modalframe_example_node_edit_page_nid']) && $GLOBALS['modalframe_example_node_edit_page_nid'] == $node->nid) {


      // Append our submit handler. This is required if we want a chance to
      // close the modal frame dialog.
   $form['#submit'][] = 'modal_gallery_comment_form_submit';
     
    // $form['#submit'][] = 'modalframe_example_message';
    //}
 // }
}
/**
 * Submit handler for our node edit form example.
 *
 * This function is part of the node edit form example.
 *
 * @see modalframe_example_node_edit_page()
 * @see modalframe_example_form_alter()
 */
function modal_gallery_comment_form_submit($form, &$form_state) {
  // Ignore preview requests. Close dialog only when user clicks "Save" button.
if ($form['submit']['#value'] == t('Save')) {
    // Tell the parent window to close the modal frame dialog.
    modalframe_close_dialog();
    }
}
infojunkie’s picture

If modalframe_close_dialog is not called, then $form['submit']['#value'] does not equal t('Save').

that0n3guy’s picture

infojunkie,

I am having the same problems. I even removed the if ($form['submit']['#value'] == t('Save')) { check

so it looks like:

function modalframe_example_form_submit($form, &$form_state) {
    modalframe_close_dialog();
}

I know that function modalframe_example_form_submit is being called b/c I can do something like:

function modalframe_example_form_submit($form, &$form_state) {
print_r('Close please');
    modalframe_close_dialog();
}

...my comment is saved, and the modalframe shows nothing but "Close please".... but it still doesn't close.

I even went in and added print_r('Close please from close dialog'); to modalframe_close_dialog. It prints fine... so I'm positive modalframe_close_dialog is being called.

I'm not really any good at java so I haven't dug into that yet.

Graloth’s picture

I am having the same problem as that0n3guy mentions, using modalframe_close_dialog() inside my modules module_form_submit, but nothing happens when i hit submit.

However in my case nothing happens when i hit submit other than the modal itself shows the node that was edited/created (very horribly if i may add since it includes everything from the page, so you get a page-in-page view).
I have little idea about what is wrong, could be my code, or something else. looking into other modules that do work (the CCK contributed module does close on save/submit) leads me nowhere as i dont have enough knowledge of how i can reuse that code myself.

So any help would be greatly appreciated.

Apfel007’s picture

hi, without the "IF",it's not working for me, too. What's is the best way to "follow" the functions? Write dsm's into the module? Or is something available where I can see the called functions and it's vars... something hidden in devel?..

Apfel007’s picture

any suggestions?

ryan_courtnage’s picture

@infojunkie

cheers for #6 - works beautifully for redirection after a modal closes!

that0n3guy’s picture

so how did you get modal to close?

Apfel007’s picture

Hi,
spend some hours with this, but can't find the problem, why the modal isn't close.... could someone give me a hint, how to solve this? I can't see a context between this and the examples..... a few hints more...
1. if i put a alert into "onSubmitCallback", this is shown on parent after closing manualy
2. watchdog shows, that "modal_gallery_comment_form_submit" is called..
3. the child.js seems to be there.. or is the "not closing frame" a sign, that it isn't loaded?

// $Id: modal_gallery_comment.js,v 1.1.2.7 2009/12/28 02:21:20 KRav Exp $
(function ($) {
Drupal.behaviors.modalGalleryComment = function() {
  $('.imagefield-field_gallery_image').addClass('modalframe-gallery-comment-processed').livequery('click', function(event) { 
    var element = this;
    function onSubmitCallback(args, statusMessages) {
       // Display status messages generated during submit processing.
      if (statusMessages) {
        $('.modalframe-gallery-comment-messages').hide().html(statusMessages).show('slow');
      }
      if (args && args.message) {
        // Provide a simple feedback alert deferred a little.
        setTimeout(function() { alert(args.message); }, 500);
      }
    }
    // Build modal frame options.
    var modalOptions = {
      url: $(this).attr('longdesc')+ '/modalframe',
      onSubmit: onSubmitCallback,
    //  onLoad: onLoadAction,
      width: 800, 
      height: 600
    };
    // Open the modal frame dialog.
    Drupal.modalFrame.open(modalOptions);
    // Prevent default action of the link click event.
    return false;
  });
};
})(jQuery);

<?php
// $Id: modal_gallery_comment.module,v 1.1.2.3 2009/06/17 12:55:55 KRAV Exp $

/**
 * @file
 * Example for the Modal Frame module.
 */

/**
 * Implementation of hook_perm().
 */
function modal_gallery_comment_perm() {
  return array('access modal gallery comment');
}

function modal_gallery_comment_init() {
  drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/jquery.livequery.js');
  if (!empty($_COOKIE['has_js'])) {
    if (($_GET['q']) == 'node/1' ) {
      drupal_set_message(t('parent.'));
      modalframe_parent_js();
      drupal_add_js(drupal_get_path('module', 'modal_gallery_comment') .'/modal_gallery_comment.js');
    }
    elseif (preg_match('/modalframe/', $_GET['q'])){
      drupal_set_message(t('child'));
      modalframe_child_js();
    }
  }
}

/**
 * Implementation of hook_form_id_alter().
 *
 * This function is part of the node edit form example.
 *
 * @see modalframe_example_node_edit_page()
 * @see modalframe_example_form_submit()
 */
 
function modal_gallery_comment_form_comment_form_alter(&$form, &$form_state){
      // Append our submit handler. This is required if we want a chance to
      // close the modal frame dialog.????? 
  if (preg_match('/modalframe/', $_GET['q'])){
    drupal_set_message('child_alter');
  }
  $form['#submit'][] = 'modal_gallery_comment_form_submit';
}

/**
 * Submit handler for our node edit form example.
 *
 * This function is part of the node edit form example.
 *
 */
function modal_gallery_comment_form_submit($form, &$form_state) {
  $type = 'gallery_comment';
  $message = 'submit function!!!';
  watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL);
modalframe_close_dialog(array());
}

...
markus_petrux’s picture

@Apfel007 #24:

      url: $(this).attr('longdesc')+ '/modalframe',

This means that the URL for the child window ends with '/modalframe', right?

So checking for preg_match('/modalframe/', $_GET['q']) may not generate the correct resulst. Also, this method alters the path Drupal needs to match with the menu system.

It is easier to append an argument to the URL. For example:

  var url = $(this).attr('longdesc');
...
...
...
      url: url + (url.indexOf('?') == -1 ? '?' : '&') +'modalframe=1',

Then, in your PHP code, you can check like this: if (!empty($_GET['modalframe'])) {

Apfel007’s picture

Hi Markus,
thanks for the hint and your help.
I tried this, but the modal is not closing... what the hell could be the cause?

This means that the URL for the child window ends with '/modalframe', right?

Yes this should be the url of the popup...

Why is the connection not working...

rc2020’s picture

Apfel007’s picture

@ corona

what do you mean exactly? I have a look on the the submit handler of the comment form. My modal handler is is added to the submitted button on position [1]
One problem, maybe THE problem is, that the " modalframe_close_dialog()" function is not fired / working.... I seems it will be ignored..

What about the form_state is this directly in context with "modalframe_close_dialog()" ?

rc2020’s picture

@Apfel -

I'm not an expert on it myself I just wanted to direct you to an issue where I passed args to the JS but my JS looks alot different than yours and our use case is better. I had to hire a dev to get it working properly.

Apfel007’s picture

.. think it's not caused by JS..
Did some one know, how the modalframe_close_dialog() work with $form_state or $form? Is the this important to know? Of cause, there are a few differences between $form_state node/add-submit and $form_state comment-submit.

Made a quick test with automodal - same thing, node/add submit is working , comment submit is not working..

MAYBE a bug like this http://drupal.org/node/477832. Could be the order of handlers be a problem?

Apfel007’s picture

Hi it seems, that this stopped the closing..
how is this working?
1. if (isset($GLOBALS['modalframe_close_dialog']))
...this don't return "return" --- could that be the problem?
2. How is this working : drupal_add_js(array('modalFrameChild' => $child_js_settings), 'setting');

Could someone give me a little help please?

How could I follow the function...

/**
* API: Close a client side dialog.
*
* This function should be used on form submit handlers to trigger the
* action that will close the modal frame on the client side.
*
* @param $args
* An optional array of arguments that will be forwarded to the client
* side onSubmit callback.
*
* @ingroup modalframe_api
*/
function modalframe_close_dialog($args = NULL) {
print "---close dialog";

print_r ($GLOBALS);
// Make sure this action is not processed more than once.
drupal_set_message(t('close'));
if (isset($GLOBALS['modalframe_close_dialog'])) {

print "---GLOBAL return";

return;
}

...
  // Build the javascript settings that will close the modal frame on the
  // client side.
  $child_js_settings = array(
    'closeModal' => 1,
    'statusMessages' => theme('status_messages'),
    'args' => (isset($args) && is_array($args) ? $args : array()),
  );
  drupal_add_js(array('modalFrameChild' => $child_js_settings), 'setting');

  // Tell Drupal's Form API that we are requested to close the modal dialog,
  // so we do not wish to perform redirections after submitted form has been
  // processed.
  $GLOBALS['modalframe_close_dialog'] = TRUE;
}
rc2020’s picture

@Apfel -

Have you tried the automodal module?

This is a pretty standard implementation of modalframe and all you have to do is add in a submit handler on the module code and it'll submit any node form no problem and close without issue.

Just download it, and edit the automodal.module and add in the following code:


function automodal_form_alter(&$form, &$form_state, $form_id) {
	$form['#submit'][] = 'automodal_form_submit';
}

function automodal_form_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Save')) {
    // Tell the parent window to close the modal frame dialog.
    modalframe_close_dialog();
  }
} 


zuzu83’s picture

try this :)

function myfunction_form_alter(&$form, $form_state, $form_id) {
      $form['buttons']['submit']['#submit'][] = 'myfunction_form_submit_redirect';
}


function myfunction_form_submit_redirect($form, &$form_state){
  // Ignore preview requests. Close dialog only when user clicks "Save" button.
  if ($form_state['values']['op'] == t('Save')) {
      $node = node_load($form_state['nid'], NULL, TRUE);
      modalframe_close_dialog(array('redirect' => $form_state['nid'] .''));
  }
}

and JS file


      function onSubmitCallback(args) {
      if (args.redirect) {
        setTimeout(function() { window.location = args.redirect; }, 1);
      }
    }

    Drupal.modalFrame.open({url: $(this).attr('href'), height: 600, onSubmit: onSubmitCallback});
    return false;
 
zuzu83’s picture

This is example for node form submission

try this

function myfunction_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'page_node_form') {
      $form['buttons']['submit']['#submit'][] = 'myfunction_form_submit_redirect';
 }
}


function myfunction_form_submit_redirect($form, &$form_state){
  if ($form_state['values']['op'] == t('Save')) {
      $node = node_load($form_state['nid'], NULL, TRUE);
      modalframe_close_dialog(array('redirect' => $form_state['nid'] .''));
  }
}
Apfel007’s picture

@ charlie836

thanks for your suggestions.. you won't be know what I've simply done..

I put the child.js call into the form_alter and everything works...!!!

tenamurphy’s picture

#6 works fine if your child modal window is editing an existing node (because you already know the nid). However, if the child modal window is a node add form, then you don't have a nid yet at the point where modalframe_close_dialog is executed. When the child closes, is there an elegant way to redirect the parent to the newly added nid, which you don't know yet?

markus_petrux’s picture

Status: Active » Fixed

If you attach your submit handler to $form['buttons']['submit']['#submit'], you'll find the nid of the new/edited node looking at $form_state['nid']. See node_form_submit().

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.