Problem/Motivation

#3024975: Add Drupal JavaScript theme function for checkbox added theme function for rendering markup for checkboxes. Drupal.behaviors.MediaLibrarySelectAll also needs to render a label.

Proposed resolution

Create a new theme function that allows rendering labels for form inputs.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Added JavaScript theme function for form labels

Issue fork drupal-3082598

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

lauriii created an issue. See original summary.

lauriii’s picture

lauriii’s picture

Issue tags: +Media Initiative
lauriii’s picture

Title: Add theme function for form elements in JavaScript » Add theme function for form labels in JavaScript
Issue summary: View changes
phenaproxima’s picture

Status: Active » Needs review
StatusFileSize
new1.52 KB

At @lauriii's request, took an initial stab at this patch.

lauriii’s picture

Status: Needs review » Needs work

This looks good! Would be nice to replace the hardcoded label in Drupal.behaviors.MediaLibrarySelectAll as part of this to prove that this works 😄

tinko’s picture

Status: Needs work » Needs review
StatusFileSize
new4.01 KB

Hello,

I've tried several different ways to pass the checkbox to theme function, but the shown checkbox in administration was always without attached js events. So i've made formLabel theme and pass only label params and left the prepend function to attach the checkbox.

What do you think about this solution?

andrewmacpherson’s picture

Issue tags: +Accessibility

How are labels associated with inputs? I don't see any handling of the for attribute.in these patches.

lauriii’s picture

Status: Needs review » Needs work

Patch in #5 rendered input inside the label element so it didn't need id and for attribute. However, if we go with the approach proposed in #7, we do have to add support for id. My main concern with the approach in #7 is that we miss tooling for generating unique ids in JavaScript.

andrewmacpherson’s picture

Most of our inputs (in twig-generated markup) use <label for> rather than wrapping inputs. Media libary's select-all is an odd case of nesting the checkbox inside the label, but it's OK because it satisfies WCAG "Name, Role, Value".

Patch #7 is better, in a way, because it doesn't force the input to be nested inside the label. Having them as distinct elements is useful for layout (label above vs label inline, say).

On the other hand, we don't want to force developers to use the for attribute. Nesting inputs inside labels is attractive too, because it means you don't have to manage IDs to get accessible names.

I'm not clear what the scope of this issue is. The new JS theme function is intended for general use, I think? Media-library is just an existing use which needs to be updated. As it happens, media-library does a separate jQuery.prepend() to put the checkbox inside the label afterwards.

So I don't know whether this theme function needs to have special handling of the for attribute. Developers can manually add a for attribute to any label easily enough, using jQuery.attr('for'), say. (Similarly, tableselect doesn't bother with a label element; it makes an accessible name with jQuery.attr('title'). You could do the same with aria-label.

Maybe it would be better to explicitly document the fact that developers are responsible for ensuring that inputs have accessible names? The docblock would note that there is no special handling of the for attribute, and a change record could contain several examples.

zrpnr’s picture

Status: Needs work » Needs review
StatusFileSize
new5.3 KB
new3.89 KB

Having them as distinct elements is useful for layout

I agree that this theme function is more flexible if it just handles the label and doesn't enforce the nested input.
It also allows for this specific use case in media_library to have unchanged markup, without the extra div.

we don't want to force developers to use the for attribute

I modified the theme function to allow for an optional "for".
In this case I'm not adding that attribute since the input is nested.

we miss tooling for generating unique ids in JavaScript

In this particular case it won't matter because of the prepend - the input gets nested by jQuery so the for isn't necessary.
I was searching core for other places labels are created, I found one in Drupal.theme.quickeditImageToolbar and the for is static, it could be that it could just be passed as a string or generated inline.

However, if it made sense to add a uniqueID method, that could be a small utility which gets required separately case-by-case.

Maybe it shouldn't be part of this patch- but the "announcement" logic was backwards, so I swapped that ternary around.

nod_’s picture

+++ b/core/misc/form-label.es6.js
@@ -0,0 +1,21 @@
+  Drupal.theme.formLabel = ({ label, className, labelFor }) => {

I would separate the label and attributes Drupal.theme.formLabel = (label, attributes) => {} and make the attribute thing generic, if it's a theme function may want to make it support more than just 2 attributes.

nod_’s picture

@lauriii pointed me to #3070521-11: Trigger deprecation notifications on JavaScript deprecations to notify developers that deprecated code is being used ok with having a single object as argument.

The rest of the patch looks good to me. The ternary swap should be in another patch though.

lauriii’s picture

I assume we should still create the attributes object requested in #12?

zrpnr’s picture

@nod_ would it work to have Drupal.theme.formLabel = ({ label, attributes }) and then destructure attributes in the function?

The ternary swap should be in another patch though.

I'll remove that from this patch and make a new issue.

nod_’s picture

I'd be ok with that, it's dangerously starting to ressemble FormAPI though let's be careful not to go overboard in other issues :)

zrpnr’s picture

StatusFileSize
new4.71 KB
new3.81 KB

Removed the ternary swap and updated the object passed into the theme function.

let's be careful not to go overboard

It was tempting to make an even more nested object like a render array!
The single object should be a good compromise on flexibility, making it simpler for a developer to override which properties are passed in and how to handle them.

zrpnr’s picture

wim leers’s picture

What's left here?

@nod_ perhaps you can RTBC this? :)

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.

nod_’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me, thanks!

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll
shashikant_chauhan’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new4.74 KB

Rerolled the patch from #17

zrpnr’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for the re-roll @ shashikant_chauhan

There was just a single line change, patch still applies fine and tests are green. This was RTBC in #21, setting it back.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/media_library/js/media_library.view.es6.js
    @@ -35,10 +35,14 @@
    +        const options = {
    +          label: Drupal.t('Select all media'),
    +          properties: { className: 'media-library-select-all' },
    +        };
    

    Nit: We probably don't need the options variable. I would prefer initializing this inline on the function arguments.

  2. +++ b/core/modules/media_library/media_library.module
    @@ -196,6 +196,7 @@ function media_library_form_alter(array &$form, FormStateInterface $form_state,
    +    $form['#attached']['library'][] = 'core/drupal.form-label';
    

    Instead of attaching this library manually here, we should add this as a dependency for the media_library/view library. This way we can ensure that whenever the library is loaded, the dependency exists as well.

tinko’s picture

Status: Needs work » Needs review
StatusFileSize
new2.57 KB
new4.33 KB

Hello, @lauriii, changes are added.

zrpnr’s picture

Status: Needs review » Needs work

This addresses #25.1, The object is now directly inline with the theme function.
This formatting looks correct to me but Prettier shows an error here unless the line breaks are slightly different:

-        const $label = $(Drupal.theme('formLabel', {
-          label: Drupal.t('Select all media'),
-          properties: { className: 'media-library-select-all' },
-        }));
+        const $label = $(
+          Drupal.theme('formLabel', {
+            label: Drupal.t('Select all media'),
+            properties: { className: 'media-library-select-all' },
+          }),
+        );

#25.2 looks good as well, the library is no longer attached in the form alter and instead as a dependency in media_library/view

The only other nits are some extra spaces in:

+++ b/core/modules/media_library/js/media_library.view.js
@@ -21,10 +21,15 @@
+        ¶

and 2 places (form-label.js, media-library.view.js) where the ending newlines are not removed.
For me the extra space and newlines are removed by running yarn build:js.

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new4.28 KB
new1.73 KB

#27 fixes

zrpnr’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @bnjmnm, now running yarn build:js does not produce any changes and the es6 file matches Prettier formatting suggestions.

This was RTBC in #21, rerolled in #23 and @tinko addressed @lauriii feedback in #25 with #26.

zrpnr’s picture

Added a change record, I wasn't totally sure what to put for the "introduced in" since this is on the 8.9.x branch now but will hopefully be backported to 8.8.

zrpnr’s picture

Issue summary: View changes
lauriii’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll
  1. +++ b/core/misc/form-label.es6.js
    @@ -0,0 +1,29 @@
    +   * @param {object} [options.properties]
    ...
    +    const { className, labelFor } = properties;
    

    Let's document supported properties in the docblock 📄

  2. +++ b/core/misc/form-label.es6.js
    @@ -0,0 +1,29 @@
    +   * @param {object} [options.properties]
    +   *   Attributes object
    

    We probably should update the documentation since this doesn't seem like an Attributes object.

kostyashupenko’s picture

Issue tags: -Needs reroll
StatusFileSize
new4.23 KB

Reroll of #28

kostyashupenko’s picture

Status: Needs work » Needs review
kostyashupenko’s picture

Status: Needs review » Needs work

Need to fix #32 feedbacks

boulaffasae’s picture

Status: Needs work » Needs review
StatusFileSize
new4.43 KB

Hello @lauriii, Here's a fix for #32

  1. documenting supported properties in the docblock 📄
          +   * @param {string} [options.properties.className]
          +   * The class attribute of the label.
          +   * @param {string} [options.properties.labelFor]
          +   * The for attribute of the label.
        
  2. update the documentation for properties object.
          +   * @param {object} [options.properties]
          +   * An object with the following properties:
        

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.

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.

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new144 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

madhaze’s picture

This would still be nice. It would also need to be added to tableselect.js so the checkbox there also has a label for accessibility. https://git.drupalcode.org/project/drupal/-/blob/11.x/core/misc/tablesel...

gauravvvv’s picture

Status: Needs work » Needs review
StatusFileSize
new2.55 KB

I have attached a patch for 11.x, please review

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new2.32 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

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

rpayanm’s picture

Status: Needs work » Needs review

I rerolled it, please review.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

New feature will need test coverage. Tagging for that.

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.