diff --git a/examples/2-sightseeing.elm b/examples/2-sightseeing.elm new file mode 100644 index 0000000..b3477bd --- /dev/null +++ b/examples/2-sightseeing.elm @@ -0,0 +1,189 @@ +import Html exposing (Html, Attribute, div, h1, input, p, text) +import Html.App as App +import Html.Attributes exposing (checked, style, type') +import Html.Events exposing (onClick) +import Html.Lazy exposing (lazy) +import String +import Table exposing (defaultCustomizations) +import Time exposing (Time) + + + +main = + App.program + { init = init missionSights + , update = update + , view = view + , subscriptions = \_ -> Sub.none + } + + + +-- MODEL + + +type alias Model = + { sights : List Sight + , tableState : Table.State + } + + +init : List Sight -> ( Model, Cmd Msg ) +init sights = + let + model = + { sights = sights + , tableState = Table.initialSort "Year" + } + in + ( model, Cmd.none ) + + + +-- UPDATE + + +type Msg + = ToggleSelected String + | SetTableState Table.State + + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + case msg of + ToggleSelected name -> + ( { model | sights = List.map (toggle name) model.sights } + , Cmd.none + ) + + SetTableState newState -> + ( { model | tableState = newState } + , Cmd.none + ) + + +toggle : String -> Sight -> Sight +toggle name sight = + if sight.name == name then + { sight | selected = not sight.selected } + + else + sight + + + +-- VIEW + + +view : Model -> Html Msg +view { sights, tableState } = + div [] + [ h1 [] [ text "Trip Planner" ] + , lazy viewSummary sights + , Table.view config tableState sights + ] + + +viewSummary : List Sight -> Html msg +viewSummary allSights = + case List.filter .selected allSights of + [] -> + p [] [ text "Click the sights you want to see on your trip!" ] + + sights -> + let + time = + List.sum (List.map .time sights) + + price = + List.sum (List.map .price sights) + + summary = + "That is " ++ toString (Time.inHours time) ++ " hours of fun, costing $" ++ toString price + in + p [] [ text summary ] + + + +-- TABLE CONFIGURATION + + +config : Table.Config Sight Msg +config = + Table.customConfig + { toId = .name + , toMsg = SetTableState + , columns = + [ checkboxColumn + , Table.stringColumn "Name" .name + , timeColumn + , Table.floatColumn "Price" .price + , Table.floatColumn "Rating" .rating + ] + , customizations = + { defaultCustomizations | rowAttrs = toRowAttrs } + } + + +toRowAttrs : Sight -> List (Attribute Msg) +toRowAttrs sight = + [ onClick (ToggleSelected sight.name) + , style [ ("background", if sight.selected then "#CEFAF8" else "white") ] + ] + + +timeColumn : Table.Column Sight Msg +timeColumn = + Table.customColumn + { name = "Time" + , viewData = viewTime + , sorter = Table.increasingOrDecreasingBy .time + } + + +viewTime : Sight -> String +viewTime {time} = + if time < Time.hour then + toString (Time.inMinutes time) ++ "min" + + else + toString (Time.inHours time) ++ "hr" + + +checkboxColumn : Table.Column Sight Msg +checkboxColumn = + Table.veryCustomColumn + { name = "" + , viewData = viewCheckbox + , sorter = Table.unsortable + } + + +viewCheckbox : Sight -> Table.HtmlDetails Msg +viewCheckbox {selected} = + Table.HtmlDetails [] + [ input [ type' "checkbox", checked selected ] [] + ] + + + +-- SIGHTS + + +type alias Sight = + { name : String + , time : Time + , price : Float + , rating : Float + , selected : Bool + } + + +missionSights : List Sight +missionSights = + [ Sight "Eat a Burrito" (Time.hour / 2) 7 4.6 False + , Sight "Buy drugs in Delores park" Time.hour 20 4.9 False + , Sight "Armory Tour" (1.5 * Time.hour) 27 4.5 False + , Sight "Tartine Bakery" Time.hour 10 4.1 False + , Sight "Have Brunch" (2 * Time.hour) 25 4.2 False + ] \ No newline at end of file