I'm pretty new to Elm and I've been trying to make a quiz while struggling really hard. What I need is a timer that counts downwards from 10 to 1 and once it hits 1 it switches to another page. I've tried using the time example from Elm's site as well as the Elm-timer library but all without success.
The code I'm working with:
module QuizPage exposing (..)
import Browser
import Browser.Navigation as Nav
import Html exposing (..)
import Html.Attributes exposing (..)
import Url
import Html.Events exposing (..)
-- MAIN
main : Program () Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlChange = UrlChanged
, onUrlRequest = LinkClicked
}
-- MODEL
type alias Model =
{ key : Nav.Key
, url : Url.Url
, uporabnik : String
, igra : Int
}
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key =
( Model key url "" 0, Cmd.none )
-- UPDATE
type Msg
= LinkClicked Browser.UrlRequest
| UrlChanged Url.Url
| SpremembaImena String
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LinkClicked urlRequest ->
case urlRequest of
Browser.Internal url ->
( model, Nav.load (Url.toString url) )
Browser.External href ->
( model, Nav.load href )
UrlChanged url ->
( { model | url = url }
, Cmd.none
)
SpremembaImena ime ->
({model | uporabnik = ime}, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- VIEW
view : Model -> Browser.Document Msg
view model =
{
title = "Kviz"
, body =
[div [style "width" "100%", style "text-align" "center", style "background-color" "powderblue", style "position" "fixed", style "width" "100%", style "height" "100%"]
[ Html.br[][]
, Html.div [style "width" "100%", style "font-size" "20px"][ Html.div[][Html.text "Koda vaše igre: 1234"], Html.div [][Html.text "Čas do konca 7s"] ]
, Html.br [][]
, Html.br [][]
, Html.br [][]
, Html.br [][]
, div [style "font-size" "30px"][Html.text "Vprašanje"]
, Html.br [][]
, Html.br [][]
, Html.br [][]
, Html.br [][]
, Html.div [ style "margin-left" "43%" ][ viewLink "EndPage.elm" "Odgovor1"]
, Html.br [][]
, Html.br [][]
, Html.div [ style "margin-left" "43%"][ viewLink "EndPage.elm" "Odgovor2"]
, Html.br [][]
, Html.br [][]
, Html.div [ style "margin-left" "43%" ][ viewLink "EndPage.elm" "Odgovor3"]
, Html.br [][]
, Html.br [][]
, Html.div [ style "margin-left" "43%" ][ viewLink "EndPage.elm" "Odgovor4"]
]]
}
viewLink : String -> String -> Html msg
viewLink path name =
a [ href path , style "text-decoration" "none", style "color" "black", style "width" "200px", style "magin-left" "200px", style "display" "block", style "font" "bold 11px Arial", style "border-top" "1px solid #CCCCCC", style "text-decoration" "none", style "background-color" "#EEEEEE", style "color" "#333333", style "padding" "2px 6px 2px 6px", style "border-right" "1px solid #CCCCCC", style "border-bottom" "1px solid #CCCCCC", style "border-left" "1px solid #CCCCCC", style "align" "center" ] [ text name ]
Any help is highly appreciated!
The answer to my question is a simple countdown timer.
ELM:
module Main exposing (..)
import Browser
import Html exposing (..)
import Task
import Time
-- MAIN
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{
cas : Int
}
init : () -> (Model, Cmd Msg)
init _ =
( Model 10, Cmd.none
)
-- UPDATE
type Msg
= Tick Time.Posix
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Tick newTime ->
if model.cas == 0 then
( { model | cas = 0 }
, Cmd.none
)
else
( { model | cas = (racun model) }
, Cmd.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every 1000 Tick
racun : Model -> Int
racun model =
model.cas - 1
-- VIEW
view : Model -> Html Msg
view model =
let
first = String.fromInt (model.cas)
in
h1 [] [ text (first) ]
HTML:
<html>
<head>
<style>
/* you can style your program here */
</style>
</head>
<body>
<main></main>
<script>
var app = Elm.Main.init({ node: document.querySelector('main') })
// you can use ports and stuff here
</script>
</body>
</html>