xmlet/HtmlFlow

Input attribute checked=false|true not compliant

black-inc-service opened this issue · 3 comments

.input().attrType(EnumTypeInputType.CHECKBOX).__()
.input().attrType(EnumTypeInputType.CHECKBOX).attrChecked(false).__()
.input().attrType(EnumTypeInputType.CHECKBOX).attrChecked(true).__()

Produces

<input type="checkbox">
<input type="checkbox" checked='false'>
<input type="checkbox" checked='true'>

The browser shows:

[ ] //empty
[x] //checked='false'
[x] //checked='true'

Looking at https://validator.w3.org/#validate_by_input

It reports: Error: Bad value false for attribute checked on element [input](https://html.spec.whatwg.org/multipage/#the-input-element)

Looking into the spec: for a checked input there should be an empty check attribute, unchecked should not be present.
I have a workaround by conditionally adding this attribute

.of(a -> if (wantToCheck) a.attrChecked(true););

Is this intended behaviour?

That's tricky. In truth the checked attribute is boolean according to HTML specification. And, since HtmlFlow API is designed to comply with the HTML specification, then the signature for attrChecked(boolean) method is correct. Thus, the HTML produced by your sample is correct too.

However the resulting behaviour is that you described such as, when checked is present, regardless its value, it specifies that it should be pre-selected (checked) when the page loads.

Thus, your workaround is also correct.

If performance is a concern, then you have also another alternative in HtmlFlow using the .dynamic(...) builder rather than `of(), which is only valid for dynamic views. You should read documentation about it to take advantage of that feature. Also the dynamic feature has changed a bit between version 3 and 4 of HtmlFlow.

Is it possible to extend the API?
Leave attrChecked(boolean) as before and add attrCheckedInclude(boolean) or something named appropriate
I have a workaround for this in the meantime.

public class HTML {
	public static Input<?> check(Input<?> input, boolean checked) {
		if (checked) {
			return input.addAttr("checked", "");
		}
		return input;
	}

	public static Option<?> option(Option<?> option, boolean selected, boolean disabled) {
		if (selected) {
			option = option.addAttr("selected", "");
		}
		if (disabled) {
			option = option.addAttr("disabled", "");
		}
		return option;
	}
}

Use:

.input().attrType(EnumTypeInputType.CHECKBOX).attrName("tab").of(i -> HTML.check(i, isSelected)).__()

Also affects Options, probably others as well

@black-inc-service HtmlFlow API is automatically generated through an ASM pre processor included in our project XsdAsmFaster that generates the API from a XSD file with the HTML 5 specification.

That's why we have included the custom of(... -> ...) builder in the API, since we cannot easily add new extensions. The of(... -> ...) let programmers fluently interleave any statement according to their needs.

IMO your workaround is appropriated for your need and your solution seems perfectly fine.