如何在 Elm 中获取多选的选定选项?
How to get the selected options of a multiselect in Elm?
我看过 ,但我有兴趣从多 select 中获取所有 selected 选项。我还没弄明白该怎么做。
我尝试了以下操作,但我怀疑 Json 解码器出现故障。不过我不是 100% 确定这一点,因为解码发生在虚拟 dom 代码中,任何错误都会被丢弃。
type Msg
= SetMultipleInts (List Int)
-- I'm not seeing the SetMultipleInts message when I click on the multiselect
view model =
div []
[ select (onSelect SetMultipleInts) (List.map myOption [1..4]) ]
myOption : Int -> Html Msg
myOption id =
option [ value (toString id) ] [ text <| "Option " ++ (toString id) ]
-- I'm not seeing anything happen in the onchange
onMultiSelect : (List Int -> msg) -> List (Html.Attribute msg)
onMultiSelect msg =
[ on "change" (Json.map msg targetSelectedOptions), multiple True ]
targetSelectedOptions : Json.Decoder (List Int)
targetSelectedOptions =
Json.at [ "target", "selectedOptions" ] (Json.list (Json.at [ "value" ] Json.int))
我可以在不使用端口的情况下执行此操作吗?
解码器失败,因为 event.target.selectedOptions
不是
javascript数组。当你不能使用 Json.Decode.list
时,你
可以使用 Json.Decode.keyValuePairs
.
这是您如何使用它的示例。
您可能需要根据以下情况更改 extractValues
关于您想如何对空选择等做出反应。
targetSelectedOptions : Json.Decoder (List String)
targetSelectedOptions =
let
maybeValues =
Json.at [ "target", "selectedOptions" ]
<| Json.keyValuePairs
<| Json.maybe ("value" := Json.string)
extractValues mv =
Ok (List.filterMap snd mv)
in Json.customDecoder maybeValues extractValues
如果有人需要在 Elm 中进行多选,我在 Elm 0.19 中重写了一个完整的示例:
https://ellie-app.com/g7WrS9cV4zVa1
module Main exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes
import Html.Events
import Json.Decode
type alias Model =
{ value : List ( String, Maybe String ) }
init : Model
init =
{ value = [] }
type Msg
= SetMultipleInts (List ( String, Maybe String ))
update : Msg -> Model -> Model
update msg model =
case msg of
SetMultipleInts value ->
{ model | value = value }
view : Model -> Html Msg
view model =
div []
[ select
[ Html.Events.on "change"
(Json.Decode.map SetMultipleInts targetSelectedOptions)
, Html.Attributes.multiple True
]
(List.map myOption (List.range 1 4))
, div []
[ text <|
Debug.toString
(model
|> .value
|> List.map Tuple.second
|> List.filterMap identity
)
]
]
targetSelectedOptions : Json.Decode.Decoder (List ( String, Maybe String ))
targetSelectedOptions =
Json.Decode.at [ "target", "selectedOptions" ] <|
Json.Decode.keyValuePairs <|
Json.Decode.maybe (Json.Decode.at [ "value" ] Json.Decode.string)
myOption : Int -> Html Msg
myOption id =
option [ Html.Attributes.value (String.fromInt id) ]
[ text <| "Option " ++ String.fromInt id ]
main : Program () Model Msg
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
我看过
我尝试了以下操作,但我怀疑 Json 解码器出现故障。不过我不是 100% 确定这一点,因为解码发生在虚拟 dom 代码中,任何错误都会被丢弃。
type Msg
= SetMultipleInts (List Int)
-- I'm not seeing the SetMultipleInts message when I click on the multiselect
view model =
div []
[ select (onSelect SetMultipleInts) (List.map myOption [1..4]) ]
myOption : Int -> Html Msg
myOption id =
option [ value (toString id) ] [ text <| "Option " ++ (toString id) ]
-- I'm not seeing anything happen in the onchange
onMultiSelect : (List Int -> msg) -> List (Html.Attribute msg)
onMultiSelect msg =
[ on "change" (Json.map msg targetSelectedOptions), multiple True ]
targetSelectedOptions : Json.Decoder (List Int)
targetSelectedOptions =
Json.at [ "target", "selectedOptions" ] (Json.list (Json.at [ "value" ] Json.int))
我可以在不使用端口的情况下执行此操作吗?
解码器失败,因为 event.target.selectedOptions
不是
javascript数组。当你不能使用 Json.Decode.list
时,你
可以使用 Json.Decode.keyValuePairs
.
这是您如何使用它的示例。
您可能需要根据以下情况更改 extractValues
关于您想如何对空选择等做出反应。
targetSelectedOptions : Json.Decoder (List String)
targetSelectedOptions =
let
maybeValues =
Json.at [ "target", "selectedOptions" ]
<| Json.keyValuePairs
<| Json.maybe ("value" := Json.string)
extractValues mv =
Ok (List.filterMap snd mv)
in Json.customDecoder maybeValues extractValues
如果有人需要在 Elm 中进行多选,我在 Elm 0.19 中重写了一个完整的示例:
https://ellie-app.com/g7WrS9cV4zVa1
module Main exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes
import Html.Events
import Json.Decode
type alias Model =
{ value : List ( String, Maybe String ) }
init : Model
init =
{ value = [] }
type Msg
= SetMultipleInts (List ( String, Maybe String ))
update : Msg -> Model -> Model
update msg model =
case msg of
SetMultipleInts value ->
{ model | value = value }
view : Model -> Html Msg
view model =
div []
[ select
[ Html.Events.on "change"
(Json.Decode.map SetMultipleInts targetSelectedOptions)
, Html.Attributes.multiple True
]
(List.map myOption (List.range 1 4))
, div []
[ text <|
Debug.toString
(model
|> .value
|> List.map Tuple.second
|> List.filterMap identity
)
]
]
targetSelectedOptions : Json.Decode.Decoder (List ( String, Maybe String ))
targetSelectedOptions =
Json.Decode.at [ "target", "selectedOptions" ] <|
Json.Decode.keyValuePairs <|
Json.Decode.maybe (Json.Decode.at [ "value" ] Json.Decode.string)
myOption : Int -> Html Msg
myOption id =
option [ Html.Attributes.value (String.fromInt id) ]
[ text <| "Option " ++ String.fromInt id ]
main : Program () Model Msg
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}