Git Product home page Git Product logo

elm-smart-select's Introduction

elm-smart-select

A select component written in Elm 0.19

Install

elm install mercurymedia/elm-smart-select

In Action

Single Select

SingleSelect

Multi Select

MultiSelect

Usage

This package exposes four modules SingleSelect, SingleSelectRemote, MultiSelect and MultiSelectRemote. The Single pickers can be used to pick a single element while the Multi pickers are used to select a list of elements. The pickers without a suffix select from preloaded data whereas the Remote pickers query a remote source. To keep things simple, the documentation here focuses on the SingleSelect. Note: While the basic architecture across all of the modules is similar, certain functions may expect different arguments from one module to the next. Please refer to the specific module documentation for further details and information.

There are 6 steps to configure a SmartSelect:

  1. Import the select and add it to your model providing your local Msg type and the datatype of the data to be selected.
import SingleSelect

type alias Product =
    { id : Int
    , name : String
    , price : String
    }

type alias Model =
    { products : List Product
    , select : SingleSelect.SmartSelect Msg Product
    , selectedProduct : Maybe Product
    }
  1. Define two Msgs: one to handle updates internal to the select and one to handle receiving a selection from the select.
type Msg
    = HandleSelectUpdate (SingleSelect.Msg Product)
    | HandleSelection ( Product, SingleSelect.Msg )
  1. Initialize the select. As noted above, please refer to documentation for the specific arguments that the init function of a particular module takes.
init : ( Model, Cmd Msg )
init =
    ( { products = products
      , select = SingleSelect.init
            { selectionMsg = HandleSelection
            , internalMsg = HandleSelectUpdate
            , idPrefix = "my-prefix"
            }
      , selectedProduct = Nothing
      }
    )

products : List Product
products =
    [ { id = 1
      , name = "product 1"
      , price = "$3.00"
      }
    , { id = 2
      , name = "product 2"
      , price = "$5.00"
      }
    ...
    ]
  1. View the select. Call SingleSelect.view.

Each module exposes a .view and .viewCustom function. .view takes only the arguments it needs while providing reasonable defaults for other view related settings. .viewCustom expects all of the fields that can be customized to be provided as arguments. Please refer to the module documentation for more details.

view : Model -> Html Msg
view model =
    div []
        [ ...
        , div
            [ style "width" "500px" ]
            [ SingleSelect.view { selected = model.selectedProduct, options = model.products, optionLabelFn = .name } model.select ]
        ]
  1. Update the select. Here is where we handle the Msgs we defined in step 2.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ...

        HandleSelectUpdate sMsg ->
            let
                ( updatedSelect, selectCmd ) =
                    SingleSelect.update sMsg model.select
            in
            ( { model | select = updatedSelect }, selectCmd )

        HandleSelection ( product, sMsg ) ->
            let
                ( updatedSelect, selectCmd ) =
                    SingleSelect.update sMsg model.select
            in
            ( { model | selectedProduct = product, select = updatedSelect }, selectCmd )

SingleSelect.upate returns an updated smart select instance and a cmd.

  1. Setup the select subscription. The select module uses a subscription to determine when to close (outside of a selection). Wire the picker subscription like below.
subscriptions : Model -> Sub Msg
subscriptions model =
    SingleSelect.subscriptions model.select

Examples

Examples can be found in the examples folder. To view the examples run npm install and npm start. Open your browser at localhost:1234.

CSS

The CSS for smart select is distributed separately and can be found here

elm-smart-select's People

Contributors

andys8 avatar dependabot[bot] avatar hingew avatar jmpressman avatar mschindlermm avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

elm-smart-select's Issues

Random feedback

  • The examples would be much nicer if there were examples for the remote select controls too.
  • It's not documented what e.g. SingleSelectRemote expects as data structure, and since there's no example it's not super obvious that way either.
  • I screwed up my server side json response function, and got one red line indicating error but there was no error in it. Digging into the elm debugger I got remoteData = Failure Tuple(2). 0 = "GET failed". 1 = "Status code: 500" Seems like this is a bug...
  • Now, after I fixed that I returned invalid data because I don't know what the format should be and the error member is now: remoteData = Failure Tuple(2). 0 = "GET succeeded". 1 = "Request has succeed but we have failed to parse the response! Fear not, your changes, if any, have been made.".. again no error displayed to the user. I think httpErrorToReqErrTuple should spit out the error message somehow.. I made quite a few silly mistakes that were not reported in any nice way, making for a frustrating experience.

All this being said, I hade much more luck with this project than SelectTwo that I tried first and just could never get to work :P

Optional/Advanced Settings

Some settings fields can have a reasonable default set. These could be customized through advanced settings but do not necessarily need to be set in the base settings in order to quickly get a select up and running.

I18n

There is currently no i18n support in the SmartSelect.

IDs should be unique

Multiple smart selects on one page doesn't work well. The wrong one gets opened and the wrong input gets focused.

How about passing an id prefix to the init function?

Merge both update message

There are currently two messages to be implemented for using the smartselect.

  • One for updating itself internally
  • and one that triggers after a selection happened

How about merging them together and having only one message that returns (Maybe entity, internalMsg)? In case of Just entity this means, that a selection from the user happened.

This way you don't need to implement two messages that look kinda the same. Especially when using the SmartSelectRemote you don't risk to use different RemoteAttributes across the two messages.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.