We are using grunt-html-angular-validate
package for HTML lints. It uses W3C online validator tool under-the-hood and, so far, it did a great job in validating our angular templates.
Today, it failed while checking the latest changes pulled from the repository with the following error:
Validating src/login/login.html ...ERROR [L37:C108]
Bad value {{regCodeRequired}} for attribute autofocus on element input.
Here are the related lines where it fails:
<div class="auth-reg-code-block" ng-if="regCodeRequired">
<input class="form-control" type="text" name="regCode"
id="regCode" ng-model="user.regCode" autofocus="{{regCodeRequired}}"
placeholder="Registration Code" required>
</div>
This is basically a field for entering a registration code for the two-factor authentication. regCodeRequired
is a boolean variable that is set to true
once the user passed the first login/password authentication step.
And I see the input appearing with a focus on it (using chrome 39) - it is working.
Question:
I'm pretty sure there is a reason for the validation tool to plain, but I'm not sure how to proceed. Are we using autofocus
attribute incorrectly? How should we fix the validation error?
I've looked through the W3C validator errors trying to find an explanation, but there is nothing about autofocus
there. Also, nothing inside the w3cjs
github repository.
Here is the grunt configuration for htmlangular
:
htmlangular: {
options: {
relaxerror: [
'Element head is missing a required instance of child element title.',
'Attribute href without an explicit value seen.',
'& did not start a character reference.',
'not allowed on element form at this point.',
'not allowed as child of element',
'Element img is missing required attribute src.'
],
reportpath: null
},
all: [
"<%= app.src %>/*.html",
"<%= app.src %>/**/*.html"
]
}
Would appreciate any pointers.
We are using grunt-html-angular-validate
package for HTML lints. It uses W3C online validator tool under-the-hood and, so far, it did a great job in validating our angular templates.
Today, it failed while checking the latest changes pulled from the repository with the following error:
Validating src/login/login.html ...ERROR [L37:C108]
Bad value {{regCodeRequired}} for attribute autofocus on element input.
Here are the related lines where it fails:
<div class="auth-reg-code-block" ng-if="regCodeRequired">
<input class="form-control" type="text" name="regCode"
id="regCode" ng-model="user.regCode" autofocus="{{regCodeRequired}}"
placeholder="Registration Code" required>
</div>
This is basically a field for entering a registration code for the two-factor authentication. regCodeRequired
is a boolean variable that is set to true
once the user passed the first login/password authentication step.
And I see the input appearing with a focus on it (using chrome 39) - it is working.
Question:
I'm pretty sure there is a reason for the validation tool to plain, but I'm not sure how to proceed. Are we using autofocus
attribute incorrectly? How should we fix the validation error?
I've looked through the W3C validator errors trying to find an explanation, but there is nothing about autofocus
there. Also, nothing inside the w3cjs
github repository.
Here is the grunt configuration for htmlangular
:
htmlangular: {
options: {
relaxerror: [
'Element head is missing a required instance of child element title.',
'Attribute href without an explicit value seen.',
'& did not start a character reference.',
'not allowed on element form at this point.',
'not allowed as child of element',
'Element img is missing required attribute src.'
],
reportpath: null
},
all: [
"<%= app.src %>/*.html",
"<%= app.src %>/**/*.html"
]
}
Would appreciate any pointers.
Share Improve this question edited Jan 22, 2015 at 21:31 alecxe asked Jan 11, 2015 at 5:03 alecxealecxe 474k127 gold badges1.1k silver badges1.2k bronze badges 8-
2
Couple of sanity checks for you: you have only one
autofocus
attribute specified in your document at one time; you are setting the attribute value to "" (empty string) or "autofocus" (to representtrue
), or are not setting the value at all (e.g.<input ... autofocus>
) (any other values are invalid). Perhaps the validator is confused with the angular syntax because it isn't expecting an explicit value? – Cᴏʀʏ Commented Jan 11, 2015 at 5:14 -
i might be wrong, but have you tried
ng-autofocus
– mido Commented Jan 11, 2015 at 5:15 -
@Cory thanks for the inputs.
autofocus
is set only on this input and the value is getting set totrue/false
- at least, this is not right. But, this is static analysis, it cannot know what the value of the scope variable would be - I suspect it doesn't like the angular syntax there.. – alecxe Commented Jan 11, 2015 at 5:25 - @Cory if you would elaborate more on how to proceed to fix the error, it can be a legitimate answer here. Thank you! – alecxe Commented Jan 11, 2015 at 17:44
-
It looks like grunt-html-angular-validate module is running the validation before the angular digest cycle gets applies to the template, that's why it is trying to validate the unprocessed statement
{{regCodeRequired}}
instead of the processed value true or false. Can you provide the code for your initConfig? Did you check ifoptions.angular
is set to true in your initConfig? – JoMendez Commented Jan 21, 2015 at 16:50
2 Answers
Reset to default 8 +50According to the specs, the autofocus
attribute is a boolean attribute:
A number of attributes are boolean attributes. The presence of a boolean attribute on an element represents the true value, and the absence of the attribute represents the false value.
If the attribute is present, its value must either be the empty string or a value that is an ASCII case-insensitive match for the attribute's canonical name, with no leading or trailing whitespace.
The values "true" and "false" are not allowed on boolean attributes. To represent a false value, the attribute has to be omitted altogether.
The last paragraph pretty much explains why the validator is plaining.
In other words, you can replace
<div class="auth-reg-code-block" ng-if="regCodeRequired">
<input class="form-control" type="text" name="regCode"
id="regCode" ng-model="user.regCode" autofocus="{{regCodeRequired}}"
placeholder="Registration Code" required>
</div>
with:
<div class="auth-reg-code-block" ng-if="regCodeRequired">
<input class="form-control" type="text" name="regCode"
id="regCode" ng-model="user.regCode" autofocus
placeholder="Registration Code" required>
</div>
You might be interested in ng-autofocus plugin.
Try to put the angular option explicitly to true in your configuration (this should enables the process (digest) of the angular bindings {{}} and {{regCodeRequired}} should be substituted for the value of the variable regCodeRequired before it validate the html):
htmlangular: {
options: {
angular: true, //per documentation: Turns on ignoring of validation errors that are caused by AngularJS.
relaxerror: [
'Element head is missing a required instance of child element title.',
'Attribute href without an explicit value seen.',
'& did not start a character reference.',
'not allowed on element form at this point.',
'not allowed as child of element',
'Element img is missing required attribute src.'
],
reportpath: null
},
all: [
"<%= app.src %>/*.html",
"<%= app.src %>/**/*.html"
]
}
If this doesn't works then you'll need to treat this parameter as a custom directive:
options: {
customattrs: ['autofocus']
//...
}
Per documentation: https://www.npmjs./package/grunt-html-angular-validate
options.customattrs
Type: Array Default value: []
List all of the custom attributes you have created through directives and other means here. The validator will ignore warnings about these attributes.
You can use the * wildcard, e.g.: 'custom-attrs-*'