我为学习目的构建了一个简单的应用程序,并且希望能够在用户在输入字段中按Enter
键时调度操作
view : Model -> Html Action
view model =
let
items = List.map (\ item -> li [] [ text item ]) model.items
in
div [] [
input [ onInput Change, value model.content ] [],
button [ onClick Add ] [ text "Submit" ],
ul [] items
]
这是视图代码。我希望这足以解释我对你的意图。当用户在输入一些文本到输入字段时按下Enter
键时,我希望能够发送一些动作。
答案 0 :(得分:19)
您可以使用通用keydown
处理程序手动绑定到on
事件。 Elm目前不支持开箱即用的onKeyDown
处理程序 - 但它们将来会被计划。
看起来规范正在从event.keyCode转向event.key。一旦在更多浏览器中支持此功能,我们可以在此处为onKeyUp,onKeyDown,onKeyPress等添加帮助器。(Source)
在此之前,您只需编写自己的处理程序并使用键代码13(输入)来执行操作。将以下代码复制到elm-lang.org/try或打开https://runelm.io/c/pld以查看其工作原理。 只需在输入框中输入一些文本,然后按Enter键即可查看输入框下方div中反映的当前状态。
import Html exposing (text, div, input, Attribute)
import Html exposing (beginnerProgram)
import Html.Events exposing (on, keyCode, onInput)
import Json.Decode as Json
main =
beginnerProgram
{ model =
{ savedText = ""
, currentText = ""
}
, view = view
, update = update
}
view model =
div []
[ input [onKeyDown KeyDown, onInput Input] []
, div [] [ text ("Input: " ++ model.savedText) ]
]
onKeyDown : (Int -> msg) -> Attribute msg
onKeyDown tagger =
on "keydown" (Json.map tagger keyCode)
type Msg
= NoOp
| KeyDown Int
| Input String
update msg model =
case msg of
NoOp ->
model
KeyDown key ->
if key == 13 then
{ model | savedText = model.currentText }
else
model
Input text ->
{ model | currentText = text }
答案 1 :(得分:16)
在[{3}}中处理onEnter
是一个很好,直截了当的解决方案:
import Html exposing (..)
import Html.Events exposing (keyCode)
import Json.Decode as Json
onEnter : Msg -> Attribute Msg
onEnter msg =
let
isEnter code =
if code == 13 then
Json.succeed msg
else
Json.fail "not ENTER"
in
on "keydown" (Json.andThen isEnter keyCode)
答案 2 :(得分:5)
以上答案非常好 - 但每次按键时都会在Model
中存储 每个字母 < / strong> - 并不总是一个好主意。
例如在我的情况下,我有一个fileSystem
- 像strucutre - 我想在doubbleclick
上编辑任何名称 - 无论它是如何嵌套的。我无法通过每次按键 重建洞fileSystem
视图。这是滞后的。
我发现最好 接收输入值 - 仅当用户按Enter键 ..
type Msg =
| EditingStarted
| EditingFinished String
| CancelEdit
input [ whenEnterPressed_ReceiveInputValue EditingFinished, whenEscPressed_CancelOperation CancelEdit, onBlur CancelEdit ] []
update msg model =
case msg of
EditingFinished inputValue ->
{ model | name = inputValue }
CancelEdit -> ...
whenEnterPressed_ReceiveInputValue : (String -> msg) -> H.Attribute msg
whenEnterPressed_ReceiveInputValue tagger =
let
isEnter code =
if code == 13 then
JD.succeed "Enter pressed"
else
JD.fail "is not enter - is this error shown anywhere?!"
decode_Enter =
JD.andThen isEnter E.keyCode
in
E.on "keydown" (JD.map2 (\key value -> tagger value) decode_Enter E.targetValue)
whenEscPressed_CancelOperation : msg -> H.Attribute msg
whenEscPressed_CancelOperation tagger =
let
isESC code =
if code == 27 then
JD.succeed "ESC pressed"
else
JD.fail "it's not ESC"
decodeESC =
JD.andThen isESC E.keyCode
in
E.on "keydown" (JD.map (\key -> tagger) decodeESC)
注意:如果您正在进行时间旅行调试,则 不 会看到每个字母在输入时出现。但是所有的文字都是同时发生的 - 因为只有一个消息...根据你做的事情 - 这可能是一个问题。如果没有,请享受:)
答案 3 :(得分:4)
您可以在input
元素中使用这样的内容,
如果输入键被按下,这将触发给定的消息:
onEnterPressed : msg -> Attribute msg
onEnterPressed msg =
let
isEnter code =
if code == 13 then Ok () else Err ""
decodeEnterKeyCode = Json.customDecoder keyCode isEnter
in on "keydown" <| Json.map (\_ -> msg) decodeEnterKeyCode
答案 4 :(得分:3)
如果您愿意使用社区软件包B
http://package.elm-lang.org/packages/elm-community/html-extra/latest/Html-Events-Extra#onEnter,则非常简单。
(假设您想在按下回车键时发送A
消息。)
A
答案 5 :(得分:2)
我喜欢Alon的答案,并对其进行了一些迭代,以创建一个响应<enter>
和<esc>
的属性
onEscEnter : String -> (String -> msg) -> Attribute msg
onEscEnter originalValue tagger =
let
handleKey : Int -> Jdec.Decoder Int
handleKey code =
if L.member code [ 13, 27 ] then
-- Enter (13) or ESC (27)
Jdec.succeed code
else
Jdec.fail "something to ignore"
combiner : Int -> String -> msg
combiner keyCode tgtVal =
if keyCode == 13 then
tagger tgtVal
else if keyCode == 27 then
tagger originalValue
else
Debug.crash "onEscEnter"
keyCodeDecoder : Jdec.Decoder Int
keyCodeDecoder =
Jdec.andThen handleKey keyCode
in
on "keydown" (Jdec.map2 combiner keyCodeDecoder targetValue)