In simple html js applications when I need to open dialogues of some interactive input elements (such as input[type="file"]
or input[type="date"]
or input[type="color"]
) any non-standard way (with a button or on page load) the most strait forward way is to trigger click
event on above mentioned elements. But I couldn't find a way to do that in pure elm (without ports). I see for DOM events manipulation there is focus
trigger, but no click
. Am I missing something? Is it not the "elm way" of doing things?
CodePudding user response:
You can (ab)use the way Html.attribute
can take an arbitrary string (i.e. Html.attribute "onclick" "javascript:someFunction(this)"
). In some cases, this is reasonable since it can provide the least amount friction. For example, if you're wanting a button that focuses a hidden file input, and it's wrapped up nicely in a component/view file that where it's always a button followed by a file input, this makes sense:
import Html exposing (..)
import Html.Attributes as Attr exposing (..)
import Html.Events exposing (on)
filePick : Html msg
filePick =
div [ class "file-pick-wrapper" ]
[ button
[ type_ "button"
, attribute "onclick" "javascript:this.nextElementSibling.click()"
]
[ text "Choose a File" ]
, input
[ type_ "file"
, on "change" someMsgDecoder
, style [ ( "display", "none" ) ]
]
[]
]
From there you can have the someMsgDecoder
use Json.Decode
to read at [ "target", "files", "0", "name" ]
for the filename.
CodePudding user response:
Reading throught the MDN on File
element I saw they suggest to use <label>
to trigger the element without JavaScript
:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<label for="fileElem">Select some files</label>
elm-fileinputhttps://developer.mozilla.org/en/docs/Using_files_from_web_applications
Found a library for <input type="file">
: https://github.com/lovasoa/elm-fileinput.
Also I have put up a working example using the decoder from this lib: https://runelm.io/c/ie0.