I’m completely new to Elm and are reading through the guide. In the Maybe chapter there is an exercise where one task is to put a red border around an invalid input.
Unfortunately elm/html does not have a DOM method primitive.
The problem with using Html.Attributes.property "setCustomValidity" (JSON.Encode.string e), is that Html.Attributes.property generates a setter that not only is not working but overwrites setCustomValidity() so it does not work for any JS on the page.
I think it will require using ports or a custom element to access that API. A custom element could wrap up the logic nicely, but for this use case I would recommend making your own error view in vanilla Elm if that is an option.
The ports are a decent bit of cognitive overhead, and the custom element can be too if you don’t already use them in the app, and the error view is much simpler.
I think that, with my current speed of learning, ports and custom elements are a few days out. But I can revisit my code when I get to those.
I also searched a bit for Elm packages and there is quite a few that are validation oriented. But I could not understand, with my current knowledge, if they would enable reading / setting validity.
Do you know any packages for that? I rather start out with a package than spend time re-inventing the wheel, if someone already worked on this.
For now, I can definitely use Elm and CSS but I like to use DOM API’s as they generally work much better across devices (e.g. mobile, watch etc).
Unfortunately I don’t think you will find any packages that use the validity API as it will require ports, the main options from the Elm side are going to be the pattern and required attributes, as well as ARIA for assisive technologies.
Elm is not treating DOM objects as the mutable nodes they are. Elm has this immutable abstraction of a node and it’s doing the mutations in a virtual dom implementation.
So, anything that looks like a mutation of the DOM is going to be achieved either by having the view be different in such a way that the virtual DOM generates that mutation OR through ports.
Your use-case here is actually more challenging than expected.
My experience with HTML5 validation in JS projects is that it sounds super nice first, but then never works exactly how you’d like and is full of edge cases and workarounds.
I do not fully understand. So what you are demonstrating is that it does not work?
This actually looks very nice. The only added line, to a normal Elm app, is port setValidity : { id : String, validity : String } -> Cmd msg as far as I can see. On the JS side, the amount of code is similar, or a little less, to what I would have written without Elm.
Sorry for the confusion. Yes, in that example I’ve shown you how it would have looked if it would have worked. As you can see… it is not a lot of code. To be honest, I fully expected that example to work and when it didn’t, I researched a little bit and I’ve found the issue that I linked. None of the custom elements that I use in my app are extending already existing input elements.
I have had a somewhat similar experience but categorize it into two different cases.
There is a designer who has designed the validation experience. E.i. colors, popups. etc. Or I want to play the designer and display a custom error design.
No error handling has been designed at all.
In the first case, always use text input and perhaps password but nothing else. If you do, then you will be fighting a long, long and surprising battle against browser behavior and CSS. Especially the CSS will not be documented and you might not even be able to override it… And then some Samsung browser comes along and does it a little bit different but enough to break the design. I have even used <div> with great success and implemented everything from scratch. No browser can f*** that up!
In the second case, use all of the HTML5 goodies. Save a week from not re-implementing that datepicker in corporate branding and simplify everything for the back-end folks. Have great accessibility across desktops, game consoles, watches, mobile, TV - you name it! Screen readers? Colorblind? WCAG 2? Keyboard shortcuts? Bring up the right smartphone keypad? Impossible form factors? No sweat - it is all taken care of. But accept this: YOU DO NOT CONTROL HOW IT WILL LOOK.
I appreciate your ingenious (but brittle) way of extending the DOM! It works fine in gecko while blink is ignoring it.
It is also very nice for me to see examples like this (and all of the examples in this thread). I feel it provide’s me real world examples of some of the Elm operators, that so far, has not been covered in the Elm guide.
I will save a list of all of them for future reference - thanks!
I’m currently collecting similar examples like this for a reference page! I’ll probably post a link on Discourse once I wrote some real documentation (mostly warnings) for these.
I use Firefox as my main browser, but I checked it before in Chrome. It seems to set the properties correctly (validationnMessage and validity). Maybe Chrome is not applying default styling to it? The MDN example also does not seem to have styling in Chrome
Yet a way of doing it would be do add data-validity="Whatever message" to your <input>, and call .setCustomValidity with the contents of that attribute via a MutationObserver. I use this at work to call .showModal() on <dialog data-state="modal|closed"> elements.
I’d recommend against using the is syntax if you need to support Safari as well, they don’t support customizing built-ins.
What we have been doing at work for elements that don’t need to actually add/replace children is render the elements inside the custom element, and then look them up.
For this module it would probably go in ValidInput.elm and you might expose it with an API using the “unAttr” pattern like Ellie does to restrict the public API
validInput: Model -> Html Msg
validInput model =]
ValidInput.view
[ ValidInput.validity "custom validity message"
, ValidInput.value model.value
, ValidInput.onChange SetValue
]
The ValidInput module would make sure that an input is rendered, that attributes/properties are encoded correctly, etc.