3

How do I integrate this sweet dialog into my Elm code. I've included the JS and CSS in my index.html. How do I call this JavaScript function in my update function?

update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of
    Submit ->
      let valid = length model.name > 0
      in
        if valid 
          then (model, swal({"title": "Invalid name"}))
          else (model, swal({"title": "Valid name"}))
Martin Zabel
  • 3,589
  • 3
  • 19
  • 34
alpha_cod
  • 1,933
  • 5
  • 25
  • 43

1 Answers1

4

It's tricky to rig up a full example without all the view code to check with, but I'm hoping this simpler version helps! Cribbed to some extend from this repo...

index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="Main.js" type="text/javascript"></script>
        <script type="text/javascript"
            src="bower_components/sweetalert/dist/sweetalert.min.js"
        ></script>
        <link rel="stylesheet"
            href="bower_components/sweetalert/dist/sweetalert.css"
        />
  </head>
  <body>
        <div id="main"></div>   
        <script type="text/javascript">

            var so = Elm.embed(Elm.Main, document.getElementById('main'));
            so.ports.callSwal.subscribe(doAlert); 
            function doAlert(space) {
                    if (space) swal("Hey, a spacebar!");
            }

        </script>
  </body>
</html>

modal.elm

import Graphics.Element
import Keyboard


port callSwal : Signal Bool
port callSwal =
    Keyboard.space


main = Graphics.Element.show "How about pressing a spacebar?"

stuff I did to make it work

$ bower install sweetalert
$ elm-make modal.elm --output=Main.js

Note

  • Embed the Elm application, to give js an object to access ("so" here)
  • In js, subscribe to a named port and give it a callback function.
  • create the port in elm. This one takes a simple Bool, but I guess yours will want at least a String.

A better answer

The trick turns out to be noticing that startApp has a mailbox baked into it, which you can access through app.model.

The alert message becomes part of your model. If it's an empty string, we interpret that as meaning "don't trigger any alerts".

NB. I've no idea why update needs to return a tuple with an Events Action in it. That's not been used here..

Here's an example of it all put together:

var so = Elm.embed(Elm.Main, document.getElementById('main'));
so.ports.alert.subscribe(function(text) {
    if (text.length > 0) swal(text);
});
import StartApp
import Task exposing (Task)
import Effects exposing (Effects, Never)
import Html exposing (Html, div, input, button, text)
import Html.Events exposing (on, onClick, targetValue)
import String exposing (length)


app :
  { html : Signal Html
  , model : Signal Model
  , tasks : Signal (Task Never ())
  }
app =
  StartApp.start
    { init = init
    , update = update
    , view = view
    , inputs = []
    }


port alert : Signal String
port alert =
    Signal.map (\n -> n.alert) app.model


main : Signal Html
main =
  app.html


-- MODEL

type alias Model =
  { name : String
  , alert : String
  }


init : (Model, Effects Action)
init =
  ( { name = ""
    , alert = ""
    }
  , Effects.none
  )


-- UPDATE

type Action
    = Submit
    | TextEntry String


update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of

    Submit ->
      if length model.name > 0 then
        ({ model | alert = "Valid name" }, Effects.none)
      else
        ({ model | alert = "Invalid name" }, Effects.none)

    TextEntry txt ->
      ({ model | name = txt, alert = "" }, Effects.none)


-- VIEW

view : Signal.Address Action -> Model -> Html
view address model =
  let f = (\str -> Signal.message address (TextEntry str)) in
  div
    []
    [ input
      [ on "input" targetValue f ]
      []
    , button
      [ onClick address Submit ]
      [ text "Submit" ]
    ]
Adam Marshall
  • 693
  • 6
  • 16
  • Oh thanks a lot for this help :). I have a last difficulty of sending message to this signal from the above update function. Could you please tell me how to shoot a message from the update function so that I could wire up some UI action to send a message and alert – alpha_cod Jan 23 '16 at 19:09
  • Well I just had a go here, but got quite stuck! Quite new to elm myself, so haven't seen much about StartApp, Effects or Task packages yet (though think these all need to be understood to proceed!) Worth learning for my own sake anyway, but I might not be quick on that front.. – Adam Marshall Jan 23 '16 at 21:51
  • This helped me the solve the executing-task problem: http://stackoverflow.com/questions/34978145/elm-send-message-to-mailbox-in-update-function – alpha_cod Jan 26 '16 at 18:24