2015-09-06 30 views
11

Mam element HTML <select> z 3 opcjami i elementem <p>. W elemencie <p> chcę wydrukować indeks aktualnie wybranego elementu w postaci <select>. Na przykład. jeśli wybiorę pierwszą opcję, powinien wydrukować 0, jeśli wybiorę drugą opcję, powinien wydrukować 1, i tak dalej. Jak przejść od minimalnego kodu podanego poniżej?Jak wydrukować indeks wybranej opcji w wiąz?

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 

Odpowiedz

18

Istnieje wiele different events w elm-html 2.0.0, ale nic istotne dla elementu <select> HTML. Więc zdecydowanie potrzebujesz niestandardowego programu obsługi zdarzeń, który możesz utworzyć za pomocą on. Ma typ:

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

Wydarzenie, które jest wywoływane za każdym razem wybraniu opcji wewnątrz <select> nazywa “change”. To, czego potrzebujesz, to targetSelectedIndex z elm-community/html-extra, która ustala właściwość selectedIndex.

Ostateczny kod będzie wyglądać następująco:

Aktualizacja do 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 } 

Można go uruchomić w przeglądarce tutaj https://runelm.io/c/xum

+0

Jednak można zrobić bez cięć? :) –

+0

Skrócone nazwy opakowań. Ten przykład bardzo mi pomógł, ale musiałem go skopiować w edytorze tekstu i zmienić JD na Json.Decode itd., Zanim mogłem to zrozumieć. –

+0

Byłoby wspaniale zobaczyć to zaktualizowane dla elm-0.17, jeśli masz czas. Spróbuję to zrobić, jeśli uważam, że moje zrozumienie wybranych opcji jest wystarczająco dobre. – MichaelJones