elm - vaya - ¿Cómo manejar la tecla Enter presionar en el campo de entrada?
presionar tecla enter y que vaya al siguiente campo en c# (6)
Hay una solución buena y directa para manejar onEnter
en la versión Elm de TodoMVC :
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)
Construí una aplicación sencilla para fines de aprendizaje y quiero poder enviar una acción cuando el usuario presiona la tecla Enter
en el campo de entrada
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
]
Aquí está el código de vista. Espero que sea suficiente para explicar mi intención para ti. Lo que me gustaría tener es la capacidad de enviar alguna acción cuando el usuario presiona la tecla Enter
mientras ingresa texto en el campo de entrada.
Las respuestas anteriores fueron muy buenas, pero almacenar cada letra en el Model
con cada pulsación de tecla no siempre es una buena idea.
Por ejemplo, en mi caso tengo un sistema de fileSystem
como una estructura, y quiero editar cualquier nombre, no importa lo anidado que esté, con solo hacer doubbleclick
. No puedo tener la vista del sistema de fileSystem
agujeros reconstruida con cada pulsación de tecla . Es laggy
Descubrí que es mejor recibir el valor de entrada, solo cuando el usuario presiona Intro .
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)
Nota: Si está realizando una depuración de viaje en el tiempo, no verá aparecer cada letra tal como fue escrita. Pero todo el texto a la vez, porque solo había un mensaje. Dependiendo de lo que haga, esto puede ser un problema. Si no, disfruta :)
Me gustó la respuesta de Alon y la repetí un poco para crear un atributo que responde a <enter>
y <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
-- ESC or Enter
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)
Podría usar algo como esto en su elemento de input
, esto disparará el mensaje dado si se presiona la tecla Intro:
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
Puede enlazar manualmente el evento keydown
con el genérico on
controlador. Elm actualmente no admite los controladores onKeyDown
fuera de la caja, pero están planeados para el futuro.
Parece que la especificación se está alejando de event.keyCode y hacia event.key. Una vez que esto sea compatible con más navegadores, podemos agregar ayudantes aquí para onKeyUp, onKeyDown, onKeyPress, etc. ( Source )
Hasta entonces, simplemente puede escribir su propio controlador y usar el código de clave 13 (ingresar) para realizar sus acciones. Copie el siguiente código en elm-lang.org/try o abra https://runelm.io/c/pld para ver cómo funciona. Simplemente ingrese un poco de texto en el cuadro de entrada y presione intro para ver el estado actual reflejado en el div debajo del cuadro de entrada.
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 }
Si estás dispuesto a usar el paquete de la comunidad Html.Events.Extra
package.elm-lang.org/packages/elm-community/html-extra/latest/… es muy fácil .
(Suponiendo que desea enviar el mensaje Add
cuando se presiona la tecla Intro).
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
]