Either I'm missing something big time, or the (Form API) concept of hook_field_widget_form_submit() is entirely missing currently.

I've had several support requests on IRC and even my d.o contact page that asked for how a custom, compound field widget that also contains a text format enabled element can be made work.

Problem space being:

  1. #type 'text_format' expands into 'value' and 'format', so the submitted form values cannot be used directly as field values.
  2. In the case of #type 'text_format', and additionally, within a field attach form, fiddling with #parents is extremely hard to get right. Additionally, I consider most manual munging of #parents as ugly hacks.
  3. While there is hook_field_presave() for field type modules and it could be used, it's technically not really correct. Field widgets are abstracted from field types. This expanded value has been generated by a particular widget only, so the widget is responsible for adjusting the submitted form values.
  4. While custom field widget validation routines can be implemented relatively easily by using #element_validate, Form API doesn't provide an equivalent of that for the submission phase.
  5. I wasn't able to find any remotely comparable notion of a submit hook for field widgets. You'd naturally expect hook_field_widget_form_submit().

Comments

tim.plunkett’s picture

sub

yched’s picture

So far, it's been assumed that widgets could rely on usual FAPI constructs to take care of their own validation needs (validation specific to the shape of the input, as opposed to validation of the field values) and submission needs (massaging the widget's form values into the canonical 'field value' shape).

Worked so far, although it does sometimes require advanced / acrobatic FAPI fu in some cases (especially the 'submit' part, since, as you point, #element_validate does handles the validation part quite simply)

Then again, #type 'text_format' didn't exist in D6, so if it (or other 'advanced FAPI elements' like file upload, that were pretty much absent in D6) causes real difficulties with this approach, we couldn't really know so far.

So, I'm not opposed to a specific widget hook for that specific part that's (at least) difficult with FAPI constructs only, but I'm also wondering if this is not rather the sign of a missing #element_submit in FAPI ?
There were other (non widget-related) cases where I really wished I had that one.

catch’s picture

Category: bug » task

This doesn't look like a bug to me, moving to task.

nsteen’s picture

I don't know if that's true. There is not a good way to use the format options now.
The only way that I found was using the validation hook. (hook_form_validate())

xjm’s picture

Tracking.

xjm’s picture

Priority: Major » Normal

Looking back on this, I think maybe yched has it right with it rather being the "missing" #element_submit in FAPI.

xjm’s picture

Oops, I was questioning whether it was major (given the lack of action), but I didn't mean to actually demote it. Repromote if you disagree. :P

damien tournoud’s picture

Status: Active » Closed (won't fix)

#element_validate is actually the right point to mess-up with form values, so I'm going to close this. Validate is about massaging and validating the data, submit is about executing an action based on the validated data. #element_submit would be very wrong here.

xjm’s picture

Status: Closed (won't fix) » Active

Okay, but if that's not the correct solution, then adding a hook_field_widget_form_submit() perhaps is? Because we potentially do need the ability to somehow add additional submission handling for a field widget regardless of the specific form it's in. For validation handling you can do that with hook_field_widget_form_alter() and #element_validate, but if that isn't appropriate for submit handling, then we need another way, correct?

Note that I've only needed validation handling, but at least two others on this issue have needed submission handling.

Setting active for more feedback.

yched’s picture

@Damien: True, #element_submit would be a misleading name, we're not talking about matching what happens on in the $form's #submit, but rather about massaging what gets into $form_state['values'], at the level of any arbitrary $element. Doing this kind of thing can be really tricky at places with FAPI.

Anyway, as far as Field API and widgets are concerned, I've included an explicit $widget_controller->fieldValuesFromFormValues() method in the "Field API as OO plugins" rewrite I've been working on (still in-progress; trying to move forward with a couple needed refactor passes before I push it in the open - it's in the WSCCI sandbox for those interested)

damien tournoud’s picture

Because we potentially do need the ability to somehow add additional submission handling for a field widget regardless of the specific form it's in. For validation handling you can do that with hook_field_widget_form_alter() and #element_validate, but if that isn't appropriate for submit handling, then we need another way, correct?

No, you just add the #element_validate along with your widget FAPI definition. See for example the entityreference_autocomplete widget.

Anyway, as far as Field API and widgets are concerned, I've included an explicit $widget_controller->fieldValuesFromFormValues() method in the "Field API as OO plugins" rewrite I've been working on.

I would be slightly worried of anything that splits Field API Widgets and standard form API elements further apart. If a OO rewrite of the Form API happens one day, the Widget controller should just be a special type of component.

yched’s picture

@Damz : I'd say we'll see when that day comes :-)

jhedstrom’s picture

Status: Active » Closed (works as designed)

Unless I'm mistaken, this is no longer an issue given Drupal\Core\Field\WidgetBase exists, and can easily be extended as needed.