Closed (fixed)
Project:
Field Conditional States
Version:
7.x-2.x-dev
Component:
Code
Priority:
Major
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
23 Feb 2014 at 00:00 UTC
Updated:
3 Apr 2014 at 23:41 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
hass commentedComment #2
Tobias Xy commentedTo avoid too much pain we could be more specific in field_conditional_state_field_widget_form_alter.
Then it should be save to just use $element['#id'] in field_conditional_state_element_process (at least I hope so...).
But there is also a drawback: We possibly have to list a lot of widget types explicitly within field_conditional_state_field_widget_form_alter. At least I didn't find a proper way how to determine the actual input element (and not one of its wrappers) there.
But in the end we could remove a lot of confusing code within the process and pre_render callback.
Comment #3
Tobias Xy commentedIt's not exactly a critical issue.
"Critical bugs either render a system unusable (not being able to create content or upgrade between versions, blocks not displaying, and the like), cause loss of data, or expose security vulnerabilities."
Comment #4
hass commentedCritical also means a release blocker. This is something that cannot changed after release as it is changing html and therby theming. We really need to solve this before release.
Do we really have so many widget types? The list should be short. It may give us a lot more control what really happens without many unexpected side effects.
Comment #5
Tobias Xy commentedIt's very annoying, that every widget has another array structure (hook_field_widget_form doesn't enforce any standards) and I have no clue how to handle that, without creating a lot of bad code, getting gray hair and having nightmares...
Maybe I have to do more research on how widgets are handled in Drupal, but I fear that there isn't a nice way to get the information we need...
Because of this I think we should add the process handler within the widget_form_alter hook just to the top level of the given element.
And then we should "search" for the actual input element within the process callback.
If anyone has a better solution please let me know...
Comment #6
hass commentedI'm not sure what you are talking about. Id and classes of a field widget should be in the same place all times. Otherwise theming wouldbe impossible. A have themed all my form elements abd added classes. It was not that difficult... But I may not understand something. Can you write up your action plan and what you are trying? Maybe I get a better idea of the problems you expect. Currently i do not understany why you are not using the element id as reference. That's all. We need, isn't it?
Maybe we need to hook into form theme functions.
Comment #7
Tobias Xy commentedIts not about the actual HTML output. The problem is, that during the form building process the widgets are differently wrapped.
For example:
Create a content type with a checkbox, a text field, a file field, a select list and a URL field (it's not in core but there are a lot of sites using it).
Then add a
in field_conditional_state_element_process (devel needed) and go to node/add/helloworld
The differences between these widget types (especially $element['#id']):
So we actually have to handle all the widget types differently, right?
Comment #8
hass commentedWell, I need to repro this first as I cannot fully follow.
Maybe we can use hook_form_alter() or some form preprocess functions and add the state api stuff there. Have you considered this already?
Comment #9
Tobias Xy commentedI don't think hook_form_alter (or any other form level hook) will do a better job there. We would still have to "find" the correct ID but starting from a higher level within the page array.
hook_field_widget_form_alter at least is called per field, so this should be less pain, than hook_form_alter.
Comment #10
Tobias Xy commentedI created a patch. The extra div is now not longer needed. The main changes are:
1.) Now we use a #after_build callback instead of a #process callback, because during #process the element isn't completely build.
2.) _field_conditional_state_get_element_parents returns the path to the actual input element within the $element array and additionally the path to the field information like #entity_type, #bundle, #field_name if they aren't set on the actual element.
Currently all core widget types and the url_external widget type should be supported (except of "Check boxes/radio buttons"). Field collections (or actual any kind of form where one field exists twice or more) are not supported currently.
3.) field_conditional_state_element_after_build only adds the #pre_render callback to the actual input element as defined by _field_conditional_state_get_element_parents and maps the combination of entity type, bundle and field name to the actual used HTML ID ($element['#id']).
Edit: With this patch #2185759: Select list control fields aren't working would be fixed too and #2200361: Incompatible with #type => text_format (ie. long text fields with formatting) at least partially.
Comment #11
Tobias Xy commentedRemoved useless code in _field_conditional_state_add_states.
Comment #12
Tobias Xy commentedI don't expect any reviews, so I will commit the patch at the weekend, because it will probably fix a lot of problems.
Comment #13
hass commentedThere are some code style issues. I cannot test before the weekend, too. Have you also checked pre_render hook?
Comment #14
Tobias Xy commentedFixed a lot of coding style issues here.
The #pre_render hook should work as expected (at least it does when I tested the patch).
Comment #15
Tobias Xy commentedSmall change in field_conditional_state_element_after_build.
Comment #16
Tobias Xy commentedActually visibility states have to be applied to the topmost level and enabled/required states to the actual input element. Will do that later today.
Comment #17
Tobias Xy commentedNow we have two different pre_render callbacks.
One to add the states visible and invisible and one to add all the other states.
field_conditional_state_element_after_build checks what kind of states are active for the current element and sets the appropriate pre_render callbacks (only if needed).
We have to handle this differently, because the states visible/invisible should show/hide the whole widget and not just the input element. There is not always a difference, but sometimes unfortunately there are (visible) wrappers around the element (URL field for example). So the state must be applied to the topmost level of $element passed to field_conditional_state_element_after_build.
The other states (enabled, disabled, required and optional) only affect the actual input element, so adding them to the topmost level won't work sometimes (URL field and some core widgets for example).
The whole thing is a little bit complex, but I think it's the most stable way of doing this.
Comment #18
Tobias Xy commentedComment #19
hass commentedIf I create a new node with fields inside having states I get tons of these notices at
node/add/fooLooks like entityreference_autocomplete fields are missing these keys... or better to say - they are inside
['target_id']subarray.Comment #20
Tobias Xy commentedI'll add a check for these keys tomorrow, but these notices should currently only appear for some of the not supported widget types.
Which widget types are you using on this form?Autocomplete fields aren't supported at the moment. Going to add them tomorrow too (they have to be added to _field_conditional_state_get_element_parents).
Comment #21
hass commentedThat sounds like it can fail on more field types. We should add a whitelist here. I guess we cannot support all custom field types.
Comment #22
Tobias Xy commentedIt will fail on all widgets (not equal to field types!) where the entity_type, bundle and field_name information are not on the top level of the $elements array in field_conditional_state_element_after_build AND which are not explicitly handled by _field_conditional_state_get_element_parents.
Can we create our own documentation pages for FCS? I could write a table of supported widgets then.
Comment #23
hass commentedI do not like to see notices... The documentation of supported field types is a different thing. I think a table on project home fit, but everyone can create doc pages on d.o.
Comment #24
Tobias Xy commentedYou mean a coded whitelist of widgets that are allowed to be control fields?
Sounds like a good idea.
Comment #25
hass commentedYes. If somethink is known to work... Add/show it - otherwise it is not available. We will get the request to support missing fields... I'm sure :-)
Comment #26
Tobias Xy commentedI introduced a whitelist in the new patch. It doesn't really change the behavior of the fcs settings form, because thats not even easy. I created a new issue for that: #2218339: Restrict control field selection to supported control fields.
Unsupported fields are neither usable as control fields nor as controled field.
Comment #27
Tobias Xy commentedI fixed a few coding style issues and committed it (patch is attached). Please create new issues for follow ups.