Drupal adds red asterisks to required form fields. It is usually customary that these asterisks would be explained somewhere on the page. They are not.

The default theming output for Drupal forms should check through the form array to see if there are required fields. If a required field exists, Drupal should output:

print '<p><span class="form-required">*</span>'. t(' indicates required fields') .'</p>';

...or similar.

CHX whipped up a quick recursive function that would test to see if there are required fields:

function drupal_form_has_required($form) {
  if (isset($form['#required']) && $form['#required']) {
    return TRUE;
  }
  foreach (element_children($form) as $key) {
    drupal_form_has_required($form[$key]);
  }
}

--untested

Don't have the time right now to work out the proper details for this, but I thought I'd put it up while I was thinking of it. This one has bothered me for a long time.

Comments

magico’s picture

Title: Forms Should Show Explanation of Required (*) Fields » Forms should show explanation of required (*) fields
Category: bug » feature

I totally agree, but this is not a bug.

LAsan’s picture

Version: x.y.z » 7.x-dev

Moving feature request to cvs.

black silence’s picture

just in case someone needs this...
hint: should be used within a hook_form_alter function

function drupal_form_has_required ($form) {
  if (isset($form['#required']) && $form['#required']) {
    return TRUE;
  }
  foreach (element_children($form) as $key) {
    if (drupal_form_has_required($form[$key])) {
      return TRUE;
    }
  }
}
karschsp’s picture

Issue tags: +Novice

Tagging for the novice queue

xano’s picture

In response to #3: why not put this into drupal_get_form(), which is used to render forms for display?

xmacinfo’s picture

Agreed, novices are often looking for the explanation of the (*) and they usually don't understand that they can get an explanation in a tool tip when hovering the cursor over the (*).

The “explanation” of required (*) fields should be displayed only once, either at the top of the form or at the bottom. Would a theme function let the themer position this explanation?

xano’s picture

We could also add a tooltip and a help cursor to the asterisks to explain what it means.

sun.core’s picture

Version: 7.x-dev » 8.x-dev
manuel garcia’s picture

Status: Active » Needs review
StatusFileSize
new22.14 KB
new3.43 KB

OK, well, here is a patch against HEAD, which might or might not get some love. I attach a screenshot of what it does.

Note that I'm not sure if the changes to form.test are correct, so please check it out if you know bout tests.

xmacinfo’s picture

Head is still D7 stuff, unless I miss something.

Also, looking at your screenshot, it's not what we are looking for.

We need to keep (*) for each required fields. However, at the top or the bottom, like a footnote, we need to define the meaning of the (*), which is “indicates required fields.”

manuel garcia’s picture

StatusFileSize
new22.02 KB
new1.85 KB

OK, I've taken the approach discussed earlier, introducing a new function, and using it on theme_form.

Attached the patch and screenshot. Note that I'm not touching any css from seven. We should first figure out the best way to do it. I'm just hoping this will help get the ball rolling.

We could perhaps only show the message through JS if the user starts using the form, or stuf like that... although not sure this is something core should do. In any case, please review =)

xmacinfo’s picture

Indeed, this is more in line with what we are looking for.

I've looked only quickly to the patch, though.

nevets’s picture

This should be able to disabled, while the message makes sense, not everyone wants it.

karschsp’s picture

Isn't it disable-able by unsetting $form['prefix']?

nevets’s picture

While it could be disabled unsetting $form['prefix'] it should be a setting.

karschsp’s picture

So, what/where would that setting be? admin/settings/forms "Display required fields message"?

I feel like it's best practice to indicate what the asterisks mean and it's rare that you wouldn't want to display it.

xmacinfo’s picture

@karschsp: If we need to create a setting for this, it should go in themes settings.

However, it's best practice to display the meaning of asterisks and agree that most users would not want to remove it.

For those users, they would still be able to hide it using CSS or $form['prefix'].

nevets’s picture

Both CSS and $form['prefix'] are "technical" approaches, not something the end user can control. There are plenty of sites that do not explain the asterisks (or their equivalent) and a lot of sites seem to be more minimalistic these days assuming users are familiar with input forms. Every time Drupal forces output on users, they make it harder for people have other approaches. I am just saying they should be able to choose if this shows or not through a setting.

manuel garcia’s picture

To me a setting just for this is a bit overkill for what it is. I dont think we should add a variable_get call for every form on your site just for this minor text. We are already adding a somewhat complex function call to every form just to check if we should display the text.

I'm still more fund of printing 'required' instead of '*' (#9), and forget about adding the new function etc, it'd be more lightweight, and is even clearer to the user. Even more, the fact that you pass 'required' through t(), means you could override that variable and have Drupal print there what you want, even just '*' if you so desired.

xano’s picture

We'd need a context then, something like "form_input_required".

pillarsdotnet’s picture

+1

Status: Needs review » Needs work

The last submitted patch, drupal-72197-2.patch, failed testing.

jnettik’s picture

So I tested out the patch in #11 and was getting an error for $form_prefix not being defined if there were no required fields. I've attached a patch that uses some of the code from the patch in #11 and checks to see if there are required fields before rendering the form as well.

As for a setting to hide the text, I don't see a problem with the solutions in #17.

jnettik’s picture

Status: Needs work » Needs review
acrollet’s picture

Status: Needs review » Needs work

I see a couple of small coding standards issues.

+++ b/core/includes/form.incundefined
@@ -3959,6 +3959,23 @@ function form_validate_url(&$element, &$form_state) {
+/*
+ * Returns TRUE if the form has any fields required.
+ *
+ * @param $form
+ *   The form to be checked for required fields.
+ */

The return param should be documented.

+++ b/core/includes/form.incundefined
@@ -3979,7 +4002,12 @@ function theme_form($variables) {
-  return '<form' . drupal_attributes($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  if($has_required) {
+    return '<form' . drupal_attributes($element['#attributes']) . '>'. $form_prefix .'<div>' . $element['#children'] . '</div></form>';
+  }
+  else {
+    return '<form' . drupal_attributes($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  }
 }
 
 /**

There should be a space after the if.

jnettik’s picture

Status: Needs work » Needs review
StatusFileSize
new949 bytes

Here's an updated patch.

Status: Needs review » Needs work

The last submitted patch, drupal_72197_code-formatting-documentation-fix.patch, failed testing.

jnettik’s picture

Here's the correct patch.

jnettik’s picture

Status: Needs work » Needs review
xano’s picture

Status: Needs review » Needs work

From a translation point of view I'd put the asterisk inside the translatable string using a placeholder for context purposes. The translatable string in your patch is totally weird on its own.

The last few lines of the patch can be shortened by setting $form_prefix = ''; by default, before checking if there are any required elements at all. This removes the need for the extra if-statement.

I haven't tested the patch, but apart from the aforementioned issues it looks good.

jnettik’s picture

Status: Needs work » Needs review
StatusFileSize
new1.72 KB

Here's the latest patch with the changes mentioned above. My only question would be, apart from including everything inside the t(), what benefit would using a wildcard for the asterisk have?

xano’s picture

Status: Needs review » Needs work

Using a wildcard for the asterisk provides more context for the translatable string. Compare

indicates required fields

!* indicates required fields

<div class="form-required-info"><span class="form-required">*</span> indicates required fields</div>

Which one looks easiest to translate and gives you the best idea of what the string actually means? It is a *bad* idea to translate partial English sentences, as other languages often use completely different structures and their translators need to know *exactly* what to translate. Also, putting unnecessary HTML in translatable strings only increases the risk of error (because the HTML from theme_wildcard() and the translatable string need to be identical) and makes strings look more complicated than they are to translators with no or little HTML experience.

jnettik’s picture

Thank you for your explanation. So is it ok to put the HTML in the value for the wildcard or is there another best practice for passing markup through the theme function?

xano’s picture

In this case I'd use a placeholder to ensure the required marker (asterisk) looks exactly as how it would appear in real forms.

jnettik’s picture

Status: Needs work » Needs review
StatusFileSize
new1.76 KB

Ok so I pulled the asterisk out into a placeholder as well as any markup that was used the style it. But I left the markup that's supposed to exist for the whole field. I think pulling that out into the placeholder would be confusing because I'd need to create another placeholder for the closing div. The other approach could be be to pull the .form-required-info div out of t() altogether.

jnettik’s picture

StatusFileSize
new1.77 KB

Did some looking around some of the core files and noticed that HTML was typically pulled out of t(). Here's another patch with the markup pulled out completely.

xano’s picture

Status: Needs review » Needs work
+++ b/core/includes/form.inc
@@ -3990,6 +4010,14 @@ function form_validate_url(&$element, &$form_state) {
+    $form_prefix = '<div class="form-required-info">' . $t('!* indicates required fields' . '</div>', array(

The </div> should be outside the $t call.

I don't really know theme_form(), but what if we add the explanation to $form['#prefix'] and let drupal_render() to the rest?

Gaelan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.77 KB

Updated patch. However, I think we should make the message more subtle.

jwilson3’s picture

Status: Needs review » Needs work
+function drupal_form_has_required ($form) {

Shouldn't be a space between function name and arguments.

+// This is also used in the installer, pre-database setup.

I really hate this comment (I know its used elsewhere), to me "// Ensure translations don't break at install time." is clearer.

-  return '<form' . drupal_attributes($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  return '<form' . drupal_attributes($element['#attributes']) . '>'. $form_prefix .'<div>' . $element['#children'] . '</div></form>';

Does anyone know the intended *use* of the classless <div> inside all Drupal forms? It seems like if anything this prefix message should be inside this div, not a sibling to it. Also, couldn't this be added as a #markup element to the form, to expose it to form alter hooks before rendering?

nielsonm’s picture

Here's a reroll of the patch, hopefully with no more coding standards issues. I've also back-ported this patch to D7.

xmacinfo’s picture

Status: Needs work » Needs review

Please upload a D8 only patch for the bot. :-)

Status: Needs review » Needs work

The last submitted patch, explain_required_D8-72197-40.patch, failed testing.

nielsonm’s picture

A different approach could involve adding 'Required' to required fields and hiding the output. This would allow screen readers (specifically JAWS) to read the form label and notify the user that the field is required. I also included a d7 patch.

xmacinfo’s picture

Status: Needs work » Needs review

Calling the bot.

Status: Needs review » Needs work

The last submitted patch, explain-required.43.72197.patch, failed testing.

nielsonm’s picture

StatusFileSize
new1.27 KB

Changed test to match new text.

nielsonm’s picture

Status: Needs work » Needs review
dastagg’s picture

** Novice attempt at fixing this **

I am resubmitting this patch which combines #40 and #46.

#40 actually creates the text on the page.
#46 updates the tests so they don't fail.

I applied the combined patch against an existing installation and checked. Then I created a new installation and checked as I was installing.

dastagg’s picture

Status: Needs review » Needs work
StatusFileSize
new133.61 KB

Upon further review the "* indicates required fields" is showing up on the admin/structure/block which does not have any "required fields".

The block "Main page content" is considered "required" but this is not marked with an "*"

  // Do not allow disabling the main system content block when it is present.
  if (isset($form['blocks']['system_main']['region'])) {
    $form['blocks']['system_main']['region']['#required'] = TRUE;
dastagg’s picture

Issue tags: -Novice

Removing the Novice Tag. I think this one will require a little more experience.

manuel garcia’s picture

nice catch @dastagg on #49. If we have cases like that around.... what should we do, run a grep on all core checking for '#required', find those that should be called something else semanticaly, and propose a change in that direction? Not a novice task, and not sure it's worth the effort if it's just for this change.

Also, I feel things will get messy if we start adding exceptions to the drupal_form_has_required function...

Does anyone see a clean way to go with this?

tstoeckler’s picture

+++ b/core/includes/form.inc
@@ -4188,6 +4208,14 @@ function form_validate_url(&$element, &$form_state) {
+    $form_prefix = '<div class="form-required-info">' . $t('!* indicates required fields' . '</div>', array(
+      '!*' => '<span class="form-required">*</span>',

Sorry, I saw that this was discussed above, but please don't put the HTML in a placeholder. Placeholders are for dynamic content. I realize that HTML in translatable strings is not ideal, but it's what we do elsewhere as well.

+++ b/core/includes/form.inc
@@ -4431,7 +4459,7 @@ function theme_form_required_marker($variables) {
-  return '<abbr' . drupal_attributes($attributes) . '>*</abbr>';
+  return '<abbr' . drupal_attributes($attributes) . '><span class="element-invisible">Required</span>*</abbr>';

In how far is this change related to this issue? (Sorry, I didn't read the entire issue.)

Regarding the blocks admin page, we should probably remove the #required for now, and add a custom validation callback. Hmm...

mgifford’s picture

Issue tags: +Accessibility

I thought we'd already dealt with this. Dug into old issues:

http://drupal.org/project/issues/drupal?text=abbr+*&status=All&prioritie...

At least needs reference back to:
#1162802: Asterisk * used for required or changed marker should be in abbr not span

Also tagging.

EDIT: Adding useful link on required fields best practices - http://simplyaccessible.com/article/required-fields-right/

bowersox’s picture

StatusFileSize
new36.85 KB

Let's step back and clarify what is needed here. There seems to be confusion and @mgifford is correct that we already dealt with a lot of this.

When it comes to visual instructions appearing on a page, the solution would be to add instructions at the top of the form. On any form that has at least one required field, we could add the words "Required fields are marked with *" at the top. Doing that might help some users who don't know the convention that the asterisk means "required". This would help us to strictly meet the WCAG item 3.3.2. You could also argue that most people already know what the asterisk means in this context.

Other than that, issues with required fields have already been solved. For sighted mouse users, there is already a tooltip if you mouse over the asterisk (screenshot attached). For screenreader users, there is already ARIA and HTML5 markup identifying the field as required:
required="required" aria-required="true"
JAWS 13, for example, reads these fields out loud as required.

Please correct me if you disagree. Let's get clear on what we're trying to achieve here.

mgifford’s picture

Status: Needs work » Closed (works as designed)

Following up from @bowersox, I'm going to say that "most people already know what the asterisk means in this context."

I don't think adding additional text on the page to explain what the red * is will provide much of an accessibility improvement, but it will slightly degrade usability by simply adding more text on the screen.

The convention of using a * is very prevalent.

This issue can certainly be re-opened, but that should come with some external references to indicate how this benefits users.

liam morland’s picture

rooby’s picture

Version: 8.0.x-dev » 8.6.x-dev
Category: Feature request » Bug report
Status: Closed (works as designed) » Active

Could this be revisited, even if only to have a more recent record of it being deemed unnecessary?

I've recently had a third party accessibility review done that has pushed the point on this one, although personally I agree with the previous decision in this issue.

It relates to WCAG success criterion 3.2.2.
More specifically, the techniques G131: Providing descriptive labels and H90: Indicating required form controls using label or legend.

Since it states that it is sufficient to use G131 and any one of its sub-items, G83: Providing text descriptions to identify required fields that were not completed is also relevant since we do that.

Malkiyahu’s picture

This issue is addressed by WCAG Success Criterion 1.3.1: Info and Relationships. It is the first example they give there.

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

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.

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

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.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.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.

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.

pameeela’s picture

Status: Active » Closed (works as designed)
Issue tags: +Bug Smash Initiative

I'm marking this closed again since it was mgifford who originally closed it and rejected the idea of adding text to the form. The request for more information is 3 years old now and there has been no additional activity.

I note we are already including aria-required="true", in addition to the asterisk.

I think that if anyone has suggestions to improve the accessibility of forms in core, we would do better creating a new issue with an updated context.