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" ]
]