By kabaman on
im trying since hours to get form_set_value() to run
but it throws always the same error
"warning: array_shift() [function.array-shift]: The argument should be an array in ...\includes\form.inc on line 849."
i also tried it with one dimensional arrays
actualy i need it for changing checkboxes after validation
<?php
// in hook_form
$form['demo']['test'] = array(
'#type' => 'textfield',
'#title' => t('test'),
'#default_value' => $node->test,
'#size' => 60,
'#maxlength' => 128,
'#required' => FALSE,
);
$form['demo']['valid_test'] = array(
'#type' => 'value',
'#value' => array()
);
// in hook_validate
form_set_value($form['demo']['valid_test'], $my_data);
?>
thanks in advance for any help
Comments
You have not set #parents in
You have not set #parents in $form['demo']['valid_test'], as mentioned in the documentation of form_set_value().
- Corey
Same Issue
I'm having the same problem. The API page differs from what's written in my Pro Drupal Development book, which doesn't say anything about #parents.
I've followed their example as closely as I can and I have the same problem you do.
If you figure it out please post the answer.
Thanks,
Nick
...
Post the relevant sections of your code if you want help. (The original poster didn't post enough of his code.)
You don't need to use #parents.
well it was an question in
well it was an question in general
i change now my form-values directly in hook_insert and hook_update
(actions like trim($value) or getting rid of strange values from drupal checkboxes)
yes. there is nothing about form_set_value() and #parents in the "Pro Drupal Development" book
thanks for answering
...
I see.
Well, the answer in general is:
You have an error somewhere.
:-(
You should have posted your hook_validate function. At least the parameters it gets.
Here's the code from the Pro book
Page 163:
In the form definition function:
and in the validation routine (which I took to mean in hook_validate):
and you can then access your data in the validation function:
There's nothing in the book about #parents.
No joy, no matter what. That would be the "error, somewhere."
See also this tip: http://drupal.org/node/51104
No mention of parents, but I can't get it to work either.
http://www.universalpantograph.com
Make sure the field names match up
I was just banging my head up against this problem too. Turned out that the name of the field in the form was misspelled and so didn't match the name of the field in the form I was trying to form_set_value to.
Not the most useful advice, but something to check: that array_shift error obviously isn't very informative as to what exactly the issue is.
Perhaps The Solution You Were Looking For
I ran into the same issue while working on a current project. After discussing said issue with CHX he relayed similar information as found in Drupal API documentation. Later I spoke with Merlinofchaos who gave the impression of a broken hook_validate. Merlin also provided me with a solution. So without further ado...
The Solution
If working with a node form you will want to create a custom validation function implemented by using hook_form_alter to add a custom #validate property.
Define your custom validation function.
While you could just define your custom validation function in _form the same way as we did in _form_alter, doing so would bypass the current node_validate function rendering any standard node validation useless and still wouldn't solve the error stated in this node. We don't usually want that so we use the hackish _form_alter so that both validation functions work as intended.
After completing this small task you can now use your modules custom validation function to perform the necessary changes and validation that you normally couldn't do including form_set_value. Now form_set_value should work properly and when you go on to your additional hooks like _submit, _insert, _update and perform a
print_r($node)you should see the desired changes. And no more dirty error!I hope this helps all the people I saw asking this very question. If this doesn't solve your problems with the related issue please lets get talking and I will do my best to help pass the solution in a well documented fashion.
Peace,
-mpare
www.paretech.com
Did you figure out how to do something? Did you find documentation on Drupal.org inadequate? Well now it's your turn. Document your Success!
This doesn't work for me
Using the Forms API and a #validate function with form_set_value does not work for me to change node form data.
For example, if I wanted to change all my node titles to Harry Potter; so I set up a validate function as outlined above and do a form form_set_value($form['title], 'Harry Potter');
I can throw a print_r($form_values) in there and see that $form_values['title'] has been changed but $node->title does not get changed.
I have come to the opposite conclusion, to use the node api and node hooks when dealing with nodes and leave these custom validation and submission functions to forms that do not involve nodes. I have not read the code, but I suspect since the $node hooks predate the form api, that the node hooks are a special case and do not follow the same rules.
I am just offering this as a counter-point to anyone else who burns several hours trying to write a custom #validate and #submit function for a node that uses form_change_values(): you probably should try to use hook_nodeapi first.
Clarification using hook_form, hook_validate
If you want to change node data in a hook function when $node is one of the arguments, be sure to have the & ampersand sign in front of the $node:
hook_validate(&$node)
Then just change the field in $node and they will change the original $node data.
Note that this doesn't work with the form api validate function with $form_values: that is why you need to use form_set_value() when you're not using node hooks.
Correction
Ok, I was just reading the documentation for hook_validate and noticed:
I guess this is where the whole issue originated from.
I was using the nodeapi which works fine for changing $node data. If you wanted to validate for a specific node type, (which is basically what I was doing; writing some helper code for a content_type made with CCK) I would start with something like this:
doesn't work for me
Is this in Drupal 5? I'm using 5.2, and I can't get any of these methods to work.
I've got two fields that I want to auto-generate if they are submitted empty.
one of the is a tag, the other is a url alias for the path module.
first i tried using form_set_value in the validate branch of hook_nodeapi. no dice.
i can prove that the validate code is being run, and it's calling form_set_value,
but it doesn't result in any updates. this is particularly weird because i'm using it the
exact same way that the auto_nodetitle module uses it.
then i tried the recipe above, with form_alter and a custom validation routine. no dice.
i tried modifying the node directly in hook_nodeapi as well. i can see that the
values get set, but the form doesn't seem to pick it up. i'm not sure what
would happen if i actually submitted -- maybe it would get stored right -- but
i need the user to see in the preview that things are working.
very weird and frustrating.
Here's the solution
I just fought with this problem myself while following along pg 163 in Pro Drupal Dev.
The solution is to ensure that your validate function has $form as the 3rd argument. ie:
hook_nodeapi docs explain this
Correct, the reason is explained in the docs at http://api.drupal.org/api/function/hook_nodeapi/5
The third parameter, $a3 in the docs (it's a parameter, doesn't matter what you call it)
So here is an example where, even though I know I am being a naughty boy changing values in validate, I need to do it in validate precisely to gain access to the form values (unavailable in $a3 in submit op). I need it to keep a field #disabled (it is updated via javascript, so I don't want people touching it, so I made it #disabled in form_alter; but being disabled, its value is stripped, so I need to put it back in):
Here there are two hidden fields holding the data (do a print_r of $a3 to find out where your stuff is), and I just shove them into the appropriate "#parent" (which is simply the lowest level array which is going to end up holding your value).
Victor Kane
http://awebfactory.com.ar
Victor Kane
http://awebfactory.com
Altering Field Content During Validation?
Hi victorkane,
Your example shows (I think) what I am trying to do, but it's not working here. We're on Drupal 5.1 with CCK. I created a content type with several fields that are to be derived from another.
I know there is computed fields module, but that doesn't fit the needs here.
Anyhow, so I create a module and in the nodeapi hook try something like this:
Following your lead I would have thought this should change the node title when one enters this and hits Preview, but it doesn't.
Anyone know what is going wrong here?
FWIW, I dumped the
$a3variable and it seems to repeat the fields many, many times. Why is that? It's like a needle in a haystack finding which field to modify.I know we could just change the fields on view, but that seems silly. Also, will not allow them to be used in views.
Thanks for any help. :)
Use hook form_alter
Ahhhh... in rummaging around this site I came across a suggestion to use the form_alter hook.
And indeed, this does the trick:
Hope this is helpful to someone!
Altering form values in validate, not seen in form_alter
I'm losing my mind. I've read tons of posts on multistep forms and on altering data in the validate function.
The design:
* multistep form
* node content type created in CCK
* using form_alter to hide/add/alter fields
* use custom validate and submit functions
The problem:
* if there are no errors, the concept is fine (step from one step to next)
* if there are validation errors, I'm trying to figure out a way to *communicate* that fact to the form_alter function so that the *step* stays the same instead of incrementing
* I think I'm going to have trouble having a "back" button too (since I want to save first) - I will need to know I'm going backwards instead of forwards
I have tried:
1) in validate, set $_SESSION variable... this isn't available when needed (though if you submit again) it does show up
2) in form_alter, add a placeholder form field; and in the validate function, pass in the $form as 3rd param and use form_set_value for the placeholder... the placeholder is empty when I get back to the form_alter function after submitting
3) in form_alter, check the drupal_get_messages to see if anything is there (says it's empty even though there are messages)
Any ideas?????????? I'm about to give up on the whole thing and just build my form from scratch instead of doing form_alter but maybe I will have the same issue there.
Thanks,
Kristen
-Kristen
Profile: https://www.linkedin.com/in/kristenpol
Drupal 7 Multilingual Sites: http://kristen.org/book
OK, here's how it works
Let's say you want to update a value called wibble in anyform_form() where you created this field:
Now the problem is that every example you read tells you to use form_set_value() you have to have this in anyform_form:
This is wrong. Even the book "Pro Drupal Development" says this and it's wrong. Some people use '#parents' to explain, but they never really explain, and this is why:
1) Your $form array is not available in hook_validate, so that's the first area of confusion. (And they always use $form.)
2) You do not use $form['wibble'] -- this is wrong and this is why it never works.
The people who mention '#parents' are on the right track. What you do with '#parents' is use it to identify where in the $form_values structure you want to put the value.
The first parameter for the example above can be created like this:
And then the second parameter is just the value you want to put in.
And that will work.
Let's say you had something nested deep in the form_values (and used '#tree=true') and you'd do it like this:
Obviously level0..2 above would be replaced by the actual names of the array elements. Notice that the name of the '#parents' array is completely irrelevant.
As a final note, you don't need to have created the field in '$form' at the top at all if you didn't want to -- the form_set_value() still works, but it's good practice to do it.
I hope that really helps.
Steve
Thanks Steve, this is a good
Thanks Steve, this is a good solution because it also works when you are just validating part of a form, ie. if the #validate key is set on only one form element, or multiple elements as in a fieldset, rather than the whole form.
However, it's not correct to say that $form is not available in hook_validate. It *is* available but only if you use an appropriate signature for your hook_validate function (as rcourtna explains above):
fair enough, but how many
fair enough, but how many references show that you can get $form ... yours is the first that I've ever seen that suggest it. Which makes my diatribe slightly redundant.
Nested & #tree=TRUE
Since this topic was great help for me, I would like to share the following that took some time to figure out. I think the Drupal 5 API doc says it all, or at least it does so looking afterwards... http://api.drupal.org/api/function/form_set_value/5
Ok, so if I'm having form structure like [level_0][level_1]...[level_n], and I would like to set the value in 'level_n', then I need to set the
$form['#parents'] = array('level_0', 'level_1', ... 'level_n')in order to set the value $form_values[level_0][level_1]...[level_n]. And that did the trick. The $form['#parents'] is an array pointing the path to where set the value in the form structure.
thanks Steve, this is the
thanks Steve, this is the best documentation i have found yet on how to use form_set_value. nice work!
cheers
Fish
This is what worked for me.
This is what worked for me.
First in the hook_form make sure you define a value placeholder.
Example:
$form['timestamps_placeholder'] = array(
'#type' => 'value',
'#value' => 1 //1 is just a stub. It doesn't mean anything.
);
Secondly ensure that you are passing in the $form parameter in the hook_validate signature
function event_validate($node, $form) {
//Some Code
form_set_value($form['timestamps_placeholder'], $timestampArray);
}
It actually has 2 parameters as per http://api.drupal.org/api/function/hook_validate/6
Thirdly you have to actually insert the new value within the validate hook. e.g:
form_set_value($form['timestamps_placeholder'], $timestampArray);
Lastly you can now access the new value. You do it like:
$date_timestamps = $node->timestamps_placeholder;
-----------
Currently working on Starcraft 2 Center
Not working
This is not working for me, I just did the way you said but when I try to access my node from hook_insert or hook_validate it is still returning the default value, in your case 1. This is something extremely frustrating, I just got it to work bypassing the form using some global variables, but that is not the right way! Dose anybody have a solution for drupal 6?
The function signature for
The function signature for hook_validate is actually:
function hook_validate($node, &$form)
If you need to make changes to values in $form, you must include the ampersand (&) before $form. Otherwise you are modifying a copy of $form and not $form itself:
http://www.php.net/language.references.pass
Already did that
Already did that, but that doesn't help me at all. It seems like drupal 6 is not taking in consideration the changes made to $form array. All I want is to alter the node object in the validation hook and have it's values in the insert and update hook, it's that too much I'm asking? Thanks!
Have you tried a
Have you tried a drupal_set_message($form) in your hook_validate (or however you choose to debug) to make sure the structure of the $form array is what you are expecting before you set the element? form_set_value is very fussy about specifying the relevant element's parents correctly.
Just a general observation with regard to the solutions offered above (referring to Drupal 6 only here) - if you are just modifying an existing value in the array, and not creating a new branch of an existing array tree, why would you bother using form_set_value over just setting the element directly with :
$form['element'] = $value;
It seems that unlike Drupal 5, form_set_value isn't referencing any global variables in Drupal 6.
Can anyone explain to me what special mojo form_set_value does (apart from making nested parent arrays if necessary) in Drupal 6 that would make it superior to just setting the array element with standard array notation?
Well, form_set_value dose
Well, form_set_value dose just that, there are 2 simple functions, one which is called recursively so no big deal about it. What I just realized is that there are differences between hook_validate and my_form_validate, these two validation functions have different parameters passed to them.
So it is very clear that form_set_value works only for my_form_validate (custom form, not the node module form) because my_form_validate has the $form_state parameter passed by reference.
But, the question still remains: how can I pass some values to the node object from the hook_validate function in drupal 6.x? I have the form array passed by reference in the hook_validate but any changes made to this array doesn't reflect a thing in the node object. If I'll not find an answer to this thing, I will do a complete debug and see exactly what drupal dose behind the scenes.
I had this problem also - here is how I got it to work
Hey all - I also had issues with form_set_value in the validate hook (using Drupal 5). In my case I was doing this because I had a CCK content type with a field that I wanted to hide on the create / edit node form but fill in with a calculated value before save. For me the problem was I wasn't formatting the value I wanted to use for my form element in the Drupal Forms way. For example, if my CCK field is a textfield called 'calculated_data', then in the hook_form_alter I did:
and
One other small note - the $form_values array will not have the updated value immediately after calling form_set_value, but it will be correct when the submit hook is called.
Hope this helps,
Dylan
Form_alter does work me
I created a new module name customizedlogin i want to append extra characted to username field after the user has submiited .
i am trying to do as following
function customizedlogin_form_alter(&$form, $form_state, $form_id){
form_set_value($form['name'], $replacement_value);
}
i am not getting wot is expected
printing of $form is giving me an empty array.Any Clues ?
Best Regards,
You don't need
You don't need form_set_value() in hook_form_alter() because you have $form there to change - that's why it's got the '&' in front of it. It's for the _validate() function.
I've added a comment for
If got here from a search engine looking for Drupal 6 info...
I've added a comment for Drupal 6's form_set_value documentation. http://api.drupal.org/api/function/form_set_value/6
I believe the problem most people have been having will be solved reading it.
Short version:
Use form_alter to add validate_custom to get: &$form_state.
Pass in 3 paramaters:
I came across use of
I came across the use of hook_form_alter() for a solution to problems with form_set_value() at the documentation for form_set_value() which makes no sense to me so I added a comment (http://api.drupal.org/api/function/form_set_value/6#comment-220) with an example showing what I think people are missing.
It threw me for a loop too for a while as it is not really all that intuitive and it took some digging to figure out.
--
Reg | www.AceWebGroup.com
HELP
I am having the exact same problem that electique is/was having. I have a new value I create in hool_validate for a node form on a custom node and I just want to stick that into the node object. I have the database column, I just can't get the value into it. I know the value is there, because it is used to validate the field.. THANK YOU.