Problem/Motivation
If a datetime field is invalid, the error message is too generic. It is unclear what field is incorrect, especially if there are multiple datetime fields on the entity (color alone is not sufficient).
This is a bug because
- Incorrect or misleading user interface text
and would qualify for an 8.1.x minor release.
Proposed resolution
Update error message for invalid datetime fields to include the field label.
Remaining tasks
Add test coverage for date-only fields.
User interface changes
Better error messages for invalid datetime fields.
API changes
None.
Data model changes
None.
Original Report
The validation handler for datelist \Drupal\Core\Datetime\Element\Datelist::validateDatelist
form element has wrong error messages.
$form_state->setError($element, t('The %field date is required.'));
and
$form_state->setError($element, t('The %field date is invalid.'));
Comment | File | Size | Author |
---|---|---|---|
#60 | interdiff.txt | 1.88 KB | pfrenssen |
#60 | 2486019-60.patch | 15.87 KB | pfrenssen |
#42 | 2486019-42.patch | 875 bytes | michielnugter |
#42 | interdiff-35-40.txt | 0 bytes | michielnugter |
#40 | 2486019-40.patch | 538.64 KB | michielnugter |
Comments
Comment #1
Anonymous (not verified) CreditAttribution: Anonymous commentedComment #3
iMiksuComment #4
iMiksuBefore this patch, the test of creating datetime field entity was passing nicely.
After this patch, Drupal is throwing an error (in
\Drupal\datetime\Tests\DateTimeFieldTest::testDatelistWidget()
) when testing creating an entity with datetime values:Screenshot of the output given on failure:
Comment #5
maris.abols CreditAttribution: maris.abols commentedComment #6
maris.abols CreditAttribution: maris.abols commentedPrevious patch returned multiple errors instead of just one. I created this patch and ran tests for DateTimeFieldTest and everything seems to be ok.
Comment #7
maris.abols CreditAttribution: maris.abols commentedComment #8
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedI think the bug is in the datetime widget itself, because the "Authored on" form element on the node form works fine without any errors.
Comment #9
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedComment #10
hauruck CreditAttribution: hauruck at UEBERBIT GmbH commentedThe test for TimeDateField has been update to include the missing field name. Current test skips over the first part of the error message to ignore this core bug.
Comment #12
webflo CreditAttribution: webflo at UEBERBIT GmbH commentedComment #13
mpdonadioReassigning this to datetime.module as it looks like a bug with it. This may be related to a patch where some of the logic where the widget changed, but I need to dig to find the issue.
Comment #14
mpdonadioJust stripping out the test changes to make sure the changes do catch the bug.Because of the patch this is an invalid test-only patch. Manual testing is needed to demonstrate the problem.
Comment #16
mpdonadioBack to NR.
Comment #19
mpdonadioRetesting to see where this lands w/ 8.1.x. May or may not conflict with #2696353: Bad dates in Select List widget throw an exception.
Comment #21
mpdonadioBack to NR. Will look closer at this, but
I think with the expected string we are testing for, we want to use t() instead of format_string(). Also elsewhere.
I think the format_string() in the messages is overkill. We can just say ''Invalid year failed validation.' or similar. Also elsewhere.
Comment #22
mpdonadioThe expected strings should use t() and not format_string(). That is the general convention in tests. This happens several times in the patch.
While we are at it, we should update DateTimeFieldTest::testInvalidField() to check for the updated error message on date-only fields to prevent regressions.
This one is a little hard to test. Using FF and disabling Javascript to prevent the datepicker polyfill is the best way to manually tests this.
Comment #23
mpdonadioComment #25
mpdonadioRe-roll against 8.2.x.
Comment #26
jhedstromWow, that's a pretty big oversight indeed!
Fix looks good to go.
I agree this is a bug and should be considered for a minor release of 8.2.x.
Comment #27
xjmThanks all!
Instead of using the deprecated
format_string()
, we can just concatenate strings inline, since this is an assertion. See #2549805: Remove all usage of FormattableMarkup in tests apart from explicit tests of that API. (Also, a separate message assertion parameter is usually not useful withassertText()
anyway since it is redundant and obscures the actual validation message, but that's not introduced here.)Are these bits a required part of the fix?
Comment #28
mpdonadioThis backs out the theme changes; the test changes are not in this.
Pretty sure it will fail b/c
However,
entangles this with #2788359: datetime_wrapper improperly applied to DateTimeWidgetBase and/or #1918994: Improve Datetime and Daterange Widget accessibility. I think we may want to postpone on the first of those.
Comment #30
mpdonadioPostponing on #2788359: datetime_wrapper improperly applied to DateTimeWidgetBase
Comment #32
miax CreditAttribution: miax commentedI needed this patch for Drupal 8.3. So i fixed the patch to work with that release.
I also added t() function to the placeholder %part in the setError message since this value was never translated to another language.
I know this issue is postponed but I needed this and maybe this patch will help someone =)
Comment #33
mpdonadioThis is good to work on again, I missed it in my sweep of #2788359: datetime_wrapper improperly applied to DateTimeWidgetBase and #1918994: Improve Datetime and Daterange Widget accessibility.
The patch in #28 should be rerolled, as that has the tests. Then we can look at #32.
Comment #34
jofitz CreditAttribution: jofitz at ComputerMinds commentedRe-rolled.
Comment #36
mpdonadioWe can just sprintf() these since we are trying to avoid these formatting functions in tests now.
Didn't look into why we still have a fail. I suspect we also want to add test coverage to DateRangeFieldTest.
Comment #37
mian3010 CreditAttribution: mian3010 commentedRerolled #28 on to make it apply in 8.3.x
Comment #38
Vinay15Comment #40
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedThe test changes were unrelated to the applied fix, I removed them and the test now passes. Test was moved to PHPUnit as well in the mean time.
I do think we need test coverage for the change to verify the label is now shown, only setting to needs review now to see if the test-bot agrees with the patch passing.
Interestingly though the element label for the invalid dates is not shown either right now, the placeholder in the HTML is empty:
Is the issue bigger or the test-case not good enough?
Comment #42
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedSorry, garbage patch.
Comment #43
jhedstromFix in #42 has lost the tests from above.
Comment #44
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented@jhedstrom That was on purpose as my comment stated: the test changes were unrelated because the changes tested another area. It still needs tests though but at the moment I'm too busy with the PHPUnit initiative.
Comment #45
mpdonadioWorking on this. The current fix only covers part of the problem and am adjusting the tests.
Comment #46
mpdonadioShould be green. There is probably a better way to get the field name in the $element here, but I am spacing. Also not 100% sure this will interfere w/ plain FormAPI usage of this.
The path through the invalid date logic requires a form alter to get past the option validation in order to generate an invalid date via the widget. Don't think this is worth it.
Comment #47
jhedstromThis looks good to me. One tiny nit:
Stray debugging code here.
Comment #48
mpdonadioOops.
Comment #50
mpdonadioBack to NR. CI error was was from one of the know, but fairly rare, PHP segfaults.
Comment #51
pfrenssenFrom looking at the code it appears this uses the machine name of the field in the error message that is presented to the user. It will look something like:
This is confusing to end users since the text
field_event_dates
is not visible in the page, the actual title will be something human readable like "Event date". We should use the human readable field title if possible.Comment #52
pfrenssenComment #53
pfrenssenI looked into this but the machine name being used instead of the human readable name appears to be a separate issue that pervades the entire datetime module. The other field formatters and error messages are also affected by this. This hasn't been detected before since in
DateTestBase
the same name is used for both the machine name and the human readable name when the field configuration is created :(I will make a separate issue to use the human readable name in all error messages.
This means this issue is good to go. I reviewed the code and it looks good. I wasn't entirely sure about the language used in the error message, I would have chosen "The date for the %field field is incomplete/invalid" instead of "The %field date is incomplete/invalid". But since this has been written by native English speakers my suggestion is probably worse :)
Comment #54
pfrenssenComment #55
pfrenssenI had a go at #2876047: Correctly mention field labels in form validation error messages and it is actually possible to use the human readable names in this issue too without affecting the other field type, since they are in separate classes.
Fixed the patch to use the human readable field name rather than the machine name.
Comment #56
mpdonadioSa-weet. Do we want to move this logic to DateElementBase so we can reuse it in #2876047: Correctly mention field labels in form validation error messages?
Comment #58
pfrenssenOh yeah that is a really good idea, we can create a helper function for it and reuse the code!
I see that I missed one test too, it also needs to be updated to use the
$field_label = $this->field->label();
when checking the label of the fieldset.Comment #59
pfrenssenComment #60
pfrenssenOne more test fix.
Comment #61
pfrenssenI postponed #2876047: Correctly mention field labels in form validation error messages on this issue since so it will be able to reuse the method on
DateElementBase
that @mpdonadio proposed in #56.Comment #63
jhedstromI think this is good to go. Thanks!
I like the use of proper upper case style standards =)
Comment #65
catchCommitted fde3369 and pushed to 8.4.x. Thanks!
I'm not 100% sure on a backport to 8.3.x here. The string changes/additions are probably fine because it's explicitly fixing broken strings, and the new protected static method should also be OK, moving to RTBC against 8.3.x for now and will have a think.
Comment #67
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented8.3 stil green, back to rtbc
Comment #68
catchDiscussed about backporting this. It's a new method on a base class, so to backport to 8.3.x we'd have to inline that logic, which is a fair bit of work/thought for a backport compared to cherry-pick. Given that, moving back to 8.4.x and fixed.