I'm trying to produce a modal ajax from based on various examples I've found, all of which are similar. The one thing that stands out to me as different are the circumstances under which I will display the popup. I am doing it when hook_nodeapi responds to the pre-save on a node. I think this may have much to do with the fact that the ctools_ajax_render call results in a white page full of dump beginning like this:

[ { "command": "settings", "argument": { "basePath": "/", "fb_connect": { "front_url": "/", "fbu": null, "uid": "1" }, "automodal": { ".automodal": { "autoFit": true, "draggable": true, "width": 600, "height": 400, "automodalClose": true, "automodalReload": false } }, "fivestar": { "titleUser": "Your rating: ", "titleAverage": "Average: ", "feedbackSavingVote": "Saving your vote...", "feedbackVoteSaved": "Your vote has been saved.", "feedbackDeletingVote": "Deleting your vote...", "feedbackVoteDeleted": "Your vote has been deleted." }, "modal-login-resize-user-login": { "modalSize": { "type": "fixed", "width": 300, "height": 290 } }, "modal-login-resize-user-register": { "modalSize": { "type": "fixed", "width": 300, "height": 250 } }, "modal-login-resize-user-pass": { "modalSize": { "type": "fixed", "width": 300, "height": 250 } }, "CToolsModal": { "loadingText": "Loading...", "closeText": "Close Window", "closeImage": "\x3cimg src=\"/sites/all/modules/contrib/ctools/images/icon-close-window.png\" alt=\"Close window\

My codes is:

function mymodule_popup() {
  ctools_include('ajax');
  ctools_include('modal');

  $form_state = array( 'ajax' => TRUE, 'title' => 'test' );
  $output = ctools_modal_form_wrapper('ramp_nlp_terms_form', $form_state);

  if (!$output) {
    $output = array();
    $output[] = ctools_ajax_command_replace('#modal-message', '<div id="modal-message">' . $form_state['message'] . '</div>');
    $output[] = ctools_modal_command_dismiss();
  }
  ctools_ajax_render($output);
}

function mymodule_form(&$form_state) {
  $form['text'] = array(
    '#type' => 'textfield',
    '#title' => t('Text'),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

Comments

j. ayen green’s picture

The modal form wrapper call does actually match the form function...I just missed it when I was doing clean-up before posting

merlinofchaos’s picture

Status: Active » Postponed (maintainer needs more info)

If you see a page dump like that, one of two things happened:

1) javascript crashed and turned the link into a nonjavascript link or
2) AJAX was never attached to the link and it just clicked through.

Your problems are more likely on the front end (i.e, the link that triggers the modal) rather than the back end.

j. ayen green’s picture

Both of those are related to a link...and perhaps the problem is that I'm not using one, as such. My intent is to place a modal popup between the clicking of the save button on the node form and the save/page change. To that end I'm invoking the popup as a result of nodeapi on pre-save, without altering the node form's save button...need I?

j. ayen green’s picture

Answering my own question, in part, it occurs to me (BFO) that when clicking the save button, it's unlikely an ajax event can occur unless the button is bound to js in some way, otherwise the route is back to the server with no return path to the page to cause the js popup to appear. What I'm trying to do is a quasi kind of late binding, but I'm thinking that's not possible unless I do something to alter the node form initially?

merlinofchaos’s picture

Yeah, to do something like that you'll need to write some javascript that does the ajax call you need. It's not TOO difficult but it's not completely trivial either.

j. ayen green’s picture

Ok...thanks for pointing me in the right direction. I'm first going to try to listen to the click event for the button a la jquery by hookin form alter. I'll post the solved code back here when it eventually works.

merlinofchaos’s picture

Status: Postponed (maintainer needs more info) » Fixed

You don't need a form alter for that.

$('#button-id').click(function() {
  // do stuff. Eventually call ctools clickAjaxLink or clickAjaxButton to run your AJAX.
});

Then you need to make sure your ajax response is smart enough to submit the form. That probably means a custom AJAX command.

j. ayen green’s picture

Don't I need to use form alter to place the jquery on the same page as the node form? The node form for all intents and purposes is otherwise outside the control of my module...i'm just hijacking its save workflow. So for the jquery above to work, it would need to be loaded when the node form is loaded, which I'm thinking means either (a) nodeapi at display but before save is clicked, or (b) form alter.

merlinofchaos’s picture

Well, you place the jquery in a .js file and you've got many ways to add that .js file to the page. hook_form_alter is one, hook_init is another, etc.

j. ayen green’s picture

Status: Fixed » Active

I looked at it awhile and decided it is much cleaner (and easier!) to use a link and a voluntary workflow rather than hijacking the submit process.

So I have the popup and presentation as a result of the link click working fine (mycallback/nojs/go). What I'm scratching my head about now is that the process of creating the data to display in the popup requires the contents of the node body, which has not been saved yet since this is a node creation scenario.

I can access the body on the client side via CKEDITOR.instances['edit-body'].getData(), but how do I pass that with the link click?

j. ayen green’s picture

I think I worded that too broadly. What I mean is, I create the link that invokes the ctools ajax modal call by using #suffix on the body field in the node form. So I have the link sitting below the body. Works great.

But I need the contents of the body field to be passed when the link is clicked. I can't seem to grok whether there is something I should be invoking on the php side when I alter the form to include the link that will tell ctools to grab that browser data when the link is clicked, or some way to do it on the browser side.

I know that ctools must have a way to send the data as part of the ajax call. Normally, if it were a page change and just js, I'd do an onclick and then end the js function with window.location. Here, the link is already being listened to by the js that ctools installs, because the click ends up being an ajax call and not a http location change, so if I need to use js to dynamically alter the link at the time it is clicked (to append the body field text as a query string parm) without also taking ownership of the link's execution once I'm done altering it, I don't know how.

j. ayen green’s picture

Status: Active » Closed (works as designed)