diffusionkinetics / open

DiffusionKinetics open-source monorepo
MIT License
115 stars 24 forks source link

Youido forms: drop-down to select items in database #95

Closed glutamate closed 6 years ago

glutamate commented 6 years ago

Sometimes in a form, we have to select from a drop-down and the options given in the drop-down correspond to rows in a database. For example, for a todo list you might choose who to assign that item to. You should therefore have a drop-down where the options are the names of other people in your organisation.

This is a challenge for the generic form system in its current design because that information has to come from a database query side effect and so cannot be specified in the current FromForm. I thought about postponing this but it turns out now we need it for the filocore strategy system.

Note that unlike as presented in digestive functors, this is primarily a problem of rendering a form view, not of form validation.

2 ideas:

  1. Make the FromForm and FromField multi parameter type classes where the 2nd parameter is the monad. Then the renderForm and renderField could be monadic so you can do a database query if necessary to render that field.
  2. Add a parameter to renderForm and renderField which is a map from string to a list of strings. Add a new type wrapper around text which takes a phantom parameter, a type level string, which when you call renderField reifies that type level string into a value level string and looks up in the map to get the list of strings of permissible values.

@balajirrao what do you think? Could you think about this please?

glutamate commented 6 years ago

I'm favouring option 2. It is likely that you will need other information such as the user ID to populate this list.

balajirrao commented 6 years ago

@glutamate, yes, I will look into it. I understand option 1, but not option 2. The question I have about option 2 is about where do the map and the type-level string parameter come from ? Can you give me an example please ?

glutamate commented 6 years ago

You would pass it in at the value level as an argument to renderForm. I might do it on a branch to illustrate

glutamate commented 6 years ago

Maybe option 1 is better after all. It is definitely less hacky. It's not clear to me whether one can have a default type for a associated data type, but if that's possible then the monad could be an associated data type with a default to "any monad" - that will be very unobtrusive. And if that doesn't work, the multi-parameter type class is okay.

Then for a "select options"fields one would set the monad to some reader monad over the data you need to do the query wrapped around a database query capability?

glutamate commented 6 years ago

I had a go at each of these 2 options.

https://github.com/diffusionkinetics/open/tree/95-map https://github.com/diffusionkinetics/open/tree/95-monads

The map option is nearly complete, but I don't know how to use inputSelect here http://hackage.haskell.org/package/digestive-functors-lucid-0.0.0.5/docs/Text-Digestive-Lucid-Html5.html how do I tell it what the different options are?

The monads' solution is much more difficult as the monads permeate the generics system and I wasn't able to make any real progress.

balajirrao commented 6 years ago

Thank you for the branches. I'm still working on it. I want to to try the monad idea for a day or two before giving up.