如何处理输入字段中的 Enter 键按下?
How to handle Enter key press in input field?
我出于学习目的构建了一个简单的应用程序,并希望能够在用户按下输入字段中的 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
键时能够调度一些动作。
您可以使用通用 on
处理程序手动绑定到 keydown
事件。 Elm 目前不支持开箱即用的 onKeyDown
处理程序 - 但他们计划在未来。
It looks like the spec is moving away from event.keyCode and towards event.key. Once this is supported in more browsers, we may add helpers here for onKeyUp, onKeyDown, onKeyPress, etc. (Source)
在那之前,您可以简单地编写自己的处理程序并使用键码 13(回车)来执行您的操作。打开下面的 ellie-app 看看它是如何工作的。
只需在输入框中输入一些文字并回车即可看到输入框下方的div反映的当前状态。
import Html exposing (text, div, input, Attribute)
import Browser
import Html.Events exposing (on, keyCode, onInput)
import Json.Decode as Json
main =
Browser.sandbox
{ init =
{ 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 }
您可以在 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
中处理 onEnter
有一个很好的直接解决方案
import Html exposing (Attribute)
import Html.Events exposing (keyCode, on)
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)
上面的答案非常好 - 但是存储 每个字母 在 Model
在每个按键上按下 - 并不总是一个好主意。
例如,在我的例子中,我有一个类似于 fileSystem
的结构 - 我想编辑任何名称 - 无论它是如何嵌套的 - 在 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)
注意:如果您正在进行 time-traveling 调试 - 您将 而不是 看到每个字母在键入时出现。但是一次显示所有文本 - 因为只有一条消息.. 取决于你做什么 - 这可能是个问题。如果没有,享受 :)
我喜欢阿隆的回答并对其进行了一些迭代以创建一个响应 <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)
如果你愿意使用社区包 Html.Events.Extra
http://package.elm-lang.org/packages/elm-community/html-extra/latest/Html-Events-Extra#onEnter 这很容易。
(假设您要在按下回车键时发送 Add
消息。)
import Html.Events.Extra exposing (onEnter)
view : Model -> Html Action
view model =
let
items = List.map (\ item -> li [] [ text item ]) model.items
in
div [] [
input [ onInput Change, onEnter Add, value model.content ] [],
button [ onClick Add ] [ text "Submit" ],
ul [] items
]
我出于学习目的构建了一个简单的应用程序,并希望能够在用户按下输入字段中的 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
键时能够调度一些动作。
您可以使用通用 on
处理程序手动绑定到 keydown
事件。 Elm 目前不支持开箱即用的 onKeyDown
处理程序 - 但他们计划在未来。
It looks like the spec is moving away from event.keyCode and towards event.key. Once this is supported in more browsers, we may add helpers here for onKeyUp, onKeyDown, onKeyPress, etc. (Source)
在那之前,您可以简单地编写自己的处理程序并使用键码 13(回车)来执行您的操作。打开下面的 ellie-app 看看它是如何工作的。 只需在输入框中输入一些文字并回车即可看到输入框下方的div反映的当前状态。
import Html exposing (text, div, input, Attribute)
import Browser
import Html.Events exposing (on, keyCode, onInput)
import Json.Decode as Json
main =
Browser.sandbox
{ init =
{ 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 }
您可以在 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
onEnter
有一个很好的直接解决方案
import Html exposing (Attribute)
import Html.Events exposing (keyCode, on)
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)
上面的答案非常好 - 但是存储 每个字母 在 Model
在每个按键上按下 - 并不总是一个好主意。
例如,在我的例子中,我有一个类似于 fileSystem
的结构 - 我想编辑任何名称 - 无论它是如何嵌套的 - 在 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)
注意:如果您正在进行 time-traveling 调试 - 您将 而不是 看到每个字母在键入时出现。但是一次显示所有文本 - 因为只有一条消息.. 取决于你做什么 - 这可能是个问题。如果没有,享受 :)
我喜欢阿隆的回答并对其进行了一些迭代以创建一个响应 <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)
如果你愿意使用社区包 Html.Events.Extra
http://package.elm-lang.org/packages/elm-community/html-extra/latest/Html-Events-Extra#onEnter 这很容易。
(假设您要在按下回车键时发送 Add
消息。)
import Html.Events.Extra exposing (onEnter)
view : Model -> Html Action
view model =
let
items = List.map (\ item -> li [] [ text item ]) model.items
in
div [] [
input [ onInput Change, onEnter Add, value model.content ] [],
button [ onClick Add ] [ text "Submit" ],
ul [] items
]