I've added a comment to the documentation for form_set_value with my findings from the last few hours. I though you might want the code example. I'll copy it at the end of this post so you can review more quickly, and merge in an example if you like. I think you may want to pay special attention to the forum post I linked. There's a lot of different keywords from search engines hitting it.
I hope I help someone with this.
Cheers, Lance!
______________________________
Having fought with this for a couple hours now, I thought I'd leave notes of what I found here.
Before I begin:
http://drupal.org/node/160160 is unclear, but is the top result after this page on search engines due to length. This page may need to be updated if the proper documentation can not be understood from this page.
When using drupal 6, this is the process you must use:
Optional
function hook_form(){
//... Previous Code
// You *can* (and should) declare a placeholder for the value to be inserted into later.
$form['placeholder'] = array(
'#type' => 'value'
,'#value' = > NULL // Placeholder value. Meaningless
);
//... Other Code
}
Required
Because the form_set_value function requires more arguments than standard hook_validate functions provide, you must use hook_form_alter to do custom validation for your form:
function hook_form_alter(&$form, $form_state, $form_id){
if ($form_id == '{node_type}_node_form') {
$form['#validate'][] = 'hook_validate_custom';
}
With the form set to validate through your new function, create it. Note that $form_state must be a reference.
hook_validate_custom($form, &$form_state){
// ... Validation Code
form_set_value( array('#parents' => array('array_key_parent', 'array_key_to_replace')) , $value, $form_state);
// ... Other Code
}
Sorry for the inline array.
Here's a breakdown of the three parameters you must pass in:
- An array with one item: '#parents'. '#parents' is another array. '#parents' should be the arrays keys needed to reach the form value you want to replace. For instance:
$first_parameter = array( '#parents' => array( 'first_key_in_path' ,'second_key_in_path' ,'key_to_replace' // Always the last one. *Will* create if it doesn't exist. ) );
- The value you want inserted.
- $form_state
Comment | File | Size | Author |
---|---|---|---|
#31 | documentation_form_set_value-570314-31.patch | 1.2 KB | Mac_Weber |
#30 | documentation_form_set_value-570314-30.patch | 1.12 KB | Mac_Weber |
#27 | documentation_form_set_value-570314-27.patch | 1.24 KB | Mac_Weber |
#16 | 570314new.patch | 1.02 KB | jhodgdon |
#9 | 570314update.patch | 1017 bytes | jhodgdon |
Comments
Comment #1
jhodgdonI took a look at this example... So I'm sorry, but I am unsure what you are trying to accomplish here, and which documentation you would like to see changed. Can you please explain?
a) What is your hook_form() implementation really doing? I don't see that being used anywhere else in your example.
b) The documenation on http://api.drupal.org/api/function/form_set_value already says:
It looks to me like it explains how to set $parents... what more is your example doing that needs to be explained better? Is it just that you think it should explain how to add a validation function using hook_form_alter? If so, that's probably a good idea.
Comment #2
jhodgdonAssuming that what is wanted is more detail added on how to define a validation function, here's a patch, which I think also explains better how/where to call form_set_value.
Patch is against Drupal 7. If accepted, should be back ported to Drupal 6.
I also recommend that the comment http://api.drupal.org/api/function/form_set_value#comment-49 be removed if this patch is committed (and maybe even if this patch isn't committed). (I don't have/want comment delete priveleges on api.drupal.org.)
Comment #4
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks.
Comment #5
sunWe should additionally clarify that form_set_value() _only_ sets the value in $form_state['values']. Not in $element['#value'].
And we should clarify *why* it is that way.
Comment #6
jhodgdonUmmm... I think the doc does imply that the value is stored in $form_state. I'm not sure it needs more clarification... sun, maybe you can propose a patch that would add the clarification you think is needed?
And as a note, we do need to port the above change (and any other changes in subsequent patches) to Drupal 6 once this is fixed in D7.
Comment #7
arhak CreditAttribution: arhak commentedwhile you are at it
why keeping
$element
being recursively passed in_form_set_value
while it isn't used at all?its current signature
should be
since $element is not needed in the helper function neither used, just passed through
Comment #8
arhak CreditAttribution: arhak commentedBTW, with "just passed through" I meant "to it self" (which is silly)
Comment #9
jhodgdonHere's an update patch that addresses #5 (clarifies further that values are only set in $form_state).
As far as #7 and #8 -- I think it is way too late in the development cycle to change how form_set_value() is called for Drupal 7. If you feel strongly about it, please file a new issue for Drupal 8 with your suggestion. It might be a pain to patch, though, because you'd also have to find all the spots in the core Drupal code that call this function and update them.
Comment #10
arhak CreditAttribution: arhak commented@#9 is a private function for internal use of form_set_value (to do the recursive dirty work)
Comment #11
jhodgdonI do not understand #10. ???
Comment #12
jhodgdonAh. I see what you are saying in #10: that only the internal recursive function _form_set_value() needs to be changed.
So yes, that is an OK idea. But please file it as a separate issue, and if possible, create a patch.
Comment #13
mr.baileysLooks good, just one minor thing:
The value is also persisted in $form_state through to any additional validation handlers if there are any left. Maybe this should just read "handlers" instead of "submission handlers"?
144 critical left. Go review some!
Comment #14
jhodgdonGood point.
Comment #15
jhodgdonActually, it says "through to the submission handlers", indicating it should persist and keep persisting up through the submission handlers, so I think it's OK?
Comment #16
jhodgdonOn second thought, I think your idea is good to include validation handlers in there. Here's some revised language.
Comment #18
mr.baileys#16: 570314new.patch queued for re-testing.
Comment #19
jhodgdon#16: 570314new.patch queued for re-testing.
Comment #20
jhodgdon#16: 570314new.patch queued for re-testing.
Comment #21
jhodgdon#16: 570314new.patch queued for re-testing.
Comment #22
jhodgdon#16: 570314new.patch queued for re-testing.
Comment #23
jhodgdonupdating, will click retest in a sec...
Comment #24
jhodgdon#16: 570314new.patch queued for re-testing.
Comment #26
jhodgdonNeeds a re-roll. Probably a good novice project?
Comment #27
Mac_Weber CreditAttribution: Mac_Weber commentedre-rolled patch #16
Comment #28
jhodgdonThanks for the patch re-roll! I wrote the original so I cannot mark it "reviewed". Anyone else?
Comment #29
sunLet's remove the parenthesis.
Also, I think the limitation to "during form validation" is not necessarily needed; technically it's also valid to use in submission handlers. However, we can also leave it as is...
It does not change the value in $element['#value'], only in $form_state['values'], which is where submitted values are always stored.
-16 days to next Drupal core point release.
Comment #30
Mac_Weber CreditAttribution: Mac_Weber commentedI put myself in the shoes of who might be reading it with no past knowledge (in fact, that's me). Then, I decided to get rid of "during form validation." to avoid misleading.
I feel I like learning about the API sending patches.
Comment #31
Mac_Weber CreditAttribution: Mac_Weber commentedwrong path sent in #30
sending the correct one
Comment #32
jhodgdonThis looks quite reasonable to me. Any comments sun?
Comment #33
sunThanks!
Comment #34
chx CreditAttribution: chx commentedLooks good.
Comment #35
webchickCommitted and pushed to 8.x and 7.x. Thanks!