Problem/Motivation

There was an issue: #1954968: Required CKEditor fields always fail HTML5 validation
"An invalid form control with name='{name}' is not focusable" JS error is thrown when a textarea has "required" attribute, but is not visible.

This was fixed in CKEditor: https://dev.ckeditor.com/ticket/8031
Now CKEditor removes the "required" attribute from textarea during initialization.

But the problem still exist if the "required" attribute is added via #states.

Steps to reproduce

Add states to node title and body field via form alter to make body field required when the node title is filled in.

Proposed resolution

Make this more reliable to handle if a field is changed to required via #states that the field gets marked as required and editors are notified when HTML5 validation fails,so that editors know what the problem is and can act on it.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#31 2722319-31.patch7.49 KBkiseleva.t
#2 2722319-2.patch1.05 KBleksat

Issue fork drupal-2722319

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Leksat created an issue. See original summary.

leksat’s picture

Status: Active » Needs review
StatusFileSize
new1.05 KB

Here is how I managed to fix the issue.

wim leers’s picture

Status: Needs review » Postponed (maintainer needs more info)

Conditionally marking a field as required using #state makes no sense to me, because it means Form API (the server side) can't enforce it. What am I missing?

wim leers’s picture

Priority: Normal » Minor

Also, this is minor at best, this is an extreme edge case that will at most affect 0.01%.

wim leers’s picture

Title: CKEditor fields always fail HTML5 validation when "required" is added via states » CKEditor fields always fail HTML5 validation when "required" is added via #states
leksat’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

Yeah, I got this issue only because of custom modifications to the node edit form.

I'm not sure what's the process here, but I guess we can close this issue.

Current workaround: place the code from #2 to a custom module to solve the problem.

swirt’s picture

Status: Closed (won't fix) » Active

This is still an issue even though #1954968: Required CKEditor fields always fail HTML5 validation was already merged a long time ago. That solution did not account for a change of states.

Also, this is minor at best, this is an extreme edge case that will at most affect 0.01%
Conditionally marking a field as required using #state makes no sense to me, because it means Form API (the server side) can't enforce it. What am I missing?

I think there are two assumptions being made here.

  1. Assumption: It doesn't affect a lot of users. - I think it does, I have run into this on the past several large govt projects I have worked on. Each time we have to come up with less than ideal solutions.
  2. Assumption: Conditionally marking it as required is nonsensical because the api can't enforce it. - This is not always true. Sometimes we go to the extent of writing constraints and validators to enforce it. Unfortunately it never gets that far because html5 validation prevents it from ever making it that far, but the editor has no idea because CKeditor mangles the field id so it no longer is focusable.
  3. Assumption: it is not a bug. - #states supports requiredness, so it is a bug that any field using ckeditor can not properly get passed html5 validation if it was set by #states.
mahde’s picture

I agree with swirt, I am facing this issue a lot with too many projects as well!

quietone’s picture

Status: Active » Postponed (maintainer needs more info)

This is reported on Drupal 8, which is no longer supported. Does this problem exist on a supported version of Drupal? If so, update the version value. Thanks

swirt’s picture

Version: 8.1.x-dev » 9.5.x-dev
Status: Postponed (maintainer needs more info) » Active

Yes this is still an issue in the D9. Can not say for certain on D10

aaron.ferris’s picture

Ignore me, this is a separate issue entirely

joevagyok’s picture

Version: 9.5.x-dev » 11.x-dev
Priority: Minor » Normal

@Wim Leers, here is the 0.01%! :)

We have many fields conditionally marked as required by states and having that enforced by symfony constraints on API level.
There are several contributed modules shipping custom fields with multiple subfields (columns) which might require different form logic on different projects by developers.
So I believe it is a real issue, just like others mentioned before me.

joevagyok’s picture

The patch didn't work for me, and for some reason even when it worked, for some paragraph fields, the reinitialization placed an additional editor after the first one, so I ended up having 2 complete editors rendered for a single field.

So I tried to come up with a simple and clean solution to work around the problem, which basically keeps the editor's source element up to date via a listening to the change event inside the editor model. So when submit happens, the source element contains the data from the editor.

Pasting the JS code here:

/**
   * Handle CKEditor change event to keep the source element up to date.
   *
   * @type {Drupal~behavior}
   */
  Drupal.behaviors.ckeditor5SourceElementUpdater = {
    attach: function (context, settings) {
      let $context = $(context);

      // Iterate through all CKEditors on the page.
      $(once('ckeditor5-states', $context.find('[data-ckeditor5-id]').filter(':input'))).each(function () {
        if (this.dataset.ckeditor5Id) {

          let editorId = this.dataset.ckeditor5Id;
          // Using setTimeout() in order to ensure all CKEditors are loaded.
          setTimeout(function() {
            const editor = Drupal.CKEditor5Instances.get(editorId);

            if (editor) {
              $(once('ckeditor5-states-binding', editor.sourceElement)).each(function() {
                editor.model.document.on('change', function () {
                  if (editor.getData() !== editor.sourceElement.textContent) {
                    editor.updateSourceElement();
                    $(editor.sourceElement).trigger('change', [true]);
                  }
                });
              });
            }
          });
        }
      });
    }
  };
wim leers’s picture

Off-topic: I actually worked on something related a few weeks ago: #3409525: Regression from #3341682: #states + #required do not automatically work together, resulting in an unsubmittable AccountSettingsForm, but almost the opposite direction.

On-topic: let's start with writing a failing functional JS test that shows the problem, so that we can fix this and never regress again! 😊 Then the JS snippet in #13 should make that test pass. 👍

wim leers’s picture

Title: CKEditor fields always fail HTML5 validation when "required" is added via #states » <textarea>s using Text Editor always fail HTML5 validation when "required" is added via #states
Issue tags: -JavaScript +JavaScript

joevagyok’s picture

Pushed the test only to the MR which will fail.

joevagyok’s picture

Status: Needs work » Needs review

Pushed the fix which made the test pass.

joevagyok’s picture

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update

Issue summary appears incomplete. Please use the standard issue template.

swirt’s picture

Issue summary: View changes
Issue tags: -JavaScript +JavaScript

I just updated the summary to use the template.

joevagyok’s picture

Status: Needs work » Needs review
Issue tags: -JavaScript, -Needs tests, -Needs issue summary update +JavaScript
smustgrave’s picture

Status: Needs review » Needs work

Left 2 comments on MR, one is nitpicky but believe return docs should be included.

pradhumanjain2311 made their first commit to this issue’s fork.

twilderan’s picture

Status: Needs work » Needs review

Fix from related MR worked for me on Drupal core 10.2.2 and Conditional Fields 4.0.0-alpha5.

Needs review from community and we can include it in next release to fix this and related https://www.drupal.org/project/conditional_fields/issues/2988937

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs steps to reproduce

Reading early comments I should of also tagged for steps to reproduce early on. It helps reviewers/committers to be able to quickly see how to reproduce the problem.

joevagyok’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs steps to reproduce

I updated the description to include the steps to reproduce.
The point of pushing test before the fix was to prove and show the problem, that should be the single source of truth for the reviewer, not what is in the issue description. But that is just my opinion.
Please see commits from #16.

smustgrave’s picture

Purpose of the issue summary is to be able to quickly get up to speed just fyi

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Issue summary appears clear and all feedback on MR resolved.

nod_’s picture

Status: Reviewed & tested by the community » Needs work

few comments

kiseleva.t’s picture

StatusFileSize
new7.49 KB

Exported MR into patch file.

michaelsoetaert’s picture

deleted by user.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.