executing javascript before submit in ajaxForm

458 views
Skip to first unread message

pelagic

unread,
Jan 24, 2012, 7:09:42 PM1/24/12
to Lift
I have an ajax form that's in a ModalDialog (I'm using jQuery so I've
rolled me own ModalDialog instead of using blockui). Anyways, when the
user clicks the submit button I would like to show a loading overlay
until the server responds with either a validation error or a success,
in which case the modal dialog and overlay will closed. Unfortunatley
I'm having issues getting the javascript that shows the overlay to run
before the ajax submit.

Currently I'm using ajaxSubmit like this:

"type=submit" #> SHtml.ajaxSubmit("Save", () => JE.Call("showloading")
& process) andThen SHtml.makeFormsAjax


I am able to get this working if I use an ajaxButton using the
following constructor:

"type=submit" #> SHtml.ajaxButton(Text("Save"),
JE.Call("showloading"), () => process)

But I'd like to use the ajaxSubmit based on how I've got my form wired
up. Also I've tired using SHtml.hidden(() => JE.Call("showloading")),
but to no avail.

Any help would be greatly appreciate!!!!

Cheers

Viktor Hedefalk

unread,
Jan 25, 2012, 3:28:05 PM1/25/12
to lif...@googlegroups.com
The first variant uses a closure that will be evaluated server side to
RETURN a js statement and you just chain the two js cmds with &. The
client wont get this js until it is already got the answer from the
server:

from SHtml:

def ajaxSubmit(value: String, func: () => JsCmd, attrs: ElemAttr*): Elem = {
val funcName = "z" + Helpers.nextFuncName
addFunctionMap(funcName, contextFuncBuilder(func))

(attrs.foldLeft(<input type="submit" name={funcName}/>)(_ % _)) %
new UnprefixedAttribute("value", Text(value), Null) %
("onclick" -> ("liftAjax.lift_uriSuffix = '"+funcName+"=_';
return true;"))

}

It seemed I have had the same need since I found this one in my "lift-utils":

/**
* ajax submit that does some js before sending
*/
def ajaxSubmit(value: String, before: JsCmd, func: () => JsCmd,
attrs: ElemAttr*): Elem = {
val funcName = "z" + Helpers.nextFuncName
addFunctionMap(funcName, contextFuncBuilder(func))

(attrs.foldLeft(<input type="submit" name={ funcName }/>)((a, b)
=> b.apply(a))) %
new UnprefixedAttribute("value", Text(value), Null) %
new UnprefixedAttribute("onclick", (before.toJsCmd + ";
liftAjax.lift_uriSuffix = '" + funcName + "=_'; return true;"), Null)
}

Thanks,
Viktor

> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

Diego Medina

unread,
Jan 25, 2012, 3:38:39 PM1/25/12
to lif...@googlegroups.com
> It seemed I have had the same need since I found this one in my "lift-utils":

Thanks for sharing that Viktor!

Diego

--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

David Pollak

unread,
Jan 25, 2012, 3:45:02 PM1/25/12
to lif...@googlegroups.com
Lunching with JavaScript returns:

I think we need a general before/after JavaScript mechanism... and I have an idea of how it can be done with only 2 API calls:

SHtml.beforeAjax(jsCmd) {
  SHtml.afterAjax(jsCmd) {
  code that creates an AjaxCall
}
}

Those two calls will wrap the pre and post execution of the Ajax call and will work across all the Ajax call mechanisms.  Further, they answer the need for an "in call" spinny control located near the item that's doing the Ajax call rather than the global spinny thing for Ajax calls.

Can somebody open a ticket on this issue and reference this thread?
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net

Diego Medina

unread,
Jan 25, 2012, 3:55:27 PM1/25/12
to lif...@googlegroups.com
On Wed, Jan 25, 2012 at 3:45 PM, David Pollak
<feeder.of...@gmail.com> wrote:
> Lunching with JavaScript returns:
> http://groups.google.com/group/liftweb/browse_thread/thread/b3469ab5eb55c7f5/32a6b3f8f482a8b7
>
> I think we need a general before/after JavaScript mechanism... and I have an
> idea of how it can be done with only 2 API calls:
>
> SHtml.beforeAjax(jsCmd) {
>   SHtml.afterAjax(jsCmd) {
>   code that creates an AjaxCall
> }
> }
>
> Those two calls will wrap the pre and post execution of the Ajax call and
> will work across all the Ajax call mechanisms.  Further, they answer the
> need for an "in call" spinny control located near the item that's doing the
> Ajax call rather than the global spinny thing for Ajax calls.
>
> Can somebody open a ticket on this issue and reference this thread?

that looks neat

ticket created
http://www.assembla.com/spaces/liftweb/tickets/1187-general-before-after-javascript-mechanism


Thanks

Diego

pelagic

unread,
Jan 25, 2012, 3:56:52 PM1/25/12
to Lift
Viktor - Thank you for sharing that bit of code, looks very nice.

David - I can open a ticket for this.

On Jan 25, 12:45 pm, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> Lunching with JavaScript returns:http://groups.google.com/group/liftweb/browse_thread/thread/b3469ab5e...
>
> I think we need a general before/after JavaScript mechanism... and I have
> an idea of how it can be done with only 2 API calls:
>
> SHtml.beforeAjax(jsCmd) {
>   SHtml.afterAjax(jsCmd) {
>   code that creates an AjaxCall
>
> }
> }
>
> Those two calls will wrap the pre and post execution of the Ajax call and
> will work across all the Ajax call mechanisms.  Further, they answer the
> need for an "in call" spinny control located near the item that's doing the
> Ajax call rather than the global spinny thing for Ajax calls.
>
> Can somebody open a ticket on this issue and reference this thread?
>
>
>
>
>
>
>
>
>
> On Wed, Jan 25, 2012 at 12:38 PM, Diego Medina <di...@fmpwizard.com> wrote:
> > > It seemed I have had the same need since I found this one in my
> > "lift-utils":
>
> > Thanks for sharing that Viktor!
>
> >  Diego
>
> > > Thanks,
> > > Viktor
>
> Visi.Pro, Cloud Computing for the Rest of Ushttp://visi.pro
> Lift, the simply functional web frameworkhttp://liftweb.net

David Pollak

unread,
Jan 25, 2012, 4:06:58 PM1/25/12
to lif...@googlegroups.com
On Wed, Jan 25, 2012 at 12:56 PM, pelagic <vent...@gmail.com> wrote:
Viktor - Thank you for sharing that bit of code, looks very nice.

David - I can open a ticket for this.


Seems Diego beat you to the punch.  Thanks Diego!



--
Visi.Pro, Cloud Computing for the Rest of Us http://visi.pro
Lift, the simply functional web framework http://liftweb.net

Kevin

unread,
Jan 27, 2012, 3:02:00 AM1/27/12
to Lift
I use Viktor's solution.

Clicked the button, it will return pass1 to the frontend but server
will not do anything (e.g. no pass2 is printed and no redirectTo).
I was expecting the "before" parameter is executed prior to the
execution of func parameter in respect to Viktor's def.


This is how I use it in CssSelector. Or Am I suppose to call it in a
ajaxForm?

ajaxSubmit("testButton",
  SetHtml("test",(<div style='display:block'>pass1</div>)),
   ()=> {;println("pass2");JsCmds.RedirectTo("/")} )

Thanks for the sharing.

pelagic

unread,
Jan 30, 2012, 8:19:36 PM1/30/12
to Lift
> This is how I use it in CssSelector. Or Am I suppose to call it in a
> ajaxForm?

yes you should use ajaxSubmit inside an ajaxForm.

If you take a look at the code in SHtml for ajaxSubmit, you will see
it builds an input element with an onclick handler. This handler does
not make the ajax call; rather it sets a var (liftAjax.lift_uriSuffix)
and returns true (so that event propogation will continue). The
onsubmit handler on the form element is where the ajax call is made.
This gets wired up when you call something like makeFormsAjax in your
lift code.

at least this is the way I understand it.
Reply all
Reply to author
Forward
0 new messages