2015-09-06 15 views
11

Ho un elemento HTML <select> con 3 opzioni e un elemento <p>. Nell'elemento <p>, desidero stampare l'indice dell'articolo attualmente selezionato in <select>. Per esempio. se seleziono la prima opzione, dovrebbe stampare 0, se seleziono la seconda opzione, dovrebbe stampare 1 e così via. Come procedo dal codice minimale, che viene fornito di seguito?Come stampare l'indice dell'opzione selezionata in Elm?

import Html as H exposing (Html) 
import Maybe 
import Signal as S exposing (Address, (<~)) 

type alias Model = { selected : Maybe Int } 
model = { selected = Nothing } 

type Action = NoOp | Select Int 
update action model = 
    case action of 
    NoOp -> model 
    Select n -> { model | selected <- Just n } 

view address model = 
    H.div [] 
    [ H.select [] [ H.option [] [ H.text "0" ] 
        , H.option [] [ H.text "1" ] 
        , H.option [] [ H.text "2" ] 
        ] 
    , H.p [] [ H.text <| Maybe.withDefault "" 
        <| Maybe.map toString model.selected ] 
    ] 

actions = Signal.mailbox NoOp 
main = view actions.address <~ S.foldp update model actions.signal 

risposta

18

C'è un sacco di different events in elm-html 2.0.0, ma niente di rilevante all'elemento <select> HTML. Quindi hai sicuramente bisogno di un gestore di eventi personalizzato, che puoi creare usando on. Ha un tipo:

on : String -> Decoder a -> (a -> Message a) -> Attribute 

L'evento che si attiva ogni volta che si seleziona l'opzione all'interno del <select> si chiama “change”. Quello che ti serve è targetSelectedIndex da elm-community/html-extra che utilizza una proprietà selectedIndex.

Il codice finale sarebbe simile a questa:

Aggiornato Elm-0,18

import Html exposing (..) 
import Html.Events exposing (on, onClick) 
import Html.Attributes exposing (..) 
import Json.Decode as Json 
import Html.Events.Extra exposing (targetSelectedIndex) 


type alias Model = 
    { selected : Maybe Int } 


model : Model 
model = 
    { selected = Nothing } 


type Msg 
    = NoOp 
    | Select (Maybe Int) 


update : Msg -> Model -> Model 
update msg model = 
    case msg of 
     NoOp -> 
      model 

     Select s -> 
      { model | selected = s } 


view : Model -> Html Msg 
view model = 
    let 
     selectEvent = 
      on "change" 
       (Json.map Select targetSelectedIndex) 
    in 
     div [] 
      [ select [ size 3, selectEvent ] 
       [ option [] [ text "1" ] 
       , option [] [ text "2" ] 
       , option [] [ text "3" ] 
       ] 
     , p [] 
      [ text <| 
       Maybe.withDefault "" <| 
        Maybe.map toString model.selected 
      ] 
     ] 


main : Program Never Model Msg 
main = 
    beginnerProgram { model = model, view = view, update = update } 

è possibile eseguirlo in del browser qui https://runelm.io/c/xum

+0

Eppure, si potrebbe fare a meno tagli? :) –

+0

Nome abbreviato dei pacchetti. Questo esempio mi ha aiutato molto, ma ho dovuto copypaste l'editor di testo e cambiato JD in Json.Decode ecc ... prima che potessi capirlo. –

+0

Sarebbe eccellente vedere questo aggiornamento per elm-0.17 se si ottiene il tempo. Proverò a farlo se riterrò che la mia comprensione delle opzioni selezionate sia abbastanza buona. – MichaelJones