content-type creation forms (hook_form) and ahah
fmosca - October 30, 2008 - 16:30
Description
i'm trying to adapt a form pretty much identical to the one in the example module to a node creation form for a custom content type defined by my module, and it doesn't seem to work. When the ahah callback is invoked the wrapper is emptied and with some error_logging i can see that the hook it's not invoked at all.
Is there any known incompatibility with hook_form's forms? can content creation forms be ahah/multistep at all? i see the signature is different but $form_state is supposed to be there, as from the api docs...

#1
I found this same problem. This is a problem triggered within the ahah_helper_register function, which looks for the file where the form definition lives, which, for a node add form, is node.pages.inc. Thus, nothing is returned to replace the wrapper div :-(
#2
Somebody from Belgium in IRC contacted me about this. Together we worked out a solution and he promised he'd post it within a week max. I guess he did not manage to get that done :(
I'll try to get a hold of him.
Just hang on, it *is* possible (*anything* is possible with FAPI :)).
#3
hi wim,
I'm experiencing the same issue...
I attach a bit of code as an example, in case it helps, the thing is three ahah linked selects that works perfectly in any other form, but not as part of a creation node one:
function activeselect2_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id && is_array($form['taxonomy'])) {
foreach ($form['taxonomy'] as $vid => $form_item) {
// Only apply Active Select if it's enabled for this vocabulary.
if (is_numeric($vid)) { //&& variable_get('taxonomy_override_selector', 0)) {
unset($form['taxonomy'][$vid]);
//activeselect2_form3($form, $form_state, $vid);
//$form['as_taxonomy']['#weight'] = -5;
/**/
ahah_helper_register($form, $form_state);
$form['uno'] = array(
'#tree' => TRUE,
'#weight' => -5,
'#type' => 'fieldset',
'#title' => t('Categorias'),
'#prefix' => '<div id="as_taxonomy_wrapper">', // This is our wrapper div.
'#suffix' => '</div>',
);
$form['uno']['select'] = array(
'#type' => 'select',
'#options' => array('uno', 'dos'=>'dos', 'tres'),
'#ahah' => array(
'event' => 'change',
'path' => ahah_helper_path(array('uno')),
'wrapper' => 'as_taxonomy_wrapper',
),
);
if ($form_state['values']['uno']['select']=='dos') {//
$form['uno']['select2'] = array(
'#type' => 'select',
'#options' => array('uno', 'dos'=>'dos', 'tres'),
'#ahah' => array(
'event' => 'change',
'path' => ahah_helper_path(array('uno')),
'wrapper' => 'as_taxonomy_wrapper',
),
);
}
if ($form_state['values']['uno']['select2']=='dos') {
$form['uno']['select3'] = array(
'#type' => 'select',
'#options' => array('uno', 'tres'),
'#ahah' => array(
'event' => 'change',
'path' => ahah_helper_path(array('uno')),
'wrapper' => 'as_taxonomy_wrapper',
),
);
}
}
}
}
}
by the way, thank you for your great work
Greetings,
Juan Arias
Spain
#4
Ok, I'm now doubting about if it's the same problem or not...
the case is that the above form definition doesnt work as part of node/add form, but yes as standalone form, but the behaviour is that second select has no "ahah" behaviour associated...
if someone gives me some "light" I could try to work out some solution.
Thx
Juan Arias
Spain
#5
hey guys,
Problem1: placing the ahah_helper_register function
The problems you're having is due to the fact that you call ahah_helper_register in de hook_form (or not at all!) . The sollution is to do this in the form alter, for example like this :
if(isset($form_state['post'] )) {ahah_helper_register($form, $form_state);
}
This way you will only register the form once.
Problem2: Staying on the node form page iso the view page.
But then a new problem occurs. Normal node form submissions go to the view page. You will need to do that as well. But I have not figured out were to do this redirect. Ahah_helper lets you stay on the same page, logic behaviour because ahah calls are at the same page.
Problem3: Losing taxonomy and initial fields values in form_state.
A bigger problem is , that saving the form twice ... node fields filled in the first time, get lost. I dont know yet why this is happening.
I tried dozens of ways to make sure that the ahah_helper_register does NOT get called on the "END SUBMISSION" of the form. The problem here is that ahah helper retrieves a cached version of the form (and loses the last saved values) ... . The module is super handy but we really need to figure this out. I needed a quick way (for the client and i worked with the post values on save.
Sollutions
- make a call to ahah_helper_register
- Use hook_form_submit/ hook_form_validate / hook_form_alter to do the redirection.
@WimLeers : sorry that i haven't had the time to look any further for this. I am working on the heartbeat module right now, but the project where i needed the ahah_helper calls will come again at the end of this month. The promised test case is almost finished. I will work on this , promised.
#6
Hi stalski,
I tested the problem 1 solution and it didn't worked...
I refactored the code as if it can help...
I attached a test module showing this issue: the aim would be:
-> previously you have to set up a vocabulary and associate to one node type (for example story)
-> setting chained selects showing up via ahah. (if value = two)
-> as you can see: using the code via menu link works perfectly, selects expand on change to "two" value.
-> but if you try to create a node "story", in the replacement of the taxonomy selector only the first select has "ahah behaviour", the second one is a "normal" select
I'm research something with the info provided by stalski
Greetings
Juan Arias
Spain
#7
Update of the case:
following the thing, I have noticed that the code responsible of the strange things is:
node.pages.inc: 134if ($extra = node_invoke($node, 'form', $form_state)) {
//unset($extra['body_field']['teaser_js']);
//print_r($extra);
$form = array_merge_recursive($form, $extra);
}
if you uncomment the unset... everything works ok in the previous example...
what we're disabling is:
[teaser_js] => Array(
[#type] => textarea
[#rows] => 10
[#teaser] => edit-body
[#teaser_checkbox] => edit-teaser-include
[#disabled] => 1
)
I'll keep on this and tell you something if I find out...
Greetings,
Juan Arias
Spain
#8
Ok, the question I have right now is: is there an incompatibility with "split teaser by js" utility in core and ahah helper???
What do you think?
Greetings,
Juan Arias
Spain
#9
Stalski: could you please post the sample code that you were working on back then, so we can go on from there? And: no problem for not finishing that yet. We're all very busy :)
Hwangar: thanks for also jumping into this. I'll try to give you some feedback on the test code that you've posted when I find the time (which might take a couple of days in the best case).
#10
Thanks to you Wim,
ok, I located the error (in the teaser management), and I managed to sacrify that functionality for this one, this is how I did it:
function ahah_helper_render($form_item_to_render = FALSE) {
(...)
unset($form['body_field']['teaser_js']); // Workaround for ahah_helper in node-form's (deactivates the teaser js management)
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . drupal_render($form_item),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
after this, my upper example works ok...
Wim: I want to make a replacement for taxonomy selector for hierarchical large vocabularies, more or less in the way of your Hierarchical Select, but taking advantage of the ahah functionality in D6... I'll post the code when it's more or less ready
Greetings,
Juan Arias
Spain
#11
@Wim: ok, fine.
@Hwangar: Good job, at least that problem is tackled (didn't notice that one actually). I am starting to think that taxonomy comes into play because that was one of the values i kept loosing after a situation like :
ajax1, ajax2 , submit (stays on the same page) , submit (ERROR, required fields , meaning, where are my values ??)
I will look into this but maybe not in the first two days.
Greetz
Stalski!
#12
Hwangar: you cannot take advantage of AHAH in D6. AHAH in D6 requires $form['#cache'] to be enabled. Some forms, notably the Views exposed filters form, don't support this (i.e. they require $form['#cache'] to be FALSE). If you're only working in node forms, then you should be safe of course.
Secondly, if you want HS for D6 but can live without the UI, you can use it already. It works. See the latest .zip in the D6 port issue of HS.
#13
I made some time to look into this. The problem is indeed teaser.js. Not because there's some sort of incompatibility, but because teaser.js has a bug:
Undefined valuehttp://localhost/d6/misc/teaser.js?O (line 74)
(This happened both in Safari 3 and Firefox 3.)
And for some unknown reason (probably somebody with thorough JS/browser knowledge can explain this), this prevents other things from working, amongst which AHAH callbacks. Simply fixing teaser.js does the trick for me.
I created a new issue for it, along with a patch in the Drupal core issue queue: http://drupal.org/node/336517.
Please confirm that this fixes all issues.
P.S.:
Stalski: that check for $form_state['post'] is useless: it makes your code less legible, calling ahah_helper_register() doesn't do any harm, it already prevents problems because of multiple calls by itself.
Hwangar: your wrapper div is *very* badly named. "wrapper" is also used by themes (it completely messes up Garland for example) and is too generic no matter how you look at it. Try to be more specific.
#14
Hey Wim,
About the post, you are correct. (you cannot image what i tried :p )
About that other problem, I never had that perticular problem.
I took some time as well and created that node demo for you as promised. It is in the attachment.
I added a lot of information about what you see or could try with it to handle it from there. You will find this in the .module file on top.
I hope it is all clear to you what is going on.
You can just put the module in the ahah_helper folder, i did it like that and try it out. I even think after the bug is gone, this could help people using the module as it lowers the step to the implementation of it.
Greetz,
Stalski
#15
Besides,
in my opinion, the taxonomy issue of Hwangar is too different from this one (is not a node form). Maybe best to split this into two. Better to follow-up
Stalski
#16
Stalski, thanks! :)
I briefly looked at your code and noticed that you, like ppblauw in another issue, are abusing #default_value (i.e. using it in ways that are completely senseless). That makes two of you and then it's no longer a coincidence. So I looked at my demo code and yes, there was the same problem. I just fixed that and even extended my demo a bit, in such a way that you can understand why those #default_values were there in the first place.
Please see the diff of this commit http://drupal.org/cvs?commit=154002. It'd be great if you could update your example accordingly :) I'll do a more thorough review soon.
#17
I don't understand what you mean. Take a look at the node_example module for drupal6. That is the one i extended, so default values are used correctly with the node values / or form_state values.
Could you explain what you mean exactly because i think that has nothing to do with the problem, no? To build the form without default values will not work for the node demo because .... euh there are no default values and that is really needed (loaded from the database OR in changed form_state after submitting it)
Thx for looking into this. For the moment I am not using the module anymore for known reasons, but i will use it as soon as values are retrieved and saved correctly.
Stalski
#18
@Wim (#13) Sorry, this doesn't fix the problem on node/add/node_type form. I wasn't having the js error message because I tried this module on a new node type I've created with no body. Still, I patched the teaser.js file but I cannot use the ahah helper on a node add form anyway. However, I 'moved' the node creation form for my node outside the node add workflow and it works ok.
#19
subscribe
#20
It's got absolutely nothing to do with the problem. It's just code style criticism.
Could you please post your code? You can contact me in private it it's not for the public to see.
#21
Wim, I will update the node demo as well pretty much the same way as you did the helper demo. I now understand what you mean. Tests will tell if it fixes one of the issues I described in the file description of ahah_helper_nodedemo.module.
I will keep you informed. You do the same? Thuesday i amm planned on the project again where i used it. Hopefully till then the problem is solved :)
grtz
#22
I didn't read through all the comments so my apologies if this is covered or explained. I was having a similar problem as described above. I updated a (cck) content type form in form_alter and added some ahah code with ahah_helper. I used the ahah_helper_register function and it was causing problems with my taxonomy terms and ahah fields added by other cck fields.
I have a workaround which was simply to copy the ahah_helper_register function to my own copy and I removed the menu item registration code completely. Now it works for me and it still works for another non-content-type form where I'm using ahah_helper as well. I don't know why but I'm happy that it works!
My new function:
function my_ahah_helper_regsiter(&$form, &$form_state) {
$form['cache'] = true;
drupal_add_js(drupal_get_path('module', 'ahah_helper') . '/ahah_helper.js', 'footer');
}
Perhaps someone has already explained that menu item file registration stuff and understands why this is working without it.
#23
Well, I spoke too soon. If I edit the old content, it works fine but when I create a new node, it doesn't work. If I use the original ahah_helper_register for new nodes, then it partially works... it saves the cck fields but doesn't save the node body (and perhaps other things) and doesn't redirect to the node view page... I'll have to figure out a workaround for this because this functionality is needed.
#24
I went through the comments above and tried various "solutions" but nothing worked. Issues:
1) body text isn't saved (I tried the teaser.js patch)
2) taxonomy fields don't get pre-populated correctly (if the storage #file is set)
3) auto-complete (cck) text field is getting pre-populated with incorrect information (if the storage #file is set)
I tried replacing the buttons submit function with my own which called node_form_submit and redirected to the node/[nid] page. This works but the node body goes missing and I'm not sure it's anywhere in the form data (I looked but didn't see it in $form or $form_state).
I thought that the ahah stuff was working when I editing existing content but actually it is buggy. It sometimes (?) is only keep the previous state data. I'm too tired to try to reproduce well enough to document right now.
It's a shame because I really need this functionality on my content edit form. Someone else said they created their own version of the node add/edit pages... I'm not sure how to do this while still keeping the same URLs... (hijack the url to go to your own form page)... I have some vague recollection that this can be done.
Any chance someone is going to get this to work in the very near future?
#25
Please update to version 2 and check if this problem persists.
#26
Hello Wim:
I'm still having problems using the ahah_helper on {type}_node_form forms in drupal 6.9 with ahah_helper 6.x-2.0
I receive the following error when using the example module at http://drupal.org/node/328201#comment-1116930:
#27
@jbomb: Have you tried to apply the patch provided in #380312: Only AHAH javasript settings are send back to ahah_helper. Especially fixing the required_once statement might resolve your problem.
I am on drupal-6.10 where the provided ahah_helper_nodedemo seems to work. More information about the error 500 (like error messages) might help, to find the error if it is still present after the patch.
#28
@frenkx thanks I'll give it a shot and report back.
#29
I have successfully used 6.x-2.0 for a non content type form. When I use it for a content type form on a field I have added through form_alter (rather than an existing field - haven't tried that yet), then it will update the page but it also appears to be submitting the form because I'm seeing the validation errors for the missing required fields. I'm assuming that either I have things set up incorrectly or this is a bug.
---
I also just noticed that the node reference fields are still getting messed up. When I load the page, they have in them:
[nid: Array]
when they should be blank.
#30
@kepol: Is your setup according to the structure in the demo module provided in #328201-14: content-type creation forms (hook_form) and ahah? Especially the part about calling ahah_helper_register() in hook_form_alter() only after validating $form_id seems to be important.
I had a similar problem coming from a non content type form to a content type form - but changed a lot at the same time, so this is more or less a wild guess. If this does not solve your problem, please report back...
#31
Yes, I am only calling ahah_helper_register for the correct form_id. Perhaps the issue of the nodereference textfields showing [nid: Array] can shed some light on the problem. I don't know enough about ahah/ajax to debug this.
#32
I'm not sure if I should post this here, or create a different issue, since my problem also relates to "content-type creation forms (hook_form) and ahah".
What I'm trying to do is to change the #title of a form element (a drop-down list) in a CCK node add form when a specific button (added in hook_form_alter) is clicked (this is a "hello world" example - once I've done this my actual use case - to repopulate a select list based on a chosen date range - is trivial).
In the ahah_helper_demo module, all form elements belong to the billing_info fieldset, and after the 'usage' select list is changed, ahah_helper_render rebuilds the form, then allows ahah_helper_demo_form() to modify it, then asks drupal_json to render the whole fieldset. But what if instead of rendering the whole fieldset again, I only need a single form element to be rendered?
Since my use case means I need to modify form elements directly they can't belong to a fieldset. So in the demo example, I moved all form elements out of the fieldset, like this:
$form['billing_info']['usage']became$form['usage'].Then I changed the demo example to simply change the title of the 'usage' select list whenever "private" is selected, by changing
'path' => ahah_helper_path(array('billing_info')),to
'path' => ahah_helper_path(array('usage')),on line 98 of ahah_helper_demo.moduleIt was my hope that by changing the value in the select list from 'company' to 'private', the title of the list would then change from "Usage" to "Hello world". What actually happens is that the field_billing fieldset (which now has no elements in it, but is still rendered) is replaced by a NEW field_usage select list, which has "hello world" as a title.
Is my logic correct i.e. can AHAH helper change the title of an individual element that doesn't belong to a fieldset, in the context of a CCK node add form? If so, was I correct to pass as an argument to ahah_helper_path array('usage') instead of array('billing_info')?
#33
I sorted this problem out here: http://drupal.org/node/331941#comment-1503260
#34
Hi
I've tried following the examples in ahah_helper_demo.module, but am experiencing the following problem, which I think is the same as others in this thread:
I have a module which will create multiple content-types, thus .module contains hooks as such:
but
I am also attempting to do multi-step forms AND AHAH.
The form at /node/add/child appears ok at first;
When I change the select field which should trigger the AHAH, the contents of its fieldset disappear, and this error message appears:
I have set #cache in modulename_form_alter: this is the correct name for the hook, as it sets the buttons for multi-step correctly.
ahah_helper_register has to be called in child_form, otherwise the whole form appears blank in its initial state.
#35
I've tried this demo node module #328201-14: content-type creation forms (hook_form) and ahah. But it returns errors (same as my own module):
Alert
An error occurred.
/server/ahah_helper/billing_info
<br />
<b>Fatal error</b>: require_once() [<a href='function.require'>function.require</a>]: Failed opening required '' (include_path='.;C:\php5\pear') in <b>C:\wamp\www\server\sites\all\modules\ahah_helper\ahah_helper.module</b> on line <b>145</b><br />
Warning
warning: require_once() [function.require-once]: Filename cannot be empty in C:\wamp\www\server\sites\all\modules\ahah_helper\ahah_helper.module on line 145.
Cheers.
#36
I had the same error message as the two previous posts. The problem was in this code in ahah_helper.module on lines 144-146
<?phpif (isset($form_state['storage']['#ahah_helper']['file'])) {
require_once($form_state['storage']['#ahah_helper']['#file']);
}
?>
As you can see, it checks for the existence of ['file'], but tries to include ['#file'], which obviously doesn't exist. By removing the '#' it started working.
I hope that it helps.
#37
Not sure if this is right place to post this...
This is rather rare use case and involves a bunch of other modules, but maybe someone will find it useful...
I am using AHAH helper on node form (converting Location module's provinces auto complete field into dynamically populated select field - based on the country selected). Due to the nature of Location module (or my understanding of it) I had to add AHAH tweaks not at form level, but at location element level (in it's process function to be exact). So, it works fine with standard AHAH helper setup when it's called from standard Drupal node/add/TYPE url.
However, when I placed the node add form to my custom page (I need it to be iframed on other site), I got the "warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'node_form' ..." error when testing select field AHAH functionality. As it was described many times already, that means that node.pages.inc wasn't included at some point. Since it was added in my custom page callback, that meant that it was needed to be called once again at some step of AHAH processing that AHAH helper module involves. So my solution was to add this include into AHAH helper's main callback (ahah_helper_render()) checking for form_id from the $_POST - than embeddable (iframed) node form AHAH features worked fine.
Probably, it's worth to consider to rewrite the ahah_helper_render() function so it checks if node form is being processed and includes the needed file (node.pages.inc) automatically?