Reinstantiate a snippet for an ajax call

78 views
Skip to first unread message

Adam Coimbra

unread,
Jun 13, 2012, 2:37:55 AM6/13/12
to lif...@googlegroups.com
Hello,
I'm building a page that has a form for creating a mapper as well as a list of all existing entries for that mapper. The list has an edit link for each mapper that is created via SHtml.a, which calls a JsCmd that appends an edit form for that entry to the page in a modal window. The edit form and the creation form are built by the same rendering/processing method defined in the singleton of the mapper (it takes a Box[Mapper] argument and runs creation logic if the argument is empty, or edits the passed mapper entry otherwise). This method is first called to construct the creation form. When the edit link is clicked, it is called again, but this time the method is passed the mapper instance to edit. When the edit form is rendered, it successfully loads the values for the existing mapper entry passed to it. But when the ajax submit button is clicked, it uses the callback logic for the creation form. I'm guessing this has to do with reflection snippets being instantiated once per http request, for which the solution seems to be DispatchSnippets, but I'm not sure how to use a DispatchSnippet in this situation, especially given that the method is defined in a Mapper, then called later in a snippet.

Is there an example of DispatchSnippets being used to use a snippet twice on the same page? Sorry for not posting any code but it's big and convoluted. Any advice would be greatly appreciated.

Thanks,
Adam

AGYNAMIX Torsten Uhlmann

unread,
Jun 13, 2012, 3:09:19 AM6/13/12
to lif...@googlegroups.com
Hi Adam,

I can say I understood your explanation fully, I just grasped "Ajax request" and "snippet instance".

The thing is, if you use a class snippet (not object), then one instance of the snippet is created per http request and for all subsequent ajax requests. An exception is StatefulSnippet, which would survive multiple http requests…

It doesn't seem I answered your question but maybe it points you in the right direction…

Torsten. 

-- 
AGYNAMIX(R). Passionate Software.
Inh. Torsten Uhlmann | Buchenweg 5 | 09380 Thalheim
Phone:       +49 3721 273445
Fax:             +49 3721 273446
Mobile:       +49 151 12412427
Web:           http://www.agynamix.de

--
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

Adam Coimbra

unread,
Jun 13, 2012, 10:45:03 AM6/13/12
to lif...@googlegroups.com
Torsten-
Thanks for your reply. That is basically what I guessed the issue was. I'm hoping that one of the lift jedi here will just throw together an example of how to use Dispatch/StatefulSnippet for this type of thing, but that might be a tall order. In the meantime my workaround is to create a separate template/snippet for the edit dialog and load it with a jquery get request, which I imagine will cause a new instance to be created. It just seems inelegant or not the "lift way" of doing things.
Thanks again,
Adam

Antonio Salazar Cardozo

unread,
Jun 13, 2012, 11:29:36 AM6/13/12
to lif...@googlegroups.com
If the result is generated in a closure that has references to different variables, this shouldn't be a problem. If you post an example project, we may be able to help better:


Thanks,
Antonio

David Pollak

unread,
Jun 13, 2012, 2:00:48 PM6/13/12
to lif...@googlegroups.com
On Tue, Jun 12, 2012 at 11:37 PM, Adam Coimbra <adamc...@gmail.com> wrote:
Hello,
I'm building a page that has a form for creating a mapper as well as a list of all existing entries for that mapper. The list has an edit link for each mapper that is created via SHtml.a, which calls a JsCmd that appends an edit form for that entry to the page in a modal window. The edit form and the creation form are built by the same rendering/processing method defined in the singleton of the mapper (it takes a Box[Mapper] argument and runs creation logic if the argument is empty, or edits the passed mapper entry otherwise). This method is first called to construct the creation form. When the edit link is clicked, it is called again, but this time the method is passed the mapper instance to edit. When the edit form is rendered, it successfully loads the values for the existing mapper entry passed to it. But when the ajax submit button is clicked, it uses the callback logic for the creation form. I'm guessing this has to do with reflection snippets being instantiated once per http request, for which the solution seems to be DispatchSnippets, but I'm not sure how to use a DispatchSnippet in this situation, especially given that the method is defined in a Mapper, then called later in a snippet.


Snippets are not instantiated once per HTTP request.  They are instantiate once per page render.  All Ajax requests associated with a page will use the same snippet instances that were used during the initial page render or subsequent Ajax requests.
 
Is there an example of DispatchSnippets being used to use a snippet twice on the same page? Sorry for not posting any code but it's big and convoluted. Any advice would be greatly appreciated.

Thanks,
Adam

--



--
Telegram, Simply Beautiful CMS https://telegr.am
Lift, the simply functional web framework http://liftweb.net


Adam Coimbra

unread,
Jun 13, 2012, 6:39:30 PM6/13/12
to lif...@googlegroups.com
David and Antonio,
Thank you for your responses. Based on what you're saying it seems like my code should work, but I stopped going against the grain here and put together sample code. It's available here: https://github.com/adamcoimbra/snippetreuselift
If anyone could take a fresh look at it and help me out it would be greatly appreciated.
Thanks again for your help so far,
Adam

Sent from my ASUS Pad

Antonio Salazar Cardozo

unread,
Jun 17, 2012, 11:05:12 PM6/17/12
to lif...@googlegroups.com
Finally got around to having a look at this; sadly, I have exactly zero experience with mapper, so I'm not exactly sure how the default form works :/ Hopefully someone else can have a look and help you out!
Sorry,
Antonio

Adam Coimbra

unread,
Jun 18, 2012, 9:52:00 AM6/18/12
to lif...@googlegroups.com
Thanks for following up. It was an embarrassingly simple mistake. The offending line was 136 here: https://github.com/adamcoimbra/snippetreuselift/blob/master/src/main/scala/adam/model/Location.scala
Basically I was doing a jQuery click() on the html id I had assigned to the submit button for the snippet. Since this id was the same for all submit buttons/instances of the snippet, it was calling the submit button on the first one (the creation snippet). Silly mistake. There's probably a better way to do this by using a JsCmd to pull the value of map.getBounds.getSouthWest.lat/lng/etc... into the hidden field rather than setting its value client-side with jQuery as I do in the example. But that's an issue for another time. Again thanks for taking a look... I realize that the example I posted is not really the minimal amount of code to demonstrate the issue. Chances are if I had actually reduced it to the minimum amount of code, I would have found my mistake sooner.
By the way, the defaultForm is just a snippet method that I wrote for displaying the "default creation form" for Locations in my project. I put it in the mapper because I wanted all the Location related code to be contained in the Location model, but it's really just a snippet method.
Adam

Antonio Salazar Cardozo

unread,
Jun 18, 2012, 10:48:42 AM6/18/12
to lif...@googlegroups.com
Got it. Happy to see you found the fix! :)
Thanks,
Antonio
Reply all
Reply to author
Forward
0 new messages