Orange-OpenSource / elm-advanced-grid / Grid

This module allows to create dynamically configurable data grid.

Configure the grid

A grid is defined using a Config


type alias Config a =
{ canSelectRows : Basics.Bool
, columns : List (ColumnConfig a)
, containerHeight : Basics.Int
, containerWidth : Basics.Int
, hasFilters : Basics.Bool
, headerHeight : Basics.Int
, lineHeight : Basics.Int
, rowClass : Item a -> String 
}

The configuration for the grid. The grid content is described using a list of ColumnConfig. You should define the css classes, if you want to use some. By example you could add to all rows a "cursor: pointer" style, if you define some behaviour to be triggered when the user clicks a line.

gridConfig =
    { canSelectRows = True
    , columns = columnList
    , containerHeight = 500
    , containerWidth = 700
    , hasFilters = True
    , lineHeight = 20
    , rowClass = cssClassname
    }

cssClassname : Item -> String
cssClassname item =
    if item.selected then
        "selected"

    else
        ""

withColumns : List (ColumnConfig a) -> Model a -> Model a

Sets the column definitions into the configuration

withConfig : Config a -> Model a -> Model a

Sets the grid configuration

Configure a column


type alias ColumnConfig a =
{ properties : ColumnProperties
, comparator : Item a -> Item a -> Basics.Order
, filteringValue : Maybe String
, filters : Filters.Filter a
, toString : Item a -> String
, renderer : ColumnProperties -> Item a -> Html.Styled.Html (Msg a) 
}

The configuration for a column. The grid content is described using a list of ColumnConfigs.

NB: This is a "low level API", useful to define custom column types. In order to define common column types, you may want to use the higher level API, i.e. stringColumnConfig, intColumnConfig, floatColumnConfig, boolColumnConfig

idColumnConfig =
    { properties =
        { id = "Id"
        , order = Unsorted
        , title = "Id"
        , visible = True
        , width = 50
        }
    , comparator = compareIntField .id
    , filters = IntFilter <| intFilter .id
    , filteringValue = Nothing
    , toString = String.fromInt .id
    , renderer = viewInt .id
    }


type alias ColumnProperties =
{ id : String
, order : Sorting
, title : String
, tooltip : String
, visible : Basics.Bool
, width : Basics.Int 
}

ColumnProperties are a part of the configuration for a column.

NB: This is a "low level API", useful to define custom column types. In order to define common column types, you may want to use the higher level API, i.e. stringColumnConfig, intColumnConfig, floatColumnConfig, boolColumnConfig

properties =
    { id = "name"
    , order = Unsorted
    , title = "Name"
    , visible = True
    , width = 100
    }

stringColumnConfig : { id : String, title : String, tooltip : String, width : Basics.Int, getter : a -> String, localize : String -> String } -> ColumnConfig a

Create a ColumnConfig for a column containing a string value

getter is usually a simple field access function, like ".age" to get the age field of a Person record.

localize takes the title or the tooltip of the column as a parameter, and returns its translation, if you need internationalization. If you don't need it, just use identity.

intColumnConfig : { id : String, title : String, tooltip : String, width : Basics.Int, getter : a -> Basics.Int, localize : String -> String } -> ColumnConfig a

Create a ColumnConfig for a column containing an integer value

getter is usually a simple field access function, like ".age" to get the age field of a Person record.

localize takes the title or the tooltip of the column as a parameter, and returns its translation, if you need internationalization. If you don't need it, just use identity.

floatColumnConfig : { id : String, title : String, tooltip : String, width : Basics.Int, getter : a -> Basics.Float, localize : String -> String } -> ColumnConfig a

Create a ColumnConfig for a column containing a float value

getter is usually a simple field access function, like ".age" to get the age field of a Person record.

localize takes the title or the tooltip of the column as a parameter, and returns its translation, if you need internationalization. If you don't need it, just use identity.

boolColumnConfig : { id : String, title : String, tooltip : String, width : Basics.Int, getter : a -> Basics.Bool, localize : String -> String } -> ColumnConfig a

Create a ColumnConfig for a column containing a boolean value

localize takes the title or the tooltip of the column as a parameter, and returns its translation, if you need internationalization. If you don't need it, just use identity.

Configure the column sorting


type Sorting
    = Unsorted
    | Ascending
    | Descending

The sorting options for a column, to be used in the properties of a ColumnConfig.

NB: This type is useful to define custom column types. You wont need it for common usages.

By default you probably should use "Unsorted" as the value for the order field. If you give any other value (Ascending or Descending), it must match the order of the data provided to initialize the grid model.

    { properties =
        { id = "Id"
        , order = Unsorted
        , title = "Id"
        , visible = True
        , width = 50
        }

compareFields : (Item a -> comparable) -> Item a -> Item a -> Basics.Order

Compares two integers, two floats or two strings. Use this function in a ColumnConfig to define how the values in a given column should be compared. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

comparator =
    compareFields (\item -> item.id)

compareBoolField : (Item a -> Basics.Bool) -> Item a -> Item a -> Basics.Order

Compares two booleans. Use this function in a ColumnConfig to define how the values in a given column should be compared. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

comparator =
    compareBoolField (\item -> item.even)

Configure the rendering when a custom one is needed

viewBool : (Item a -> Basics.Bool) -> ColumnProperties -> Item a -> Html.Styled.Html (Msg a)

Renders a cell containing a boolean value. Use this function in a ColumnConfig to define how the values in a given column should be rendered. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

renderer =
    viewBool (\item -> item.even)

viewFloat : (Item a -> Basics.Float) -> ColumnProperties -> Item a -> Html.Styled.Html (Msg a)

Renders a cell containing a floating number. Use this function in a ColumnConfig to define how the values in a given column should be rendered. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

renderer =
    viewFloat (\item -> item.value)

viewInt : (Item a -> Basics.Int) -> ColumnProperties -> Item a -> Html.Styled.Html (Msg a)

Renders a cell containing an int value. Use this function in a ColumnConfig to define how the values in a given column should be rendered. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

renderer =
    viewInt (\item -> item.id)

viewProgressBar : Basics.Int -> (a -> Basics.Float) -> ColumnProperties -> Item a -> Html.Styled.Html (Msg a)

Renders a progress bar in a a cell containing a integer. Use this function in a ColumnConfig to define how the values in a given column should be rendered. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

renderer =
    viewProgressBar 8 (\item -> item.value)

viewString : (Item a -> String) -> ColumnProperties -> Item a -> Html.Styled.Html (Msg a)

Renders a cell containing a string. Use this function in a ColumnConfig to define how the values in a given column should be rendered. The unique parameter to be provided is a lambda which returns the field to be displayed in this column.

renderer =
    viewString (\item -> item.name)

cumulatedBorderWidth : Basics.Int

Left + right cell border width, including padding, in px. Useful to take into account the borders when calculating the total grid width

cellAttributes : ColumnProperties -> List (Html.Styled.Attribute (Msg a))

Common attributes for cell renderers

Boilerplate


type alias Model a =
{ clickedItem : Maybe (Item a)
, config : Config a
, columnsX : List Basics.Int
, content : List a
, draggedColumn : Maybe (DraggedColumn a)
, dragStartX : Basics.Float
, filterHasFocus : Basics.Bool
, hoveredColumn : Maybe (ColumnConfig a)
, infList : InfiniteList.Model
, isAllSelected : Basics.Bool
, headerContainerPosition : Position
, order : Sorting
, resizedColumn : Maybe (ColumnConfig a)
, showPreferences : Basics.Bool
, sortedBy : Maybe (ColumnConfig a)
, visibleItems : List (Item a) 
}

The grid model. You'll use it but should not have to access its fields, and definitely should not modify them directly


type Msg a
    = ColumnsModificationRequested (List (ColumnConfig a))
    | InfiniteListMsg InfiniteList.Model
    | FilterLostFocus
    | FilterModified (ColumnConfig a) String
    | SetFilters (Dict String String)
    | SetSorting String Sorting
    | NoOp
    | GotHeaderContainerInfo (Result Browser.Dom.Error Browser.Dom.Element)
    | ScrollTo (Item a -> Basics.Bool)
    | ShowPreferences
    | UserClickedHeader (ColumnConfig a)
    | UserClickedFilter
    | UserClickedLine (Item a)
    | UserClickedDragHandle (ColumnConfig a) Position
    | UserHoveredDragHandle
    | UserClickedPreferenceCloseButton
    | UserClickedResizeHandle (ColumnConfig a) Position
    | UserDraggedColumn Position
    | UserEndedMouseInteraction
    | UserMovedResizeHandle Position
    | UserSwappedColumns (ColumnConfig a) (ColumnConfig a)
    | UserToggledAllItemSelection
    | UserToggledColumnVisibility (ColumnConfig a)
    | UserToggledSelection (Item a)

The messages the grid view can emit.

The messages constructed with UserClickedLine (Item a) are emitted when an item is clicked, so you can update the model of your app. If you use this message, you'll probably want to define a cursor of type pointer for the rows (see the rowClass property of the Config type )

The messages using the UserToggledSelection constructor let you know a line selection status changed, so you can update the list of selected items if you use it.

The ShowPreferences message constructor is to be used when you want to trigger the display of the column visibility panel. It must be sent by the parent module. There is no way to trigger it from Grid.

UserToggledColumnVisibility, and UserEndedMouseInteraction may be used in the parent module to save the grid configuration (if you want to make persistant the changes of columns' width, position and/or visibility by example).

If you want to trigger a scrolling of the grid from your program, you can call Grid's update function with ScrollTo message. ScrollTo takes one argument: a selection function. The row diplayed on top after the scrolling is the first one for which the selection function returns True.

You probably should not use the other constructors.

case msg of
    GridMsg (UserClickedLine item) ->
        let
            ( newGridModel, cmd ) =
                Grid.update (UserClickedLine item) model.gridModel
        in
        ( { model
            | gridModel = newGridModel
            , clickedItem = Just item
          }
        , Cmd.map GridMsg cmd
        )

    GridMsg (UserToggledSelection item status) ->
        let
            ( newGridModel, cmd ) =
                Grid.update (UserToggledSelection item status) model.gridModel

            selectedItems =
                List.filter .selected newGridModel.content
        in
        ( { model
            | gridModel = newGridModel
            , selectedItems = selectedItems
          }
        , Cmd.map GridMsg cmd
        )

init : Config a -> List a -> Model a

Initializes the grid model, according to the given grid configuration and content.

  init : () -> ( Model, Cmd Msg )
  init _ =
     ( { gridModel = Grid.init gridConfig data
       }
     , Cmd.none
     )

update : Msg a -> Model a -> ( Model a, Platform.Cmd.Cmd (Msg a) )

Updates the grid model

view : Model a -> Html (Msg a)

Renders the grid

Get data

filteredItems : Model a -> List a

The list of items satisfying the current filtering values

selectedAndVisibleItems : Model a -> List (Item a)

the list of items selected by the user, after filters were applied

Get grid config

visibleColumns : Model a -> List (ColumnConfig a)

The list of visible columns according to their current configuration. This list ignores the actual position of the columns; some of them may require an horizontal scrolling to be seen

isColumn : ColumnConfig a -> ColumnConfig a -> Basics.Bool

Compares the identity of two columns

isSelectionColumn : ColumnConfig a -> Basics.Bool

Returns true when the given ColumnConfig is the multiple selection column (column added by Grid when row selection is activated)

isSelectionColumnProperties : { a | id : String } -> Basics.Bool

Returns true when the given Properties are the one of the multiple selection column, provided by Grid when row selection is activated