AHAH done correctly
| Project: | Documentation |
| Component: | Correction/Clarification |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Hi,
I would like to attach a zip file containing two example modules to the Doing AHAH Correctly in Drupal 6 page (http://drupal.org/node/331941). It would be nice if I got a go from some documentation guru and a quick review of my code to make sure it's okay.
AHAH is a confusing topic and it took me the better part of a week to grasp the concepts behind it. The handbook page wasn't very helpful. If you browse through the comments, a lot of questions remain unanswered and some suggestions are downright wrong.
The package contains two modules that demo basic AHAH principles:
A. Button demo module
Demonstrates an implementation of AHAH based on a submit button.
B. Select demo module
Demonstrates an implementation of AHAH based on a select list.
Both modules contain comments which explain what happens through the process.
Package attached to this issue.
| Attachment | Size |
|---|---|
| ahah_example.zip | 14.69 KB |

#1
Great examples. I just have to ask you, do you know how to add those 2 select fields to existing form, in ahah_example_select_form_alter?
Cause when I do this:
<?php$form = array();
// Set the cache to true to create a $form_state cache on submit
$form['#cache'] = TRUE;
?>
I loose all data that have been already in $form.
#2
No time today, but will look at these ASAP. Subscribing to remind me to come back later. =)
#3
This code works fine with simple forms, but when you have some more fields or required fields some problems happen.
I have a form with 4 fields, 2 hierarquical selects and 2 required textfields (title and body). When the value of first select changes, the second select doesn't update, instead I receive a message to correct the required fields (title and body).
I think that some validations should not happen during AHAH callbacks. How could I disable this validations?
I remove the
theme('status_messages')from JSON return and when the form is posted I receive the unecessary messages.Sorry for my bad english :P
#4
Well, these are just two textbook examples that show the basic principles behind AHAH.
I suppose you're trying to add AHAH to a node form. Maybe you should check out this handbook page:
http://drupal.org/node/331941
Consider the AHAH cycle it describes. Between steps 4 and 5, you could alter the $form array and set #required on both the title and body fields to FALSE. Maybe that would make it work.
#5
I just manage to make it (2 select fields in form_alter) with ahah. I'm close to my deadline (with clients), but I'll give my best to post my solution in next week.
#6
I'm using the following code to remove the messages and CSS error styles before
drupal_jsonis called.form_set_error(NULL, '', TRUE); // remove CSS error stylesdrupal_get_messages(); // remove all messages
It works, but if I could skip validations instead of just hide them, would be nice :)
#7
I don't understand how the callback of
type_submitbutton is called on change event of thetypeselect.Please, anyone could explain?
#8
Reading "Forms API Quickstart Guide" in "Submitting Forms" I figured it out.
The data I was posting to my form was not valid (title and/or body required fields are empty) and the flow was not passing to the
type_submitsubmit function breaking the flow, and theanimals_kindselect wasn't updated.#9
netsensei,
setting the
#requiredattribute of required fields toFALSE, works very nice.I think that's a missing functionality to skip validations instead of doing this work in all fields that have some validation rule that can cause this effect, right?
#10
Asmdec,
It's not really a case of "missing" functionality here. AHAH functionality in Drupal provides you with several hooks where you should implement your own code. The problem is that it's not very well documented what you can and can't do.
Altering the #required attribute in the AHAH callback shouldn't pose a security risk (can someone confirm this?) because the data is just copied to the $form_state variable. It's used to repopulate the form when it's re-rendered with the changed elements.
If you would submit your entire form for further processing, you should be getting a validation error when a required field wasn't filled out.
oboskovic,
I saw your form topic but didn't have much time to give you an entire answer. Using form_alter in a seperate module to give existing fields the AHAH attribute would be my strategy too. I would then implement the required submit handlers and the AHAH call to make it all work in this module. You should pay attention to the naming of your functions and the callbacks. It's easy to make a mistake and AHAH is hard to debug.
I saw your comments on http://drupal.org/node/331941#comment-1503260. This code is using the 'wrong' way as Kat Bailey points out. It's changing the form directly in the AHAH call (mymodule_change_flower() function) and that's just, well, plain wrong. The callback is used to get the data into $form_state and call the submit handlers. Changes to the form happen in the mymodule_form rendering form itself. Or in form_alter in your case.
--
Colada | http://www.colada.be
#11
Netsensei,
I appreciate your help and understand your effort to better document AHAH for developers to know exactly what they're doing. Perhaps I don't use the right word when I say "missing" (bad english :), sorry.
I think that this "missing" functionality is (could be) in Form API, in
drupal_process_formmore exactly. It would receive some parameters that indicates that validation is not needed.Hierarquical selects (i.e.) don't need to validate the entire data of the form to populate one element. We're thinking only in #required validator, but we have many other validators that need to be disabled as well, like mail validator, user-defined validators, etc.
In the case of not valid data posted to form, could I call
form_execute_handlers('submit', $form, $form_state)after step #5 (drupal_process_form call)?Sorry if my ideas are confused, I'm learning AHAH these days and I don't have very deep knowledge so.
#12
I'm having another kind of bug now, the same as (not)discussed in http://drupal.org/node/371339.
1/ im creating a new node
2/ im using ahah to change a value
3/ i submit the form without filling mandatory fields
4/ so i have a new page telling me "missing fields..." and now with the new node form, the main form "action" is set to the ahah submit url
You know any about this??
#13
@asmdec, just do a drupal_get_messages() call after right at the end of your callback function and it will clear out any messages set during the node form validation that don't apply at this point. =)
#14
I make 2 files for everyone how needs 2 select fields (like country and city, or category and subcategory), in form_alter(). First file shows an ordinary , custom fields added in some content_type by form_alter function.
And second file shows how to change 2 cck fields into 2 select fields with ahah. More specific , it is a workaround for Hierarchical Select fields in some content type. I had to solve this problem fast, and this was the only solution after 10 days of research. It is not nice, but it works.
I made content type with 2 text fields called: field_category and field_subcategory. I made taxonomy Location, that has depth 2. (I mean it has Countries and Cities items). In form_alert function I made 2 dummy fields called: category and subcategory. They are select fields , and they are made with ahah, to replace Hiearachical select fields. I also didn't give any permission for cck fields, it means, admin is the only one who can see it.
The script works like this: you chose category, then ahah display subcategory for that category, and when you click on save/submit, you trigger JS that puts those values in corresponding cck fields field_category and field_subcategory. This way, drupal insert/edit/update all data by himself (you don't need to write code for that). That is all.
JS on the end of second file should be put in page.tpl.php.
I was in hurry so sorry if there are some minor mistakes.
#15
Well I spent an hour or so to fit the code from my select example in a CCK form with hook_form_alter.
I'm faced with the same issues:
* If a required field isn't filled, it complains.
* After an AHAH call, the form action is changed to something else and the data isn't saved in a new node.
I'm going to delve a bit deeper in this and see what I can do to make it work.
--
Colada | http://www.colada.be
#16
The
#actionattribute is altered by default form element information provided in hook_elements hook on system module:<?php$type['form'] = array('#method' => 'post', '#action' => request_uri());
?>
request_uriis returning the uri called via AHAH in this case. It happens indrupal_rebuild_formcall, wich callsdrupal_prepare_form, wich calls _element_info('form'), wich invokes the hook_elements hook and set the#actionas the uri requested by AHAH.I'm setting manually the
#actionattribute.<?php$form['#action'] = '/path/to/original/action';
?>
#17
Thx. You made my day.
#18
thanks,You are a star!
#19
The example code for select works for Firefox, but fails for IE6 and IE7. When the first select is chosen, the second select does not appear. Any ideas?
#20
I've noticed a couple things on my own implementation. Some have already been mentioned here.
In order to prevent issues with multiple validations (form validate works once, then the #action url is reset to the callback rather than the correct one, so the #action parameter needs to be manually set using:
<?php$form['#action'] = base_path() .'/path_to_your/page_callback';
?>
Rather than CSS'ing out the extra submit button, it is more appropriate to use #access = FALSE to avoid it rendering. The callback is still registered, and will be used during submission of the select element
<?php$form['theme_submit'] = array(
'#type' => 'submit',
'#value' => t('Select Theme'),
'#access'=> FALSE,
'#submit' => array('delta_add_override_select_theme_submit'),
);
?>
Also, regarding having the validation callbacks called when the AHAH element is submitted, I only found one clean option.
I've avoided using #required = TRUE, even on the fields I do require. What I have done also in my validate callback for the main form is to check to ensure the appropriate button was used for the callback, in most default cases the #id is edit-submit
<?phpfunction delta_add_override_validate($form, &$form_state) {
// only valid when we are truly submitting the form, not for AHAH
if ($form_state['clicked_button']['#id'] == 'edit-submit') {
$delta = $form_state['values']['delta_override'];
if (!$delta['name']) {
form_set_error('name', t('You must create a valid <strong>Override Title</strong> for this override.'));
}
if (!$delta['system_name']) {
form_set_error('system_name', t('You must create a valid <strong>System Name</strong> for this override.'));
}
if (!$delta['theme']) {
form_set_error('theme', t('You need to select a theme for this override to apply to.'));
}
}
}
?>
This really is a great piece of documentation. Needless to say the AHAH implementations are confusing at best, and this goes a little way further to a better understanding for myself personally.
I'll say it's not perfect, but it is a BIG step towards a more usable explanation. Thanks for the work!!
#21
My bad, accidentally reset title, changing back.