Searching for AHAH! instead of AHAH?
I have a form as a result of content profile. I want to add an #AHAH attribute to one of the fields, and #PREFIX/#SUFFIX to another to receive the ajax return, in hook_form_alter. When I do that ($form[myfield][#prefix]=) both fields disappear. My head is swimming looking at all the posts on this and the various hacks to solve it. I've read discussions of using pre-render, after-build, drupal_add_js to manually inject the ahah...is there a clean way to do this? Jeff -- Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com <http://ayendesigns.com> Blog: theAccidentalCoder.com <http://theaccidentalcoder.com> Drupal: j. ayen green <http://drupal.org/user/367108> IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns Ayen Designs is a tradename of the computer services division of
Please describe the entire sequence. *When* does a field disappear? When you activate the #ahah-enabled element? That means you're most of the way there, but you've put #prefix/suffix around both forms somehow and are not returning a reasonable bit of markup. Please make sure you dsm() or debug your form after altering to see what you've actually got. Are you using the base code provided by the AHAH Example in the Examples project? Thanks, -Randy On Wed, Dec 29, 2010 at 6:21 PM, <jeff@ayendesigns.com> wrote:
I have a form as a result of content profile. I want to add an #AHAH attribute to one of the fields, and #PREFIX/#SUFFIX to another to receive the ajax return, in hook_form_alter. When I do that ($form[myfield][#prefix]=) both fields disappear.
My head is swimming looking at all the posts on this and the various hacks to solve it. I've read discussions of using pre-render, after-build, drupal_add_js to manually inject the ahah...is there a clean way to do this?
Jeff
--
Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com Blog: theAccidentalCoder.com <http://theaccidentalcoder.com> Drupal: j. ayen green <http://drupal.org/user/367108> IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns
Ayen Designs is a tradename of the computer services division of
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
I'm using the example out of Drupal Pro Development actually. I have a menu callback, and my form alter is function test_form_alter(&$form, &$form_state, $form_id) { $form['field_one']['#prefix'] = '<div id="field-one">'; $form['field_one']['#suffix'] = '</div>'; $form['field_two']['#ahah'] = array( 'path' => 'test/stuff_js', 'wrapper' => 'field-one' ); The form array contains the original fields, though they don't show on the page or appear in the html. The values above appear in the form array, but not in the field-info section. On 12/29/2010 08:28 PM, Randy Fay wrote:
Please describe the entire sequence. *When* does a field disappear? When you activate the #ahah-enabled element? That means you're most of the way there, but you've put #prefix/suffix around both forms somehow and are not returning a reasonable bit of markup.
Please make sure you dsm() or debug your form after altering to see what you've actually got.
Are you using the base code provided by the AHAH Example in the Examples project?
I recommend that you start with the AHAH example, and use the very straightforward canned callback code from there. If that doesn't get you where you need to go, I can help you with specific code. -Randy On Wed, Dec 29, 2010 at 7:02 PM, <jeff@ayendesigns.com> wrote:
I'm using the example out of Drupal Pro Development actually.
I have a menu callback, and my form alter is
function test_form_alter(&$form, &$form_state, $form_id) { $form['field_one']['#prefix'] = '<div id="field-one">'; $form['field_one']['#suffix'] = '</div>';
$form['field_two']['#ahah'] = array( 'path' => 'test/stuff_js', 'wrapper' => 'field-one' );
The form array contains the original fields, though they don't show on the page or appear in the html. The values above appear in the form array, but not in the field-info section.
On 12/29/2010 08:28 PM, Randy Fay wrote:
Please describe the entire sequence. *When* does a field disappear? When
you activate the #ahah-enabled element? That means you're most of the way there, but you've put #prefix/suffix around both forms somehow and are not returning a reasonable bit of markup.
Please make sure you dsm() or debug your form after altering to see what you've actually got.
Are you using the base code provided by the AHAH Example in the Examples project?
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
Ok, doing that with dependent dropdown example. So far I've the same result, so I just want to verify something, because the place where I'm having the problem (where if commented out, the problem goes away) is what must differ for the Examples example, and I think it's more related to adding properties to the field than the ahah itself. In the examples module, the form is being created. In my case, the form comes to me created, and both dropdowns (trigger and dependent) come to me initially populated. So, instead of creating the fields and populating them the way the example does, I'm taking the existing fields and adding the pieces necessary for ahah (#ahah in the trigger field, etc.) in hook_form_alter. If I comment out where I add #ahah to the first dropdown, the field reappears. On 12/29/2010 09:13 PM, Randy Fay wrote:
I recommend that you start with the AHAH example, and use the very straightforward canned callback code from there.
If that doesn't get you where you need to go, I can help you with specific code.
Ah, think I got it. Well...the fields are back... Thanks for the example and the help!
Next issue. My callback isn't being hit when I change the value in the master dropdown. I have the code below...simplified, albeit apparently wrong. Unlike the examples, the #ahah being added to the field does not result in any ahah references in jQuery.extend(Drupal.settings. function test_menu() { $items = array(); $items['test/dropdown/callback'] = array( 'page callback' => 'test_do_callback', 'type' => MENU_CALLBACK, 'access_callback' => TRUE, ); return $items; } function test_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'test_profile_node_form') { $form['field_two']['#prefix'] = '<div id="field-two-wrapper">'; $form['field_two']['#suffix'] = '</div>'; $form['field_master']['#ahah'] = array( 'path' => 'test/dropdown/callback', 'wrapper' => 'field-two-wrapper' ); $form['field_master']['#tree'] = TRUE; } } function test_do_callback() { // do stuff here }
I won't have a chance to look at this tonight, but just a comment that is probably irrelevant: It's highly unusual to set #tree on a portion of a form rather than the whole form. #tree makes $form_state['values'] have its values in a hierarchical, rather than flat, arrangement, and it's not clear why you would want that. It's also rather dangerous to mess with #tree when you're form-altering, as it changes what will happen for other participants in the form. One thing you should make sure to check: Is ahah.js being loaded on the page? Just check with firebug. If it's not, you may have to load it explicitly. -Randy On Wed, Dec 29, 2010 at 11:03 PM, <jeff@ayendesigns.com> wrote:
Next issue. My callback isn't being hit when I change the value in the master dropdown. I have the code below...simplified, albeit apparently wrong. Unlike the examples, the #ahah being added to the field does not result in any ahah references in jQuery.extend(Drupal.settings.
function test_menu() { $items = array(); $items['test/dropdown/callback'] = array( 'page callback' => 'test_do_callback', 'type' => MENU_CALLBACK, 'access_callback' => TRUE, );
return $items;
}
function test_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'test_profile_node_form') { $form['field_two']['#prefix'] = '<div id="field-two-wrapper">'; $form['field_two']['#suffix'] = '</div>';
$form['field_master']['#ahah'] = array( 'path' => 'test/dropdown/callback', 'wrapper' => 'field-two-wrapper' ); $form['field_master']['#tree'] = TRUE; } }
function test_do_callback() {
// do stuff here
}
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
On 12/29/2010 10:10 PM, Randy Fay wrote:
It's highly unusual to set #tree on a portion of a form rather than the whole form. #tree makes $form_state['values'] have its values in a
I disagree, I often use it on just portions of the form that are hierarchical. =)
So are you saying that Earl Miles doesn't do some highly unusual things? :-) I think my key point was that using #tree in a form_alter could have unanticipated effects. -Randy On Wed, Dec 29, 2010 at 11:38 PM, Earl Miles <merlin@logrus.com> wrote:
On 12/29/2010 10:10 PM, Randy Fay wrote:
It's highly unusual to set #tree on a portion of a form rather than the whole form. #tree makes $form_state['values'] have its values in a
I disagree, I often use it on just portions of the form that are hierarchical. =)
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
On Wed, 2010-12-29 at 23:55 -0700, Randy Fay wrote:
So are you saying that Earl Miles doesn't do some highly unusual things? :-)
I think my key point was that using #tree in a form_alter could have unanticipated effects.
Not only could, but does. A lot of forms in core are not #tree'd, but have a hierchical build in the function that builds it. The side effect is that at validate (if any custom validation handler) / submit time, the handlers won't find their original data because the values will be a tree reflecting the form build instead of a flattened array. It happened to me once, I won't mess like that with core forms anymore :) But I still don't understand the real purpose of making form that are not #tree'd by the way. #tree is good, and at least it ensures that data will have the same structure than the form (and more than that, can avoid name conflicts). Pierre.
On 12/30/2010 4:08 AM, Pierre Rineau wrote:
But I still don't understand the real purpose of making form that are not #tree'd by the way. #tree is good, and at least it ensures that data will have the same structure than the form (and more than that, can avoid name conflicts).
Because often the hierarchy is used for organizationl purposes and not actually changing the data. For example, you might put buttons in a group simply to ensure they stay together (and then weight the group down so that form alters put their info in the right place). Fieldsets are accomplished using a specific #type but you don't usually want the fieldset to appear as part of the return data. Those are the two biggest examples I can think of.
On 12/30/2010 01:10 AM, Randy Fay wrote:
One thing you should make sure to check: Is ahah.js being loaded on the page? Just check with firebug. If it's not, you may have to load it explicitly.
It isn't being loaded. Why is that? If I click on an example from Examples, ahah.js is loaded, but doesn't appear to be done explicitly.
There must be something else fundamentally wrong. I put a drupal_add_js call in and now ahah.js is loaded, but none of the ahah-related field parameters appear in the jquery reference at the top of the page, so I'm surmising that whatever is not working in my code at this point with adding the #ahah to the field is also why ahah.js doesn't get loaded. Jeff
A defining moment. A quick recap, my objective was to use hook_form_alter to add ahah to a field in a content profile form. When I add a new field, ahah is loaded and the jquery code on the page contains the appropriate metadata regarding the field. When I add an #ahah key to an existing field, none of that happens. We've come full-circle, I think.
Almost there. I have the ahah appearing now by using #after_build. I guess from what I read that this had something to do with CCK fields (such as content profile fields) not cooperating with hook_form_alter due to timing. My (hopefully) last hurdle is probably just a need for another pair of eyes. When the change event fires and the throbber spins, I get a 404 error on the callback. function test_menu() { $items = array(); $items['test/change_value/callback'] = array( 'page callback' => 'test_change_callback', 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); return $items; } function test_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'test_profile_node_form') { $form['field_result']['#prefix'] = '<div id="field-result-wrapper">'; $form['field_result']['#suffix'] = '</div>'; $form['#after_build'][] = 'test_add_ahah'; } } function test_add_ahah($form, $form_state) { $ahah = array(); $ahah['edit-field-test-value'] = array( 'button' => false, 'effect' => 'none', 'event' => 'change', 'keypress' => NULL, 'method' => 'replace', 'progress' => array('type' => 'throbber'), 'selector' => '#edit-field-test-value', 'url' => 'test/change_value/callback', 'wrapper' => 'field-result-wrapper', ); drupal_add_js(array('ahah' => $ahah), 'setting'); return $form; } function test_callback_helper() { $form_state = array('storage' => NULL, 'submitted' => FALSE); $form_build_id = $_POST['form_build_id']; $form = form_get_cache($form_build_id, $form_state); $args = $form['#parameters']; $form_id = array_shift($args); $form_state['post'] = $form['#post'] = $_POST; $form_state['ahah_submission'] = TRUE; $form['#programmed'] = $form['#redirect'] = FALSE; drupal_process_form($form_id, $form, $form_state); $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id); return $form; } function test_change_callback() { $form = test_callback_helper(); $output= test_do_stuff(); drupal_json(array('status' => TRUE, 'data' => $output)); exit(); }
Jeff: Have you tried putting the url in the array through the url() function? That sounds like something to try. Possibly with the 'absolute' option set to True. On Dec 30, 2010 5:41 PM, <jeff@ayendesigns.com> wrote:
Almost there. I have the ahah appearing now by using #after_build. I guess from what I read that this had something to do with CCK fields (such as content profile fields) not cooperating with hook_form_alter due to timing.
My (hopefully) last hurdle is probably just a need for another pair of eyes. When the change event fires and the throbber spins, I get a 404 error on the callback.
function test_menu() { $items = array(); $items['test/change_value/callback'] = array( 'page callback' => 'test_change_callback', 'access callback' => TRUE, 'type' => MENU_CALLBACK, );
return $items; }
function test_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'test_profile_node_form') { $form['field_result']['#prefix'] = '<div id="field-result-wrapper">'; $form['field_result']['#suffix'] = '</div>';
$form['#after_build'][] = 'test_add_ahah'; } }
function test_add_ahah($form, $form_state) {
$ahah = array();
$ahah['edit-field-test-value'] = array( 'button' => false, 'effect' => 'none', 'event' => 'change', 'keypress' => NULL, 'method' => 'replace', 'progress' => array('type' => 'throbber'), 'selector' => '#edit-field-test-value', 'url' => 'test/change_value/callback', 'wrapper' => 'field-result-wrapper', ); drupal_add_js(array('ahah' => $ahah), 'setting');
return $form; }
function test_callback_helper() { $form_state = array('storage' => NULL, 'submitted' => FALSE); $form_build_id = $_POST['form_build_id']; $form = form_get_cache($form_build_id, $form_state); $args = $form['#parameters']; $form_id = array_shift($args); $form_state['post'] = $form['#post'] = $_POST; $form_state['ahah_submission'] = TRUE; $form['#programmed'] = $form['#redirect'] = FALSE; drupal_process_form($form_id, $form, $form_state); $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id); return $form; }
function test_change_callback() {
$form = test_callback_helper(); $output= test_do_stuff(); drupal_json(array('status' => TRUE, 'data' => $output)); exit(); }
John, same result...the actual module name is regions, and i'm receiving "An HTTP error 404 occurred. /regions/change_value/callback" Looks the same to me as every other module :) other than the complication of it being used by jquery. Doesn't need drupal_get_path or anything, does it? The jquery parameters all look the same as the working example, including the url format and what it relates back to. When I put in the absolute parameter in url() I get a 404 with http://mydomain.com/regions/change_value/callback On 12/30/2010 07:45 PM, John Fiala wrote:
Jeff: Have you tried putting the url in the array through the url() function? That sounds like something to try. Possibly with the 'absolute' option set to True.
A 404 means that the path you're trying to access doesn't work, as you've discovered. So you either need to rebuild the menu router (likely) or there's just something wrong with your hook_menu() entry or the function it calls. Most likely you need to rebuild the menu router. Use your browser to hit regions/change_value/callback. What do you get? If it's a 404 (which it will be, I think) then you don't have a working hook_menu() entry. -Randy On Thu, Dec 30, 2010 at 6:19 PM, <jeff@ayendesigns.com> wrote:
John, same result...the actual module name is regions, and i'm receiving "An HTTP error 404 occurred. /regions/change_value/callback"
Looks the same to me as every other module :) other than the complication of it being used by jquery. Doesn't need drupal_get_path or anything, does it? The jquery parameters all look the same as the working example, including the url format and what it relates back to.
When I put in the absolute parameter in url() I get a 404 with http://mydomain.com/regions/change_value/callback
On 12/30/2010 07:45 PM, John Fiala wrote:
Jeff: Have you tried putting the url in the array through the url()
function? That sounds like something to try. Possibly with the 'absolute' option set to True.
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
Of course...maybe if I cleared cache. Perfect ending to the year! Not completely clear at all on the ahah-cck issue, but hey, that it works is just fine! Thanks all. May we all byte and nibble more bits in the new year.
This AHAH-when-form-altering-CCK problem is quick common, and as you found, I don't think there's a good writeup on it. Could you post your experience with some sample code in the Examples issue queue? We can add it into the AHAH example, as it really is important. BTW: It all seems to work fine without problems in D7. -Randy On Thu, Dec 30, 2010 at 6:42 PM, <jeff@ayendesigns.com> wrote:
Of course...maybe if I cleared cache.
Perfect ending to the year! Not completely clear at all on the ahah-cck issue, but hey, that it works is just fine!
Thanks all. May we all byte and nibble more bits in the new year.
-- Randy Fay Drupal Module and Site Development randy@randyfay.com +1 970.462.7450
I'll start that now. I owe a write-up on a custom views field handler too, as soon as I get the last kink out of it. Jeff On 12/30/2010 09:15 PM, Randy Fay wrote:
This AHAH-when-form-altering-CCK problem is quick common, and as you found, I don't think there's a good writeup on it.
Could you post your experience with some sample code in the Examples issue queue? We can add it into the AHAH example, as it really is important.
BTW: It all seems to work fine without problems in D7.
-Randy
Jumped the gun a tiny bit. One remaining annoyance. In the Examples, because the module is creating the form rather than altering it, the function that creates the form can check for a form_state value from via ahah, which it then uses as a key to generate the options for the dependent select field. Because I'm altering the form, when I change the master select value it fires the callback that receives the $form data from the helper function just like in the Examples example. The problem is that the $form data being returned from that function doesn't seem to contain the form_state value resulting from the select box change. I could just alter the helper function to return both $form and $form_state, but wanted to check for another idea first. By the way, for anyone following the thread, when applying ahah to an existing form with cck fields, not only does ahah.js need to be loaded explicitly but also jquery.form.js. Jeff
participants (5)
-
Earl Miles -
jeff@ayendesigns.com -
John Fiala -
Pierre Rineau -
Randy Fay