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

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ben kuper’s picture

Version: 7.0-rc2 » 7.0

The 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 :

      var elem = $(e.target).closest('.form-item, .form-submit, .form-wrapper');
	  if(elem.parent().hasClass('text-format-wrapper')){
		  elem = elem.parent();
	  }
	  elem[e.value ? 'show' : 'hide']();

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.

cpliakas’s picture

Version: 7.0 » 7.x-dev
FileSize
118.72 KB

This bug is still present in 7.2 release and the 7.x-1.x branch. Attaching a screenshot to further illustrate the bug.

PatchRanger’s picture

Confirmed : the bug is still alive in 7.15 release.

nod_’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +JavaScript

Happens in D8 as well.

Shiraz Dindar’s picture

Confirming this bug exists in 7.16.

haggins’s picture

Issue summary: View changes

I worked around the following way (could possibly be the general fix):

Copy the filter_process_format() function to your module and rename it to mymodule_filter_process_format().

Change the new function like this (adding 3 lines of code):

// snip

// Setup child container for the text format widget.
  $element['format'] = array(
    '#type' => 'fieldset',
    '#attributes' => array('class' => array('filter-wrapper')),
  );

  // The #states-bug fix:
  if (isset($element['value']['#states'])) {
    $element['format']['#states'] = $element['value']['#states'];
  }

  // Prepare text format guidelines.
  $element['format']['guidelines'] = array(
    '#type' => 'container',
    '#attributes' => array('class' => array('filter-guidelines')),
    '#weight' => 20,
  );

// snap

Finally, set the #process attribute of your text_format element to array('mymodule_filter_process_format').

amar.deokar’s picture

Simple work around !

 $form['container'] = array(
   '#type' => 'container',
   '#states' => array('visible' => array(':input[name="xyz"]' => array('value' => true),),),
 );

 $form['container']['mytext'] = array(
   '#type' => 'text_format',
   '#format' => 'full_html',
   '#title' => t('My text format'),
   //'#states' => array('visible' => array(':input[name="xyz"]' => array('value' => 'true'),),),
   );

I achieved #states results for my "mytext" field by putting "mytext" field inside "container" field and applying #states to "container" field rather than "mytext".

amar.deokar’s picture

Ideally 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.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

chgasparoto’s picture

#7 worked perfectly here (D7). Thanks!

NancyDru’s picture

While #7 works just fine, IMHO it's clunky and not very Drupal-y.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

sukanya.ramakrishnan’s picture

Submitting a core patch with the suggestion in comment #6

sukanya.ramakrishnan’s picture

Status: Active » Needs review

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

JonMcL’s picture

Patch 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

JonMcL’s picture

Version: 8.6.x-dev » 8.8.x-dev
DuneBL’s picture

#16 solved my problem

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

szeidler’s picture

Issue tags: -JavaScript +JavaScript

Patch #16 works quite well for me using Drupal 8.8

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

wells’s picture

Status: Needs review » Reviewed & tested by the community

#16 working in 8.9.x now, as well.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Thanks 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:

  1. https://www.drupal.org/docs/testing/phpunit-in-drupal/phpunit-javascript...
  2. https://api.drupal.org/api/drupal/core%21core.api.php/group/testing/9.1.x

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Lendude’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
3.63 KB
4.34 KB

Here is a test for this, test only patch is also the interdiff

The last submitted patch, 28: 997826-28-TEST_ONLY.patch, failed testing. View results

idebr’s picture

Status: Needs review » Reviewed & tested by the community

Patch #28 works as expected and includes test coverage. Setting to RTBC.

Matroskeen’s picture

Issue tags: +Bug Smash Initiative
larowlan’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
@@ -80,6 +112,8 @@ protected function doCheckboxTriggerTests() {
+    $this->assertFalse($text_format_invisible_when_checkbox_trigger_checked_value->isVisible());
+    $this->assertFalse($text_format_invisible_when_checkbox_trigger_checked_format->isVisible());

We'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.

dww’s picture

Yay, 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:

  1. +++ b/core/modules/filter/src/Element/TextFormat.php
    @@ -165,6 +165,12 @@ public static function processFormat(&$element, FormStateInterface $form_state,
    +    // Set the states property for the filter format element from the value
    +    // of the element if it exists.
    

    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.

  2. +++ b/core/modules/filter/src/Element/TextFormat.php
    @@ -165,6 +165,12 @@ public static function processFormat(&$element, FormStateInterface $form_state,
    +    if (isset($element['value']['#states'])) {
    

    Should we also check if $element['#states'] itself is set?

  3. +++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
    @@ -121,6 +121,15 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +    $form['text_format_invisible_when_checkbox_trigger_checked'] = [
    +      '#type' => 'text_format',
    +      '#title' => 'Text format invisible when checkbox trigger checked',
    +      '#states' => [
    +        'visible' => [
    +          ':input[name="checkbox_trigger"]' => ['checked' => FALSE],
    

    The rest of the test names the things exactly what they are. E.g.:

       $form['textfield_invisible_when_checkbox_trigger_checked'] = [
          '#type' => 'textfield',
          '#title' => 'Textfield invisible when checkbox trigger checked',
          '#states' => [
            'invisible' => [
              ':input[name="checkbox_trigger"]' => ['checked' => TRUE],
            ],
          ],
        ];
    

    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

Lendude’s picture

Status: Needs work » Needs review
FileSize
2.11 KB
4.88 KB

Thanks 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

dww’s picture

Thanks, @Lendude! Mostly looking good. A few final points:

  1. +++ b/core/modules/filter/src/Element/TextFormat.php
    @@ -165,6 +165,12 @@ public static function processFormat(&$element, FormStateInterface $form_state,
    +    // Set the #states property of the filter format element to the same value
    +    // as the value element, if the value element has #states set.
    

    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. ;)

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
    @@ -60,6 +88,10 @@ protected function doCheckboxTriggerTests() {
    +    $text_format_invisible_when_checkbox_trigger_checked_value = $page->findField('text_format_invisible_when_checkbox_trigger_checked[value]');
    +    $text_format_invisible_when_checkbox_trigger_checked_format = $page->findField('text_format_invisible_when_checkbox_trigger_checked[format]');
    

    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.

  3. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
    @@ -60,6 +88,10 @@ protected function doCheckboxTriggerTests() {
    +    $this->assertNotEmpty($text_format_invisible_when_checkbox_trigger_checked_value);
    +    $this->assertNotEmpty($text_format_invisible_when_checkbox_trigger_checked_format);
    

    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:

  1. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
    @@ -21,6 +22,33 @@ class JavascriptStatesTest extends WebDriverTestBase {
    +    $filtered_html_format->save();
    

    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:

1) Drupal\FunctionalJavascriptTests\Core\Form\JavascriptStatesTest::testJavascriptStates
Failed asserting that true is false.
...
/.../core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php:116

Line 116 is:

    $this->assertFalse($text_format_invisible_format->isVisible());

I believe 1 of these 2 patches is now RTBC, but now I can't say. 😉

Thanks,
-Derek

The last submitted patch, 35: 997826-35.test-only.patch, failed testing. View results

The last submitted patch, 35: 997826-35b.patch, failed testing. View results

dww’s picture

Re: #37 - The failed test result for #35b was unexpected. #3192260: [random test failure] Random fail in media_library CKEditorIntegrationTest strikes again. Re-queued.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

I have hidden the b patch let's go with the original patch.

  • catch committed 722be73 on 9.2.x
    Issue #997826 by dww, Lendude, sukanya.ramakrishnan, amar.deokar, JonMcL...
catch’s picture

Version: 9.2.x-dev » 9.1.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.2.x and cherry-picked to 9.1.x, thanks! Nice to see an eleven-year-old bug fixed.

  • catch committed b3cff0f on 9.1.x
    Issue #997826 by dww, Lendude, sukanya.ramakrishnan, amar.deokar, JonMcL...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.