lessless
lessless

Reputation: 896

How to fill in several dropdowns subsequently from JSON in Elm?

We are stuck with filling in form from JSON data and need help. The component is about selecting the ward in the district of the given city. The data structure is a tree of Cities, Districts, and Wards with approximately following structure (everything is wrapped in GeoJSON):

// Cities: '/api/cities/berlin'
{
  features: [
    {
        type: "Feature",
      properties: { 
        slug: "berlin",
        name: "Berlin",
        districts: [
          {name: "Neukölln", slug: "neukolln", ...}
        ]
        },
      geometries: {...}
    } 
  ]
}

// Districts: '/api/cities/berlin/districts/neukolln'
{
  features: [
    {
        type: "Feature",
      properties: { 
        slug: "neukolln",
        name: "Neukölln",
        wards: [
          {name: "Britz", slug: "britz", ...}
        ]
        },
      geometries: {...}
    } 
  ]
}

// Wards: '/api/cities/berlin/districts/neukolln/wards'
{
  features: [
    {
        type: "Feature",
      properties: { 
        slug: "britz",
        name: "Britz",
        },
      geometries: {...}
    } 
  ]
}

In the view, three are three dropdown boxes for selecting City, District and Ward, thus, when User select City, then District dropdown is filled from the properties.districts field of the JSON response. Same is applied for the Districts dropdown: wards are filled in from the properties.wards When the page is loaded it already has an injected JSON of all available Cities (and, accordingly their districts)

What strategy would you advise on:

1) how to get currently selected city and hit server for next administrative divisions? I.e. when a user selects District, get its slug and query server for the wards?

2) how to fill subsequent select from the response or injected JSON on the page? I.e. when user select another City, fill District select box with respective Districts?

Upvotes: 1

Views: 227

Answers (2)

halfzebra
halfzebra

Reputation: 6797

Start-up

If selected city is known, before the start-up, you can pass in as a flag to Html.App.programWithFlags

The same thing you can do to the list of cities.

Please see the http example, it covers most of the stuff.

If you want to send xhr request on start-up, you might use a little neat trick for that:

init : String -> (Model, Cmd Msg)
init topic =
  ( Model topic "waiting.gif"
  , getRandomGif topic
  )

Where getRandomGif will execute the xhr request on start-up, assuming that you have gotten some data for that from passing them as flags or from user input.

On every FetchSucceed, you should send the next xhr to grab the data for the next step.

The flow

Please consider this flow chart, illustrating the flow of your multi step form. Dashed arrows point to steps, where you can restart the cycle, if you want to change the city/district at some point.

Caching layer is optional, Elm offers a variety of data structures for that.

Multi-step form flow

Upvotes: 1

Tosyn
Tosyn

Reputation: 21

Here's how I have done something similar in the past (in elm v0.17.0):

dropdown : List City -> Html Msg
dropdown cities =
    div []
        [ div []
              [ span [] [ text "dropdown label name" ]
              , selectOptions cities
              ]
        ]


selectOptions : List City -> Html Msg
selectOptions cities = 
      select [ on "change" ( Json.map (\city -> GetDistrictsMsg city) targetValue ) ]
            (List.map setOption cities)


setOption : City -> Html Msg
setOption city =
    option [ value city.name ]
           [ text city.name ]

And you will repeat the same for districts to get wards.

Upvotes: 1

Related Questions