【问题标题】:How to get the selected options of a multiselect in Elm?如何在 Elm 中获取多选的选定选项?
【发布时间】:2016-10-14 13:03:45
【问题描述】:

我见过what is required for a getting the selected index of a single select,但我有兴趣从多选中获取所有选定的选项。我无法弄清楚如何做到这一点。

我尝试了以下操作,但我怀疑 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))

我可以在不使用端口的情况下执行此操作吗?

【问题讨论】:

  • onMultSelect 应该在哪里使用?它已定义且未使用。

标签: html-select elm


【解决方案1】:

解码器失败,因为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

【讨论】:

    【解决方案2】:

    如果有人需要在 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
            }
    

    【讨论】:

      猜你喜欢
      • 2018-04-24
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 2019-10-15
      • 2020-11-29
      • 2021-11-10
      • 1970-01-01
      • 2015-02-19
      相关资源
      最近更新 更多