Search code examples
elm

How can I make a table striped using elm-bootstrap 4.1.0?


I have been trying several things and cannot work out how to style this Elm table with Bootstrap so it's striped. I am trying to use elm-bootstrap and have installed rundis/elm-bootstrap 4.1.0

Bootstrap.Table is currently unused:

module Players.List exposing (..)

import Html exposing (..)
import Html.Attributes exposing (class)
import Msgs exposing (Msg)
import Models exposing (Player)
import RemoteData exposing (WebData)
import Bootstrap.Table as Table

view : WebData (List Player) -> Html Msg
view response =
div []
    [ nav
    , maybeList response
    ]


nav : Html Msg
nav =
div [ class "clearfix mb2 white bg-black" ]
    [ div [ class "left p2" ] [ text "Players" ] ]


maybeList : WebData (List Player) -> Html Msg
 maybeList response =
case response of
    RemoteData.NotAsked ->
        text ""

    RemoteData.Loading ->
        text "Loading..."

    RemoteData.Success players ->
        list players

    RemoteData.Failure error ->
        text (toString error)


list : List Player -> Html Msg
list players =
div [ class "col-md-4" ]
    [ table [ class "table table-striped" ]
        [ thead []
            [ tr []
                [ th [] [ text "Id" ]
                , th [] [ text "Initials" ]
                , th [] [ text "Time" ]
                , th [] [ text "Score" ]
                ]
            ]
        , tbody [] (List.map playerRow players)
        ]
    ]


playerRow : Player -> Html Msg
playerRow player =
tr []
    [ td [] [ text player.id ]
    , td [] [ text player.initials ]
    , td [] [ text (toString player.time) ]
    , td [] [ text (toString player.score) ]
    ]

As this should be ultra simple I'm clearly missing something here. How can I make this table striped?


Solution

  • Your example uses HTML functions from Elm's HTML library but you're probably going to have a better time using the appropriate Bootstrap types and functions. For example, using the table options defined in the documentation, you could rewrite the view functions like this:

    list : List Player -> Html msg
    list players =
        Table.table
            { options = [ Table.striped ]
            , thead = Table.thead []
                [ Table.tr []
                    [ Table.th [] [ text "Id" ]
                    , Table.th [] [ text "Initials" ]
                    , Table.th [] [ text "Time" ]
                    , Table.th [] [ text "Score" ]
                    ]
                ]
            , tbody = Table.tbody [] (List.map playerRow players)
            }
    
    playerRow : Player -> Table.Row msg
    playerRow player =
         Table.tr []
            [ Table.td [] [ text player.id ]
            , Table.td [] [ text player.initials ]
            , Table.td [] [ text (Debug.toString player.time) ]
            , Table.td [] [ text (Debug.toString player.score) ]
            ]
    

    That will give you the right HTML but you may still need to import the Bootstrap styles. The documentation gives an example of including the stylesheet, which you could do in some wrapping function, for example:

    import Bootstrap.Grid as Grid
    import Bootstrap.Table as Table
    import Bootstrap.CDN as CDN
    
    view : Model -> Html Msg
    view model =
        Grid.container []
            [ CDN.stylesheet -- creates an inline style node with the Bootstrap CSS
            , Grid.row []
                [ Grid.col []
                    [ list model.players ]
                ]
            ]
    

    Here is a slimmed down Ellie example to play with.