Elm 如何处理输入字段中的回车键?
我为学习目的开发了一个简单的应用程序,希望在用户按下输入字段中的[code>Enter]键时能够发送一个动作Elm 如何处理输入字段中的回车键?,elm,Elm,我为学习目的开发了一个简单的应用程序,希望在用户按下输入字段中的[code>Enter]键时能够发送一个动作 view : Model -> Html Action view model = let items = List.map (\ item -> li [] [ text item ]) model.items in div [] [ input [ onInput Change, value model.cont
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
处理程序,但它们将在将来计划使用
看起来规范正在从event.keyCode转移到event.key。一旦这在更多浏览器中得到支持,我们可能会在此处为onKeyUp、onKeyDown、onKeyPress等添加帮助程序()
在此之前,您只需编写自己的处理程序,并使用keycode13(enter)执行操作。打开以下内容以查看其工作原理。
只需在输入框中输入一些文本,然后按enter键即可查看输入框下方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 }
您可以在
输入
元素中使用类似的内容,
如果按下enter键,将触发给定消息:
onEnterPressed:msg->Attribute msg
单味味精=
让
等中心码=
如果代码==13,则确定()否则错误“”
decodeEnterKeyCode=Json.customDecoder keyCode isEnter
在“按键关闭”消息中)解码输入按键代码
在以下方面有一个很好的简单解决方案来处理onEnter
:
导入Html(属性)
导入Html.Events(keyCode,on)
导入Json。解码为Json
onEnter:Msg->attributemsg
奥奈特味精=
让
等中心码=
如果代码==13,则
Json.succeed msg
其他的
Json.fail“不输入”
在里面
关于“keydown”(Json.and然后是输入keyCode)
上述答案非常好-但在每次按键时将每个字母存储在模型中并不总是一个好主意
例如,在我的例子中,我有一个文件系统
,比如structure,我想在双击
上编辑任何名称,无论其嵌套程度如何。我不能用每次按键来重建文件系统的孔。是拉吉
我发现最好接收输入值-只有当用户按下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)
注意:如果您正在进行时间旅行调试-您将看不到键入的每个字母。但是所有的文字同时出现,因为只有一条信息。。这取决于你做什么-这可能是一个问题。如果没有,请欣赏:)我喜欢Alon的答案,并对其进行了一点迭代,以创建一个响应
和
的属性
如果您愿意使用社区软件包Html.Events.Extra
,这非常简单
(假设您想在按下enter键时发送Add
消息。)
看起来您创建了自定义事件处理程序。你能简单解释一下发生了什么吗?@NikitaLuparev keyCode是一个JSON解码器,记录在上面答案中引用的同一页上。很遗憾,这不起作用,因为同一事件的多个处理程序,keydown
,在本例中不受支持:。请参阅此答案,了解有效的解决方案密钥代码来自何处?显然来自Html.Events
。是的,keyCode来自我用import语句更新了帖子以澄清。或者只复制这个函数
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)
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
]