2017-02-22 10 views
5

を使用するコンテンツ編集可能なタグをと入力してモデルを更新しようとしています。Elm:条件付き防止デフォルト(contentEditable付き)

私のコードは以下の通りです。ここではEllieで遊ぶことができるバージョンがあります。

オンの「ぼかし」属性は、クリックしたときに機能し、モデルを更新します。しかし、と入力されたときに、同じ「更新」機能を使用したいと考えています。

view : Model -> Html Msg 
view model = 
    let 
     attrs = 
      [ contenteditable True 
       --, on "blur" (Json.map UpdateTitle targetTextContent) 
      , onInput2 UpdateTitle 
      , onEnter EnterPressed 
      , id "title" 
      , class "title" 
      ] 
    in 
     div [] 
      [ h1 attrs [ text model.existing ] 
      , text "Click above to start editing. Blur to save the value. The aim is to capture an <enter> and interpret that as a blur, i.e. to save the value and blur the field" 
      , p [] [ text <| "(" ++ model.existing ++ ")" ] 
      ] 


targetTextContent : Json.Decoder String 
targetTextContent = 
    Json.at [ "target", "textContent" ] Json.string 


onInput2 : (String -> msg) -> Attribute msg 
onInput2 msgCreator = 
    on "input" (Json.map msgCreator targetTextContent) 


onEnter : (Bool -> msg) -> Attribute msg 
onEnter enterMsg = 
    onWithOptions "keydown" 
     { stopPropagation = False 
     , preventDefault = False 
     } 
     (keyCode 
      |> Json.andThen 
       (\ch -> 
        let 
         _ = 
          Debug.log "on Enter" ch 
        in 
         Json.succeed (enterMsg <| ch == 13) 
       ) 
     ) 

このコードはモデルを正常に更新しているようですが、DOMがうんざりしています。私はが「爆発」した後を入力して入力した場合たとえば、私はこの

​​が

見る私はHtml.Keyedに切り替えて「KeyDownイベント」を使用してみましたが、それはすべての違いを作るか、単に別の問題を作成していませんでした。

+0

私はあなたの問題への回答はありませんが、仮想DOMを使用することと関係があると思います。 Reactがそれをどのように扱っているかを調査したいかもしれません。例えば。 http://stackoverflow.com/q/30601516/1238847 – Tosh

答えて

6

解決済み!重要な点は、<enter>だけがpreventDefaultの対象になるようにJson.Decode.failを使用するフィルタ関数です。このアイディアについては、https://github.com/elm-lang/virtual-dom/issues/18#issuecomment-273403774を参照してください。

view : Model -> Html Msg 
view model = 
    let 
     attrs = 
      [ contenteditable True 
      , on "blur" (Json.map UpdateTitle targetTextContent) 
      , onEnter EnterPressed 
      , id "title" 
      , class "title" 
      ] 
    in 
     div [] 
      [ h1 attrs [ text model.existing ] 
      , text "Click above to start editing. Blur to save the value. The aim is to capture an <enter> and interpret that as a blur, i.e. to save the value and blur the field" 
      , p [] [ text <| "(" ++ model.existing ++ ")" ] 
      ] 


targetTextContent : Json.Decoder String 
targetTextContent = 
    Json.at [ "target", "textContent" ] Json.string 


onEnter : msg -> Attribute msg 
onEnter msg = 
    let 
     options = 
      { defaultOptions | preventDefault = True } 

     filterKey code = 
      if code == 13 then 
       Json.succeed msg 
      else 
       Json.fail "ignored input" 

     decoder = 
      Html.Events.keyCode 
       |> Json.andThen filterKey 
    in 
     onWithOptions "keydown" options decoder