Function mapping in "S" doesn't support "image" type input form elements.

5 views
Skip to first unread message

Mark Tye

unread,
Sep 22, 2009, 12:51:54 AM9/22/09
to Lift
Hello? Hello? Is this thing on?

Ahem! Well, now that I have been un-banned, I shall re-post my
original message:

I've encountered a limitation in Lift's handling of form elements. I
was able to come up with a workaround, but I was wondering if anyone
knew of a better solution, or if perhaps functionality should be added
to Lift to make the workaround unnecessary.

I wanted to replace a standard form submit button with an image
button. There was no helper function in SHtml for an image button, so
I rolled my own:

private def image(src: String, func: () => Any, attrs: (String,
String)*): Elem =
fmapFunc(func)(funcName => attrs.foldLeft(<input type="image" src=
{src} name={funcName} />)(_ % _))

This generated the correct HTML:

<input type="image" name="F529756071772HPQ" src="images/foo.png"
class="bar" />

But when I clicked on the image in my browser, the function was not
invoked!

I discovered the reason when I captured the POST with Firebug:

http://localhost:8080/sample?F529756071772HPQ.x=11&F529756071772HPQ.y=6&F529756071774VLD=true

As you can see, the browser appended an ".x" and a ".y" to the "name"
parameter. (The HTML spec mandates this behavior so the server can
implement "image map" functionality.) When Lift processed this
request, it tries to invoke two functions named "...HPQ.x" and
"...HQP.y", neither of which exist, instead of "...HPQ", which never
gets invoked.

I was able to get around this by hacking up an alternate version of
S.fmapFunc, but it's ugly:

private def fmapFuncX[T](in: AFuncHolder)(f: String => T): T = {
val name = formFuncName
addFunctionMap(name + ".x", in)
f(name)
}

This works for me because I don't care about the click coordinates,
but it seems that in order to support image map functionality, Lift
would have to intercept the "FOO.x" and "FOO.y" request parameters and
combine them somehow before invoking "FOO". Is there a location in the
pipeline where this could be done conveniently?

Anyway, it'd be be great in anyone can think of a better solution than
hacking up S.fmapFunc, or wants to properly support the x&y coordinate
parameters.

Here's the HTML spec for "image" type form INPUT elements:

http://www.w3.org/TR/html401/interact/forms.html#h-17.4.1

- Mark

marius d.

unread,
Sep 22, 2009, 10:49:58 AM9/22/09
to Lift
name.x and name.y are a pain :) ... since these are propagated with
the same function ID we need to make sure that the function is not
going to be called twice.IO don't think this should be addressed from
fmapFunc. We should be able to handle this when lift is determining
the functions based on param names and apply the knowledge that
F529756071772HPQ.x=11&F529756071772HPQ.y=10 is about all about one
function.

One simple workaround is to place an image for the button but that is
not a submit button. Let's say it's a span. You add onclick to to to
submit the form. F529756071772HPQ input element can simply be a hidden
field (last field in the form) that you attach a function to it.



Br's,
Marius

On Sep 21, 11:51 pm, Mark Tye <mark...@gmail.com> wrote:
> Hello? Hello? Is this thing on?
>
> Ahem! Well, now that I have been un-banned, I shall re-post my
> original message:
>
> I've encountered a limitation in Lift's handling of form elements. I
> was able to come up with a workaround, but I was wondering if anyone
> knew of a better solution, or if perhaps functionality should be added
> to Lift to make the workaround unnecessary.
>
> I wanted to replace a standard form submit button with an image
> button. There was no helper function in SHtml for an image button, so
> I rolled my own:
>
>  private def image(src: String, func: () => Any, attrs: (String,
> String)*): Elem =
>    fmapFunc(func)(funcName => attrs.foldLeft(<input type="image" src=
> {src} name={funcName} />)(_ % _))
>
> This generated the correct HTML:
>
>  <input type="image" name="F529756071772HPQ" src="images/foo.png"
> class="bar" />
>
> But when I clicked on the image in my browser, the function was not
> invoked!
>
> I discovered the reason when I captured the POST with Firebug:
>
>  http://localhost:8080/sample?F529756071772HPQ.x=11&F529756071772HPQ.y...
Reply all
Reply to author
Forward
0 new messages