Problem/Motivation

Search block form does not comply with W3C HTML validation:

"Bad value for attribute name on element input: Must not be empty."
…selector="edit-submit" type="submit" id="edit-submit" name="" value="Search" />

The name attribute is mandatory but can't be empty :
http://www.w3schools.com/tags/att_input_name.asp

The Views module exposed forms have the same problem.

The reason this happens is that both Search and Views are using a hack to the Form API to make it so that the internal form keys do not show up in GET URLs when the forms are used, something like this:

$form['actions']['submit'] = array(
   '#type' => 'submit',
   '#value' => $this->t('Search'),
   // Prevent op from showing up in the query string.
   '#name' => '',
);

Proposed resolution

Fix the form.inc code so that empty name attributes on buttons are not printed in the HTML.

Remaining tasks

Review and manually test the back port patch for Drupal 7.

User interface changes

Valid HTML for submit buttons used on GET forms that try to have clean URLs.

API changes

None.

Comments

Dom. created an issue. See original summary.

dom.’s picture

Status: Active » Needs review
StatusFileSize
new625 bytes

Before patch:

<input class="search-form__submit button js-form-submit form-submit" data-drupal-selector="edit-submit" type="submit" id="edit-submit" name value="Search">
W3C validation:
"Bad value for attribute name on element input: Must not be empty."
…selector="edit-submit" type="submit" id="edit-submit" name="" value="Search" />

After patch:

<input class="search-form__submit button js-form-submit form-submit" data-drupal-selector="edit-submit" type="submit" id="edit-submit" name="search-block-submit" value="Search">
=>W3C is now OK

NOTE: Please rebuild cache after applying patch when testing.

Status: Needs review » Needs work

The last submitted patch, 2: search_bock_w3c_validation--2637680--2.patch, failed testing.

The last submitted patch, 2: search_bock_w3c_validation--2637680--2.patch, failed testing.

dom.’s picture

According to code comments, this empty "name" attributes has been introduce to remove the action name from URL, but in the meanwhile, it is not valid. What is the correct approach, any other opinion ?
Should I just correct the URL in the test to have the "name" parameter in URL ?

nils.destoop’s picture

Imo, the url should stay as it's now.
Isn't it just an option to let the empty name stay, and make sure the name attribute isn't rendered when it's empty (for all elements, so not only this search submit)? This will prevent that other modules also introduce w3c invalid html.

mikeocana’s picture

Assigned: Unassigned » mikeocana

ill work on this

mikeocana’s picture

Status: Needs work » Needs review
StatusFileSize
new630 bytes

added the name attribute based on the standard name in drupal 8 to avoid empty #name.

'#name' => 'search_block_form_submit',

Status: Needs review » Needs work

The last submitted patch, 8: core-fix_search_block_name_empty-10683884-7-D8.patch, failed testing.

dom.’s picture

@mikeocana for #7: good idea.
@mikeocana for #8: indeed, better name.

We should push on the direction of #7 instead of #8 I think.

mikeocana’s picture

@dom, thank you.

more checking :)

cilefen’s picture

Issue tags: -php-novice, -html-novice

I marked this issue as related to #1366020: Overhaul SearchQuery; make search redirects use GET query params for keywords. Those following this issue should read that.

jhodgdon’s picture

Component: user system » search.module

Um, wrong component. ;)

So. The reason that we put #name='' is shown in the comment just before the patched line from #8 and reflected in the test failure. That is, we do NOT want the submit button showing up in the GET parameters.

This patch breaks that, and in fact having any name in there breaks that.

I do not think there is a way to have a non-empty name and avoid having an ugly search URL. So I think this is a Won't Fix. But if someone can figure out how to have the Search block pass w3c validation and still pass the test that checks that the search URL is clean, sure...

Maybe #6 will work? Try it...

laranajim’s picture

Assigned: mikeocana » laranajim
Issue tags: +CatalystAcademy

Unassigning @mikeocana as it has been a month without any activity. This will be my first patch for Drupal core.

laranajim’s picture

Assigned: laranajim » Unassigned
Status: Needs work » Needs review
StatusFileSize
new595 bytes

Hey @jhodgdon
I took a look at the code that generates the markup for the input fields. I was able to add some logic that will check for empty name attributes and if empty would remove them. I have run my code through the W3C validator to ensure the resulting HTML for the submit button is now valid.

This is my first patch to Drupal core.

dom.’s picture

Hi laranajim !
Congratulation for your patch !! I have tried it and it's okay to me, here is the reason why:

BEFORE:
Input button code:
<input class="search-form__submit button js-form-submit form-submit" data-drupal-selector="edit-submit" type="submit" id="edit-submit" name="" value="Search">
Attached is the W3C error corresponding.
The request for searching "foobar" in the search box is :
Request URL: http://.../search/node?keys=foobar

AFTER PATCH #8:
The request for searching "foobar" in the search box is :
Request URL: http://.../search/node?keys=foobar&search_block_form_submit=Search
which is not correct as per @jhodgon #13

AFTER PATCH #15:
Input button code:
<input class="search-form__submit button js-form-submit form-submit" data-drupal-selector="edit-submit" type="submit" id="edit-submit" value="Search">
No more error regarding this button in W3C validation.
The request for searching "foobar" in the search box is :
Request URL: http://.../search/node?keys=foobar

Thus #15 is RTBC for me.
NOTE: I still wait for unit tests to get green to actually flag the issue as RTBC.

However, arguably, I would change the following in your patch. For this reason, I'm attaching another patch here just in case others agrees with me. But if your patch is OK for others, let's go with it !

  1. +++ b/core/includes/form.inc
    @@ -325,6 +325,10 @@ function template_preprocess_vertical_tabs(&$variables) {
    +  // W3C requires name attributes, if present, to not be empty.
    

    Small typo here:
    "Remove name attribute if empty, for W3C compliance."

  2. +++ b/core/includes/form.inc
    @@ -325,6 +325,10 @@ function template_preprocess_vertical_tabs(&$variables) {
    +  if (isset($variables['attributes']['name']) && empty((string) $variables['attributes']['name'])) {
    

    For me, the cast in (string) is not necessary here since it has to be one. Anyway, 'empty' method allows other objects then string in case [name] could an array such as [class] is for instance.

wiifm’s picture

Hey @Dom,

I was helping @laranajim with this patch, and totally agree with your point #1, I will ensure a re-roll takes place tomorrow for this. As for point #2, $variables['attributes']['name'] is an object of type Attribute, the type cast seems to make it work reliably, but open to suggestions for ways to improve this (this is my first time working with this class).

Thanks for your time with the review! Very comprehensive.

dom.’s picture

@wiifm : Your are right, ['attributes']['name'] is generally a string as in D7, but in this case debugger says it is a "Drupal\Core\Template\AttributeString" (and I think it will/should always be this). Actually, my patch even don't work because of that: I did fucked up the review of my own patch ^^

So here is a patch with just first point included !

jhodgdon’s picture

Title: Search block submit button is not W3C valid » Search block submit button is not W3C valid due to empty 'name' attribute
Component: search.module » forms system

This patch looks like a good solution to me. It has rather far-reaching consequences though (way beyond the Search module), so I'm moving this into the Form component.

dom.’s picture

Tests are passing, so I guess the number of impacted empty name is quite low.

Actually a search for the various combinaison of 'name' => '', "#name" => '' and everything that can happen between the two using:
['"]#?name['"]\s?=>?\s?['"]{2}

gives me 12 occurences in core, most of it being in Tests, with the notable:

  1. SearchBlockForm.php line 108:
    $form['actions']['submit'] = array(
       '#type' => 'submit',
       '#value' => $this->t('Search'),
       // Prevent op from showing up in the query string.
       '#name' => '',
    );
    
  2. ViewsExposedForm.php line 112
    $form['actions']['submit'] = array(
       // Prevent from showing up in \Drupal::request()->query.
       '#name' => '',
       '#type' => 'submit',
      '#value' => $this->t('Apply'),
      '#id' => Html::getUniqueId('edit-submit-' . $view->storage->id()),
    );
    

It's the only two I could found about name attributs set to empty.

Patch for this issue will thus also make views with expose filters to be W3C valid.

jhodgdon’s picture

Title: Search block submit button is not W3C valid due to empty 'name' attribute » Submit buttons for GET forms in search/views are not W3C valid due to empty 'name' attribute
Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Thanks for the research! Updating title and issue summary, and I think this is RTBC.

BarisW’s picture

This is an issue in D7 too.

wiifm’s picture

Hey @BarisW, cool, let's backport to D7 after being committed to D8.

jhodgdon’s picture

So we should probably tag this issue as "needs backport to D7" and mark the other one as a duplicate then???

cilefen’s picture

Issue tags: +Needs backport to D7
cilefen’s picture

Issue tags: -Needs backport to D7

Maybe not - is the other issue fixed in Views?

jhodgdon’s picture

Issue tags: +Needs backport to D7

The idea would be to fix the underlying problem, which also exists in D7, and needs to be fixed in Core because it is a Core form API problem.

catch’s picture

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

Patch looks fine, but this could use automated testing.

jhodgdon’s picture

What do you suggest for additional automated testing? There is already quite a bit of testing of the Search form, which earlier patches failed (there are tests for instance that verify that the form ID stuff doesn't get into the URL when you submit the form with GET).

I don't believe we can test for W3C validity easily in an automated test...

dom.’s picture

@jhodgdon : I made the W3CValidator module. It could somehow be activated as part of Jenkins post-process tests for instance. Or we just taking the W3C processor part of this module and add it to the testing profile ?

jhodgdon’s picture

Maybe we could just make a short test for this particular issue that would verify that there is not an empty 'name' attribute in the form?

dom.’s picture

Status: Needs work » Needs review
StatusFileSize
new1.38 KB
new823 bytes

OK, trying here with a test checking that the input button does not have an empty name attribut.
The patch #32 is the same as the #18 + the #32--test-only

Status: Needs review » Needs work

The last submitted patch, 32: w3c_search_block_validation--2637680--32--test-only.patch, failed testing.

dom.’s picture

Status: Needs work » Needs review

test-only as failed for obvious reasons ! ^^
The 32.patch includes the test and validates. Thus, the test at least seems credible and submitted for humain reviewing.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me, thanks! Verified the tests failed/passed as expected.

BarisW’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/search/src/Tests/SearchBlockTest.php
@@ -45,6 +45,11 @@ public function testSearchFormBlock() {
+    $this->assertTrue(empty($elements), 'The search input field does not have empty name attribut.');

Minor typo (attributE).

dom.’s picture

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

Typo corrected.
Thanks @jhodgdon and @BarisW for review !

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

OK! Thanks BarisW for being more detail-spotting than the rest of us.

  • catch committed 12c2da9 on
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...

  • catch committed 3caa7b3 on
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...
catch’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!

maximpodorov’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new1.51 KB

This patch is a direct backport for Drupal 7.

Status: Needs review » Needs work

The last submitted patch, 42: w3c_search_block_validation-D7-2637680-42.patch, failed testing.

maximpodorov’s picture

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

The next attempt.

maximpodorov’s picture

Test only patch. Single failure is expected.
Oops. Something went wrong.

jhodgdon’s picture

Hm. Does Drupal 7 even have the same problem? Maybe not since the test didn't fail...

maximpodorov’s picture

The problem exists for Views exposed forms, see #2514028: Empty 'name' value for the exposed filter submit button.

maximpodorov’s picture

In D7, default value for 'name' attribute of a button is 'op', see system_element_info().
So, unless you specify it explicitly as empty string, the resulting HTML code is valid.
Views exposed forms do exactly this in views_exposed_form() function in order to "prevent from showing up in $_GET".
This means the test must contain creating a special form with a button having #name set to empty string.

jhodgdon’s picture

Status: Needs review » Needs work

Ah, so in D7 this problem doesn't affect the Search form I guess. Anyway, sounds like you know how to modify the test. Setting to Needs Work because the test needs work.

Collins405’s picture

Can confirm patch in #44 works nicely in 7. Thanks.

uzmaabdulrasheed1@gmail.com’s picture

Status: Needs work » Needs review
jhodgdon’s picture

Status: Needs review » Needs work

The test needs work. See earlier comments.

  • catch committed 12c2da9 on 8.3.x
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...

  • catch committed 12c2da9 on 8.3.x
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...
ollie222’s picture

Just a little more info on this as I've just come across the issue.

I have a views exposed filter with the name="" as expected. As discussed it doesn't pass W3C validation and I've also noticed that there is different behaviour between browsers.

On a windows machine Chrome doesn't include the button value in the search string but in IE it's included but without a name. For example with me it was appending &=Search in IE for the search button.

This means that as far as caching is concerned the pages are not the same and therefore need caching again.

For some reason it also means that return has to be pressed twice in IE when entering a search term.

The patch in #44 appears to fix all of the issues for me so it's a thumbs up from me.

tameeshb’s picture

Assigned: Unassigned » tameeshb

I'd like to take this up! :)

ollie222’s picture

I'd commented in #55 that

for some reason it also means that return has to be pressed twice in IE when entering a search term.

After more testing I don't think it's related to this issue and more to do with a browser quirk if you enter a term that has already been entered previously but I can't replicate it every time.

Either way it's not to do with the original issue.

  • catch committed 12c2da9 on 8.4.x
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...

  • catch committed 12c2da9 on 8.4.x
    Issue #2637680 by Dom., mikeocana, laranajim: Submit buttons for GET...
tameeshb’s picture

Are there any tasks left on this issue?

tameeshb’s picture

Assigned: tameeshb » Unassigned
danielveza’s picture

Whats the latest on this ticket. Looks like there has been commits but never marked as fixed.

We are seeing this on our distribution, just interested to know if this could be the issue or if this is considered fixed.

maximpodorov’s picture

Status: Needs work » Needs review

D7 should be fixed also.

Diane Bryan’s picture

Doesn't look fixed based on my WC3 site validation check, and yet supposedly catch has committed a fix. (#59)

volkswagenchick’s picture

Issue tags: +fldc19, +sfdug, +dcnj19

Tagging for upcoming contribution days.

altback’s picture

Issue tags: -Accessibility +accessibility

This issue still remains with drupal 8.6.8 and needs to fixed.
Here is the error I receive in w3c validator:

Error: Bad value for attribute name on element button: Must not be empty.

From line 207, column 300; to line 207, column 412

roup-btn"><button type="submit" value="Search" class="button js-form-submit form-submit btn-primary btn icon-only" name=""><span 
altback’s picture

This issue remain with 8.6.8 and needs to be fixed.

altback’s picture

Version: 7.x-dev » 8.6.8

w3c validation returns error :
Bad value for attribute name on element button: Must not be empty

altback’s picture

Status: Needs review » Needs work
altback’s picture

I tried a work-around for this issue. I am not sure if it is the right approach or not.

As the 'name' attribute is NULL for the html tag , it is causing the W3C validator to issue the following error:
Error: Bad value for attribute name on element button: Must not be empty.

In order to deal with it, I created a 'block--theme-search.html.twig' file in the templates folder of the sub-theme.
This overrides the core code.

I particularly removed the attribute 'name' and error is gone.

Here is code for the 'block--theme.search.html.twig' file:

<div class="search-block-form block block-search block-search-form-block" data-drupal-selector="search-block-form" id="block-simpleblogtheme-search" role="search">
  <h2 class="visually-hidden">Search</h2>
  <form action="/search/node" method="get" id="search-block-form" accept-charset="UTF-8">
    <div class="form-item js-form-item form-type-search js-form-type-search form-item-keys js-form-item-keys form-no-label form-group">
      <label for="edit-keys" class="control-label sr-only">Search</label>
      <div class="input-group">
        <input title="Enter the terms you wish to search for." data-drupal-selector="edit-keys" class="form-search form-control input-lg" placeholder="Search" type="search" id="edit-keys" name="keys" value="" size="15" maxlength="128" data-toggle="tooltip" />
         <span class="input-group-btn">
           <button type="submit" value="Search" class="button js-form-submit form-submit btn-primary btn icon-only">
             <span class="sr-only">Search</span>
             <span class="icon glyphicon glyphicon-search" aria-hidden="true"></span>
           </button>
         </span>
      </div>
    </div>
    <div class="form-actions form-group js-form-wrapper form-wrapper" data-drupal-selector="edit-actions" id="edit-actions"></div>
  </form>
</div>

As I mentioned earlier, I am not sure if its the right approach or not.
Needs to be tested and reviewed by the community.

tim.plunkett’s picture

Issue tags: -accessibility (duplicate tag), -CatalystAcademy, -fldc19, -sfdug, -dcnj19 +Accessibility

Fixing tags

andrewmacpherson’s picture

vacho’s picture

This issue does not apply for 8.6.x or 8.7.x. Definitely D8 does not present this issue.

chris burge’s picture

Version: 8.6.8 » 7.x-dev
StatusFileSize
new1.51 KB

I can confirm this issue does not exist in 8.5.x or higher. Setting back to 7.x-dev for back porting of patch. Patch #44 corrects the issue. Attached is a re-rolled copy against HEAD.

The test is no longer valid, however. Below is what the Search form markup looks like in 7.65:

<div class="form-actions form-wrapper" id="edit-actions"><input type="submit" id="edit-submit" name="op" value="Search" class="form-submit"></div><input type="hidden" name="form_build_id" value="form-fqsEapcJJVZpN9nno_Rkobvl6jJGPaxvHkJIS7TzY1Q">

Because of the change in the Search module, I tested with an exposed filter in views.

Leaving at Needs Work due to test coverage.

chris burge’s picture

D7 branch tests are failing. Test failures are unrelated to patch #74.

chris burge’s picture

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

Updated patch with updated tests.

mradcliffe’s picture

I removed the Needs issue summary update after a few tweaks. I also removed the Needs Accessibility Review tag because the approach is already in 8.1.x. Ideally the back port should now be a follow-up issue these days, which may be why there was some confusion.

joseph.olstad’s picture

Project: Drupal core » Bootstrap
Version: 7.x-dev » 7.x-3.x-dev
Component: forms system » Code
Status: Needs review » Needs work
Parent issue: #2467827: [META] W3C validation for Drupal Core » #3061891: Validate Attributes (W3C validation)

as per @alexpott #3061891: Validate Attributes (W3C validation)

This should be fixed in bootstrap, not core.

here is a bootstrap type of a fix that others have been using.

for more details, see @alexpott bootstrap patch and discussion in #3061891: Validate Attributes (W3C validation)

chris burge’s picture

Project: Bootstrap » Drupal core
Version: 7.x-3.x-dev » 7.x-dev
Component: Code » forms system
Status: Needs work » Needs review
StatusFileSize
new1.65 KB

The issue can be reproduced without Bootstrap. There are two parts to patch #76 - the bug fix and updated tests. We can verify this is a core issue by running tests on a test-only version of the patch. This patch should fail. I'm uploading a test-only version of #76 and setting the project back to D7 core to allow tests to run.

Status: Needs review » Needs work
chris burge’s picture

Tests failed, as expected:

Form API.FormsElementsLabelsTestCase.testFormLabels

fail: [Other] Line 847 of modules/simpletest/tests/form.test:
No name attribute found.

This result confirms this issue is a Drupal core issue. Without this patch theme_button() will render a name attribute with no value. Setting back to Needs Review. Patch #76 remains the latest patch for review/commit.

sjerdo’s picture

Status: Needs review » Reviewed & tested by the community

Patch in #76 LGTM +1

mcdruid’s picture

Issue tags: +Pending Drupal 7 commit

As mentioned in earlier comments, this doesn't seem to affect D7 core directly because it doesn't use an empty name attribute to avoid unwanted GET params, and core's search forms use POST.

So perhaps the "empty name hack" only applies to views in D7? (and possibly unknown other contrib modules, custom code etc..?)

https://git.drupalcode.org/project/views/-/blob/7.x-3.24/views.module#L2163

  // Form submit, #name is an empty string to prevent showing up in $_GET.
  $form['submit'] = array(
    '#name' => '',
    '#type' => 'submit',
    '#value' => t('Apply'),
    '#id' => drupal_html_id('edit-submit-' . $view->name),
  );

I'm not entirely sure we should be "fixing" this in core?

I've manually tested with a views exposed filter and confirmed that the empty name attribute is removed with the patch, and that the GET params when the search form is used are unaffected.

However, why was this hack put there in the first place then? Looks like without views setting an empty name, core provides a default name="op" which does then pollute the GET params.

(Sorry for probably going over old ground but restating this makes it easier to review a 80+ comment issue that dealt with D8 and then became a D7 backport).

So this change is probably okay for D7 core to make as it's effectively removing an artefact of a hack that contrib code does to avoid core's default behaviour.

fabianx’s picture

RTBC + 1, while not technically a core bug, core has always been friendly to contrib shenanigans :D.

There is no harm that I can see in removing an empty attribute and if themes are broken worst case can override theme_button() again.

  • mcdruid committed 2a225b2 on 7.x
    Issue #2637680 by Dom., maximpodorov, Chris Burge, mikeocana, laranajim...
mcdruid’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs backport to D7, -Pending Drupal 7 commit

Thank you!

Status: Fixed » Closed (fixed)

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