[web-devel] [Haskell-beginners] Options for creating a multiple select form via Yesod

Greg Weber greg at gregweber.info
Thu Jun 16 01:08:15 CEST 2011


If you want to use the new version, you have to reinstall yesod or any
package that want the new forms as a dependency (and it must match the
version constraints), which will break projects wanting the old yesod. My
biggest complaint with haskell :)

If you want a different version of yesod (and dependencies) for different
projects you have to use cabal-dev. I use cabal-dev as much as possible,
however it doesn't yet play well with yesod-devel or wai-handler-devel.

On Wed, Jun 15, 2011 at 3:40 PM, Michael Litchard <michael at schmong.org>wrote:

> David,
>        I checked-out yesod-forms from the repository and see that
> you've made the changes. Thank you once again. My follow-up question
> is for anyone who cares to answer. How do I swap the new yesod-forms
> and the old one from 0.2.0? I don't want to hose
> my system. This is new ground for me.
>
> On Tue, Jun 14, 2011 at 10:56 AM, Michael Litchard <michael at schmong.org>
> wrote:
> > Oh sweet! Thanks!
> >
> > On Tue, Jun 14, 2011 at 9:43 AM, David McBride <dmcbride at neondsl.com>
> wrote:
> >> I think I'll give it a shot.  Fun problem and something I'll
> >> definitely need eventually.  I'll try and get you a pull request
> >> tonight if all goes well.
> >>
> >> On Tue, Jun 14, 2011 at 11:40 AM, Michael Snoyman <michael at snoyman.com>
> wrote:
> >>> Hi David,
> >>>
> >>> Thank you for the analysis, you're absolutely correct that this is a
> >>> shortcoming in the API of yesod-form as it stands. I had an idea for a
> >>> possibly simple modification to fix the situation: change fieldParse
> >>> to
> >>>
> >>>    [Text] -> Either msg (Maybe a)
> >>>
> >>> We don't really want to support returning singles or doubles from the
> >>> same Field; a multiSelectField will automatically make the "a"
> >>> variable a list. Said another way, the types should be:
> >>>
> >>>    selectField :: [(Text, a)] -> Field xml msg a
> >>>    multiSelectField :: [(Text, a)] -> Field xml msg [a]
> >>>
> >>> Another related change: we don't really need to separate out
> >>> fieldRender from fieldView I believe. Instead, we can have fieldView
> >>> be:
> >>>
> >>>    fieldView :: Text -- ^ ID
> >>>                 -> Text -- ^ name
> >>>                 -> a -- currently, this is another Text
> >>>                 -> Bool -- ^ required?
> >>>                 -> xml
> >>>
> >>> I'm willing to test out these changes myself, but wanted to (1) get
> >>> input from you and (2) see if you or anyone else wanted to take a
> >>> crack at it.
> >>>
> >>> Michael
> >>>
> >>> On Tue, Jun 14, 2011 at 4:25 PM, David McBride <dmcbride at neondsl.com>
> wrote:
> >>>> I gave a shot at this last night,and didn't quite pull it off.  But I
> >>>> got pretty far and I'd rather you have my work than try it from
> >>>> scratch.
> >>>>
> >>>> The first method won't work because the Field type is used in
> >>>> validating the get parameters in the mhelper function in
> >>>> yesod.form.functions.  That means that you have to have a unified type
> >>>> for field that can do everything.  Maybe there is a more succinct way
> >>>> with classes, but I just couldn't think of an elegant way to do it
> >>>> that way.
> >>>>
> >>>> So what I tried to do was make the fieldParser callback into its own
> type:
> >>>>
> >>>> newtype FieldParser msg a = FieldParser (Either
> >>>>  (Maybe Text -> Either msg (Maybe a))
> >>>>  (Maybe [Text] -> Either msg (Maybe [a])))
> >>>>
> >>>> That means a field parser can either take one text and return one
> >>>> item, or it takes a list and returns a list of items.
> >>>>
> >>>> Then I went through Yesod.Form.Fields and changed about 12 or 15
> references of
> >>>> { fieldParse = blank $ \s ->
> >>>> to
> >>>> { fieldParse = FieldParser . Left $ blank $ \s ->
> >>>>
> >>>> Cool, now when you write your multipleSelectField, you'll set the
> fieldParser to
> >>>> FieldParser . Right $ etc...
> >>>>
> >>>> The very last thing you have to do to fix this is the mhelper
> >>>> function, which is where I lost steam.  Right now it looks up the name
> >>>> of the field in the get/post params that were passed in, and then
> >>>> hands the value to fieldParse.  What it needs to do is check to see
> >>>> whether Field Parser is left or right, and then pass in the params
> >>>> slightly differently depending on which it is.  I don't know how the
> >>>> parameters will end up getting passed into askParams though.  Right
> >>>> now askParams returns a list of names to value pairs, so hopefully you
> >>>> will end up with a list of multiple entries for the name of your mutli
> >>>> select and a different value for each entry, which you need to filter
> >>>> out and collect into a single list and then run the fieldParser on it.
> >>>>
> >>>> Hopefully that is not too bad.
> >>>>
> >>>>
> >>>> On Tue, Jun 14, 2011 at 4:30 AM, Michael Litchard <
> michael at schmong.org> wrote:
> >>>>> Well I will try the easier way first, and having accomplished that I
> >>>>> will look into doing it the better way. If people can call dibs, I'd
> >>>>> like to.
> >>>>>
> >>>>> On Mon, Jun 13, 2011 at 9:47 PM, David McBride <dmcbride at neondsl.com>
> wrote:
> >>>>>> After looking at the source, you should be aware that
> >>>>>>
> >>>>>> 1) yesod-form has been updated to 2.0,
> >>>>>> 2) it is a lot easier to understand than 1.x was.
> >>>>>>
> >>>>>> The main obstacle I see is that the library uses the Field datatype,
> >>>>>> that has a fieldParse method of Maybe Text -> Either msg (Maybe a).
> >>>>>> The problem with that is that a multiple select box should require
> >>>>>> [Text] or perhaps Maybe [Text] rather than Maybe Text.  It is making
> >>>>>> the assumption that there can only be one piece of data per field,
> >>>>>> which holds for everything except multiple selects and multiple
> radio
> >>>>>> buttons.
> >>>>>>
> >>>>>> So looking at this, it looks like you'd have to add another field
> type
> >>>>>> "FieldMulti" to Yesod/Form/Types.hs, which allows for multiple
> values.
> >>>>>>  Then add a new version of selectFieldHelper that accepts
> fieldMultis
> >>>>>> instead of fields, and then it is trivial to change selectField to
> be
> >>>>>> a multi field.
> >>>>>>
> >>>>>> Alternatively you could change Field to accept either single or
> >>>>>> multiple values and change its use everywhere else, which is
> probably
> >>>>>> the better answer, but more involved.
> >>>>>>
> >>>>>> I don't know if this is the best way to go about it, but it seems
> like
> >>>>>> it should work.
> >>>>>>
> >>>>>> On Mon, Jun 13, 2011 at 8:11 PM, Michael Litchard <
> michael at schmong.org> wrote:
> >>>>>>> Thank you David. I'm trying to figure out step-by-step, exactly how
> >>>>>>> selectFields binds field values. One thing I'm having trouble with
> is
> >>>>>>> visualizing return values.
> >>>>>>> Beginning with askParams.
> >>>>>>>
> >>>>>>> askParams :: Monad m => StateT Ints (ReaderT Env m) Env
> >>>>>>> askParams = lift askenv <- askParams
> >>>>>>>
> >>>>>>>
> >>>>>>> Here's the example from selectFields
> >>>>>>> env <- askParams
> >>>>>>> later on env is used in with the lookup function
> >>>>>>>
> >>>>>>> let res = case lookup name env of
> >>>>>>> seeing as lookup is checking for value of type a in a [(a,b)]
> >>>>>>> and given the type of askParams
> >>>>>>> I have no idea what is going on here. I don't see a [(a,b)] in
> >>>>>>> askParams :: Monad m => StateT Ints (ReaderT Env m) Env.
> >>>>>>>
> >>>>>>> So if someone could answer how env <- askParams yields a [(a,b)]
> for
> >>>>>>> lookup to use as input, I would appreciate it.
> >>>>>>>
> >>>>>>>
> >>>>>>> On Mon, Jun 13, 2011 at 2:54 PM, David McBride <
> dmcbride at neondsl.com> wrote:
> >>>>>>>> The read function is sort of the opposite of the show function.
>  Take
> >>>>>>>> a string, give me a value.  reads is like read, however it has
> some
> >>>>>>>> traits that read doesn't have.
> >>>>>>>>
> >>>>>>>> The problem with read is that if you go: read "asdf" :: Int, it
> will
> >>>>>>>> die with an exception, and that is something you don't want in a
> web
> >>>>>>>> app.  Also it doesn't tell you what the rest of the string is, so
> you
> >>>>>>>> have no real way of finding out what was left of the string after
> the
> >>>>>>>> part you wanted to parse.
> >>>>>>>>
> >>>>>>>> So there is the reads function that returns [(a,String)] which is
> a
> >>>>>>>> list of pairs of the answer a, and the rest of the string String.
>  As
> >>>>>>>> a bonus, it returns a list so if it can't parse the string you
> pass
> >>>>>>>> it, then it just returns an empty list.  Why didn't it use Maybe
> you
> >>>>>>>> ask?  I bet it probably has to do with the function being one of
> the
> >>>>>>>> first functions ever written for haskell, long before Maybe
> existed.
> >>>>>>>>
> >>>>>>>> So all it is there is unpack this bytestring into a string, then
> parse
> >>>>>>>> it into a value, and please don't blow up if the input is invalid.
> >>>>>>>>
> >>>>>>>> On Mon, Jun 13, 2011 at 5:28 PM, Michael Litchard <
> michael at schmong.org> wrote:
> >>>>>>>>> I was a bit hasty. I can render a multi-select field easily
> enough.
> >>>>>>>>> However, I'm having difficulty following how selectField makes a
> value
> >>>>>>>>> from the select field accessible from the handler code calling
> >>>>>>>>> selectField. Once I figure that out, I can modify
> multiSelectField
> >>>>>>>>> accordingly.
> >>>>>>>>>
> >>>>>>>>> The goal here being to modify selectField so that a list of field
> >>>>>>>>> values can be bound .
> >>>>>>>>>
> >>>>>>>>> Here's what I have so far:
> >>>>>>>>> multiSelectField is thus far identical in every way to
> selectField
> >>>>>>>>> save for the following change in the Hamlet part.
> >>>>>>>>>
> >>>>>>>>> <select multiple="#{theId}" id="#{theId}" name="#{name}">
> >>>>>>>>>
> >>>>>>>>> My thinking was that the value bound to multiple was arbitary,
> and I'd
> >>>>>>>>> use theId until I figured out something that made more sense.
> >>>>>>>>>
> >>>>>>>>> Here's where I am focusing my efforts next
> >>>>>>>>>
> >>>>>>>>> http://hpaste.org/47774
> >>>>>>>>>
> >>>>>>>>> Specifically
> >>>>>>>>> (x', _):_ ->
> >>>>>>>>>                            case lookup x' pairs' of
> >>>>>>>>>                                Nothing -> FormFailure ["Invalid
> entry"]
> >>>>>>>>>                                Just (y, _) -> FormSuccess y
> >>>>>>>>> I'm thinking this is where selectField binds a value from the
> select
> >>>>>>>>> field form. I'm confused by the (x',_):_. At first I thought it
> meant
> >>>>>>>>> that just the first pair in a list of pairs is pattern matched
> >>>>>>>>> against, and the rest discarded. But then I ask myself where the
> list
> >>>>>>>>> is coming from. In a select field there would only be one pair,
> not a
> >>>>>>>>> list of them. Here's where I get confused. Because if this is not
> >>>>>>>>> where the values of the select field get bound, I don't know
> where
> >>>>>>>>> it's happening.
> >>>>>>>>>
> >>>>>>>>> Is my confusion clear enough such that I could get some
> clarifying
> >>>>>>>>> feedback? If not, what is unclear?
> >>>>>>>>>
> >>>>>>>>> On Sat, Jun 11, 2011 at 11:03 AM, Michael Snoyman <
> michael at snoyman.com> wrote:
> >>>>>>>>>> The best way for code contributions in general is to submit a
> pull
> >>>>>>>>>> request on Github. If that's a problem, sending a patch via
> email
> >>>>>>>>>> works as well (either directly to me or to web-devel).
> >>>>>>>>>>
> >>>>>>>>>> Michael
> >>>>>>>>>>
> >>>>>>>>>> On Sat, Jun 11, 2011 at 1:14 AM, Michael Litchard <
> michael at schmong.org> wrote:
> >>>>>>>>>>> Hey! I just added multiSelectField to the Forms library. I'm
> only
> >>>>>>>>>>> getting the first value selected, but I think that's because of
> how
> >>>>>>>>>>> I'm using multiSelecrField. I'm going to try to change the
> client code
> >>>>>>>>>>> to fix this. I'll let you know how it goes. when I get a
> >>>>>>>>>>> maybeMultiSelectField added I'll show you what I have. What
> would be
> >>>>>>>>>>> the best way to submit this?
> >>>>>>>>>>>
> >>>>>>>>>>> On Thu, Jun 9, 2011 at 10:05 PM, Michael Snoyman <
> michael at snoyman.com> wrote:
> >>>>>>>>>>>> Hi Michael,
> >>>>>>>>>>>>
> >>>>>>>>>>>> There's nothing jQuery or Javascript specific about a
> multi-select
> >>>>>>>>>>>> field: it's just a normal select field with a "multiple"
> attribute. I
> >>>>>>>>>>>> would recommend taking the selectField code from yesod-form
> and
> >>>>>>>>>>>> modifying it to be multi-select. I'll likely do this myself
> >>>>>>>>>>>> eventually, but it could be a good learning experience in
> Yesod (and a
> >>>>>>>>>>>> great introduction to contributing to the framework if you're
> so
> >>>>>>>>>>>> inclined).
> >>>>>>>>>>>>
> >>>>>>>>>>>> Michael
> >>>>>>>>>>>>
> >>>>>>>>>>>> On Thu, Jun 9, 2011 at 8:29 PM, Michael Litchard <
> michael at schmong.org> wrote:
> >>>>>>>>>>>>> I'm trying to create a multiple select form, as illustrated
> on the following:
> >>>>>>>>>>>>> http://api.jquery.com/selected-selector/
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Here's the options I see possible:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> (1) Write a jQuery widget.
> >>>>>>>>>>>>> (2) Use plain javascript via Julius
> >>>>>>>>>>>>> (3) Use the low-level functions in Yesod.Form to write a
> widget
> >>>>>>>>>>>>> (4) Use a pre-existing function that does what I need, but am
> not
> >>>>>>>>>>>>> aware of this functionality
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> (1) has appeal as it looks like something small I can
> contribute to
> >>>>>>>>>>>>> the project. It will take me some extra time to figure out
> the
> >>>>>>>>>>>>> details. But, I had a look at the other jQuery widgets and
> they seem
> >>>>>>>>>>>>> to provide an approachable model to follow.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> (2) This looks like the most straight-forward approach. I'm
> just
> >>>>>>>>>>>>> learning javascript so would have to figure out how to
> capture values
> >>>>>>>>>>>>> in Haskell from the form.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> (3) This looks like the most difficult way. I don't think I
> know
> >>>>>>>>>>>>> enough about the low-level functions in Yesod.Form to be able
> to
> >>>>>>>>>>>>> accomplish this in a timely manner.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> (4) This is the best scenario. There's already a way to do
> this right
> >>>>>>>>>>>>> now, and I just haven't identified it. If this is the case, I
> would
> >>>>>>>>>>>>> appreciate being pointed in the right direction.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Until informed otherwise, I'm evaluating options 1 and 2. All
> feedback
> >>>>>>>>>>>>> welcomed. Thanks to all who made Yesod possible.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> _______________________________________________
> >>>>>>>>>>>>> Beginners mailing list
> >>>>>>>>>>>>> Beginners at haskell.org
> >>>>>>>>>>>>> http://www.haskell.org/mailman/listinfo/beginners
> >>>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> _______________________________________________
> >>>>>>>>> Beginners mailing list
> >>>>>>>>> Beginners at haskell.org
> >>>>>>>>> http://www.haskell.org/mailman/listinfo/beginners
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> _______________________________________________
> >>>>>>>> Beginners mailing list
> >>>>>>>> Beginners at haskell.org
> >>>>>>>> http://www.haskell.org/mailman/listinfo/beginners
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> Beginners mailing list
> >>>>>> Beginners at haskell.org
> >>>>>> http://www.haskell.org/mailman/listinfo/beginners
> >>>>>>
> >>>>>
> >>>>
> >>>> _______________________________________________
> >>>> Beginners mailing list
> >>>> Beginners at haskell.org
> >>>> http://www.haskell.org/mailman/listinfo/beginners
> >>>>
> >>>
> >>
> >> _______________________________________________
> >> Beginners mailing list
> >> Beginners at haskell.org
> >> http://www.haskell.org/mailman/listinfo/beginners
> >>
> >
>
> _______________________________________________
> web-devel mailing list
> web-devel at haskell.org
> http://www.haskell.org/mailman/listinfo/web-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110615/c9239d70/attachment-0001.htm>


More information about the web-devel mailing list