When using type "text_format", it generates a textarea and the filter form fieldset.
But in html, fieldset element is out of the div .form-item.
When you add #states on this element, it apply only to .form-item and not on fieldset.
One solution could be to add parents jquery function on states.js to the text-format-wrapper ?, sample line 372:
$(e.target).parents('.text-format-wrapper')[e.value ? 'show' : 'hide']();
But i'm not sure it's a good way...
An other solution could be to change the way the text_format is render to add filter form fieldset in the div.form-item ?
Or perhaps you can consider it's not a bug and text_format need to be in a container or a fieldest to get states working.
Regards
Mog.
Proposed solution
The format field should inherit the #states from the parent element
| Comment | File | Size | Author |
|---|---|---|---|
| #35 | 997826-35.patch | 4.63 KB | dww |
| #35 | 997826-35.test-only.patch | 5.29 KB | dww |
Comments
Comment #1
ben kuper commentedThe final version of D7.0 didn't took care of this... as for few other things considering the #states functionnality (#735528: FAPI #states: Fix conditionals to allow OR and XOR constructions is a very cool fix i think).
Anyway, this function changed a bit since the rc2 and the closest() function is used now, so i went along with your idea of changing the states.js, but in the final version of it.
I changed the parents() function a contionnal with hasClass() verification since parents() or parent() doesn't return the current element if nothing was found.
Line 481 :
I still think that it's not the good way to fix it as it's not really a states.js misfunctionning but as you said the text_format/text-area form fields generation that should be adjusted. At least i see it that way.
Comment #2
cpliakas commentedThis bug is still present in 7.2 release and the 7.x-1.x branch. Attaching a screenshot to further illustrate the bug.
Comment #3
PatchRanger commentedConfirmed : the bug is still alive in 7.15 release.
Comment #4
nod_Happens in D8 as well.
Comment #5
shiraz dindarConfirming this bug exists in 7.16.
Comment #6
haggins commentedI worked around the following way (could possibly be the general fix):
Copy the
filter_process_format()function to your module and rename it tomymodule_filter_process_format().Change the new function like this (adding 3 lines of code):
Finally, set the #process attribute of your text_format element to array('mymodule_filter_process_format').
Comment #7
amar.deokar commentedSimple work around !
I achieved #states results for my "mytext" field by putting "mytext" field inside "container" field and applying #states to "container" field rather than "mytext".
Comment #8
amar.deokar commentedIdeally by considering above(#7) work around we can update some basics designing in filter module.
Istead of wrapping text_format field in simple div we should have container field as parent field.
and attributes like #states should be applied to it. I am not sure about pros and cons of adding parent container to text_format field internally.
Comment #12
chgasparoto commented#7 worked perfectly here (D7). Thanks!
Comment #13
nancydruWhile #7 works just fine, IMHO it's clunky and not very Drupal-y.
Comment #16
sukanya.ramakrishnan commentedSubmitting a core patch with the suggestion in comment #6
Comment #17
sukanya.ramakrishnan commentedComment #19
jonmcl commentedPatch at #16 works perfectly for me!
By the way, I have been having trouble getting #states applied to a container to properly work in a situation where the form (or subform) is loaded via AJAX. At least with Paragraphs. So I'm not sure if that is a viable workaround for every situation. For some reason, the #states don't get properly activated when the form elements first load from the AJAX request. They work, in that if I change the element that the container is dependent on, the state changes get applied.
I think patch at #16 is elegant and in the right place. Thanks @sukanyaramakrishnan
Comment #20
jonmcl commentedComment #21
dunebl#16 solved my problem
Comment #23
szeidler commentedPatch #16 works quite well for me using Drupal 8.8
Comment #25
wells#16 working in 8.9.x now, as well.
Comment #26
alexpottThanks for filing this bug report and for fixing the issue. Bug fixing is very valuable. In order to commit a bug fix, we need an automated to test to prove that we've fixed the bug and ensure that we don't break it again in the future. For more information about writing tests in Drupal, see the following links:
Comment #28
lendudeHere is a test for this, test only patch is also the interdiff
Comment #30
idebr commentedPatch #28 works as expected and includes test coverage. Setting to RTBC.
Comment #31
matroskeenComment #32
larowlanWe've got two negative asserts here, but not the corresponding
assertTrue(...->isVisible())like we have for the other elements being tested in this class.I think we should add those.
Comment #33
dwwYay, glad to see this getting fixed! And that it's easy to expand core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php from #2702233: [backport] Add JavaScript tests for Form API #states: required, visible, invisible, expanded, checked, unchecked. Thanks for the effort so far. In addition to #32 (+1 to all that), a few other nits/concerns:
Maybe:
"Set the #states property for the filter format element from the value element if it exists." ?
a. "states" on its own is maybe confusing? Is "#states" more clear?
b. "format element" vs. "value of the element" is a little confusing. Let's be consistent about if it's a value/format *of* the element, or if we're talking about the value and format (sub)elements *of* the (parent) element.
Should we also check if
$element['#states']itself is set?The rest of the test names the things exactly what they are. E.g.:
In this case, the name doesn't match the logic due to inverted values. Either we should use
'invisible'and'checked' => TRUE, or we should rename this element to "text_format_visible_when_checkbox_trigger_unchecked" or something.Thanks again,
-Derek
Comment #34
lendudeThanks for the reviews!
#32.1 done
#33.1 Updated the comment, I think it's clearer now
#33.2 Don't think we need that since $element['value'] is set to the value of $element about 50 lines earlier, so there is nothing there that isn't in 'value'
#33.3 Agree, changed to invisible and TRUE
Comment #35
dwwThanks, @Lendude! Mostly looking good. A few final points:
This still seems clumsy. How about?
"If the value element has #states set, copy it to the format element."
That even fits in 80 chars. ;)
While I'm all for self-documenting variable names, this seems to take it a bit far. ;) All of the other local vars in this method assume the "when_checkbox_trigger_checked" part. It seems cleaner to leave that out for these, too.
All the existing code puts the assertNotEmpty() immediately after trying to find each thing, so for consistency, let's do the same.
Attached fixes these 3. I also wondered about this:
Why the local variable at all? Why not just:
FilterFormat::create([...])->save();?
Wasn't sure that was worth fixing, so attaching it as a separate patch.
Also refreshing the test-only patch for good measure. It should fail with:
Line 116 is:
I believe 1 of these 2 patches is now RTBC, but now I can't say. 😉
Thanks,
-Derek
Comment #38
dwwRe: #37 - The failed test result for #35b was unexpected. #3192260: [random test failure] Random fail in media_library CKEditorIntegrationTest strikes again. Re-queued.
Comment #39
jibranI have hidden the b patch let's go with the original patch.
Comment #41
catchCommitted/pushed to 9.2.x and cherry-picked to 9.1.x, thanks! Nice to see an eleven-year-old bug fixed.