Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
It seems that using form_set_value()
from within an #element_validate
callback has no effect.
If this is by design, I guess it should be added to documentation.
Comments
Comment #1
jhodgdonHm. I think that this is supposed to work. Can you provide more information?
Also note that the documentation for form_set_value() says:
Comment #2
anrikun CreditAttribution: anrikun commentedThe documentation says this too:
Note that form validation functions are specified in the '#validate' component of the form array (the value of $form['#validate'] is an array of validation function names). If the form does not originate in your module, you can implement hook_form_FORM_ID_alter() to add a validation function to $form['#validate'].
So I guess
form_set_value()
only works from within a#validate
callback but not an#element_validate
callback?It is not clearly stated.
Anyway, I may be misusing the function too so I will check my code again and let you know.
Comment #3
jhodgdonIt should work within either type of validate callback, as far as I know. So... some code that isn't working would be helpful to see.
Comment #4
anrikun CreditAttribution: anrikun commentedHere is some code. I have simplified it so it's just an example:
What I expect if user submits a value over 1 for 'qty':
- An error is displayed.
- 'qty' field displays 1.
What I get:
- An error is displayed.
- 'qty' field still displays submitted erroneous value.
I guess this is by design. Does it mean that
$form_state['rebuild'] = TRUE;
is needed here?Comment #5
jhodgdonWell, I don't know what to tell you for sure. I looked at
drupal_validate_form()
and there is some code in there about '#limit_validation_errors' -- it looks like if this is set (not sure how/when it does get set), values set during validation on elements that failed validation would be cleared. Is it possible that is what is happening in your case?
It looks like that might be set up in
_form_validate()
That's about all I can gather... I don't know if this is a support request or a code bug at this point, so I'm moving it to the forms component (I don't think it's a documentation bug). You might try getting some help in IRC (see http://drupal.org/irc) so you can narrow it down... for now I am out of ideas and I'm un-following this issue. Sorry I didn't have more to offer you.
Comment #6
anrikun CreditAttribution: anrikun commented@jhodgdon: thanks for your help anyway, much appreciated :-)
Comment #7
j0rd CreditAttribution: j0rd commented@anrikun I'm having similar issue, but mine is working in everything except IE9.
If you use $form_state['rebuild'] = TRUE, which is required for my form to work, this breaks other ajax stuff, like with an image field. Attempt to add an image field to your node_form and then see if you can "update image" in IE9. For me it doesn't work.
This is the last remaining problem I have with my beast of a widget on a node form.
Comment #8
rszrama CreditAttribution: rszrama commentedform_set_value() within an #element_validate callback does work. This code example comes from the Commerce Product Reference autocomplete textfield widget:
It could be you're just using in invalid $value for the form element. However, I'm going to close out this request, as in your case you simply shouldn't make the value editable if it can only ever be 1. ; )
Comment #9
j0rd CreditAttribution: j0rd commentedFor me, it works just fine in all browsers but IE9.
And the issue is not that my form_set_value() code in #element_validate doesn't work, but it breaks an image upload.
Again only in IE9.
I have no idea how to fix it...but currently IE9 users on my site are not able to upload images on their nodes because of this.
It's a very strange bug, and most likely due to some bad JS in core or modules.
If I do remove my #element_validate hook on the form though, the image upload works fine in IE9.
I am using jquery_update (jQuery 1.7), but I have also tried disabling that to see if it works, and it doesn't help.
Comment #10
rszrama CreditAttribution: rszrama commentedHmm, and there's no resulting error message from that form validation? When an AJAX process is triggered, it's validating the whole form before rebuilding just that part of the form that would include the uploaded image. But the validation all happens server side, not client side in some JS that should screw up depending on whether or not it had validation.
Comment #11
jigariusFacing the same problem! I am using
form_set_value()
within an#element_validate
callback, but it does not seem to work. Spent over 2 hours now.Comment #12
nvahalik CreditAttribution: nvahalik as a volunteer and at Code and Salt commentedJust putting some notes in here in case anyone else comes across this.
I had a use case where I was getting a custom line item field value in the add to cart form (a custom price field for a gift card) and people were putting all sorts of funky-formatted values in the field. The field is already set up and I didn't want to have to change the field type or make a bunch of big changes so I figured I'd just do some pre-validation, parse and clean the value, and then let the rest of the validation system do it's job. However, it was not working.
As Ryan mentioned, calling
form_set_value()
from within an#element_validate
callback does work in that it properly updates the form. Validation functions set at the form level will see the correct value. However, if you're wanting to do something like perform a custom validation on a value—cleaning it up and parsing it, for instance— before a subsequent validator gets it thenform_set_value()
will not work because those element validator functions do not look at$form_state
to get their values. Instead, they are looking at the$element
array.As a workaround, you could replace that validator with your own custom function, make your changes, and then just call the original validator at the end of your custom function. This is the solution that I chose to do. Example:
Comment #13
Fabianx CreditAttribution: Fabianx at Tag1 Consulting commentedJust to add to this:
If you need to have your new form_state value be used in your form, then you need to also change $element and pass that by reference.
e.g.