onload sending an Ajax Request with parameter

165 views
Skip to first unread message

Gautam

unread,
Jul 14, 2010, 3:48:47 PM7/14/10
to Lift
Hi,

I am new to the lift world and would like to take suggestion from you
guys regarding building one important feature of my app. I need to
display a list of contents which I fetch from Lucene and Cassandra.
Now say I need to display 20 such descriptions (in a page), instead of
doing one shot query and binding it to the UI, I want it to create 20
placeholders, which some keys in the UI and as the page loads I want
to post 20 ajax requests (which passes this key along with it) to load
its individual contents. Would be interested to know what would be a
good and easy approach.

Would really appreciate your help.

Thanks
Gautam

Naftoli Gugenheim

unread,
Jul 14, 2010, 4:53:10 PM7/14/10
to liftweb
One approach would be to have separate snippet to render items, which could take the id from S.attr, and output <lift:lazy-load><lift:ItemSnippet id={id}/></lift:lazy-load>.
It would be nice if the code that inspired LazyLoad would be in Lift so that one could render lazy xml from within a snippet. Say it would go in SHtml (very questionable that that's the right place to throw everything), you could write SHtml.lazy(calcXml) (it would take a call by name and wrap it in an ajax call).



--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.


David Pollak

unread,
Jul 14, 2010, 7:17:31 PM7/14/10
to lif...@googlegroups.com

I think your best bet is to use Lift's LazyLoading snippet:

<lift:lazy-load>
  <lift:mySnippet to_load="1">
    stuff to bind
  </lift:mySnippet>
</lift:lazy-load>

<lift:lazy-load>
  <lift:mySnippet to_load="2">
    stuff to bind
  </lift:mySnippet>
</lift:lazy-load>

Lift will take care of farming off the rendering and push the changes to the page when they are computed.

Thanks,

David
 
 

Would really appreciate your help.

Thanks
Gautam
--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

Gautam Mr

unread,
Jul 15, 2010, 8:10:11 AM7/15/10
to lif...@googlegroups.com
Thanks a lot Naftoli & David for your quick reply.
It indeed gave me a direction and I am able to achieve what I wanted.
But when I add <lift:embed> to use template I am facing some issues. Here is what I am doing

I have a index.html which has following :
<lift:surround with="default" at="content">
    First Page <br/>
    <table>
        <lift:BlogDisplayer.load>
            <ll:load/>       
        </lift:BlogDisplayer.load>
    </table>     
</lift:surround>
----------------------

Then I have a template named blog-template.html (which I placed under templates-hidden). It contains following code:

<table>
            <tr>
                <td><b><bd:title/></b></td>
            </tr>
       
 </table>
-----------------------
Then I have a scala snippet which has the following code:

class BlogDisplayer {
   
    def load (ns:NodeSeq):NodeSeq = {
       
        val xml = <lift:lazy-load><lift:BlogDisplayer.display id="12" eger_eval="true"><lift:embed what="blog-template"/>  </lift:BlogDisplayer.display></lift:lazy-load>
       
       bind ("ll", ns,
                "load" -> xml)
    }
   
   
    def display (ns:NodeSeq):NodeSeq = {
        val id:String = S.attr ("id") openOr "xx"
 
        println (":::" + id)
       
        bind ("bd", ns,
                "title" ->  Text ("Title XYZ"))       
    }

}
------------------------

When I execute it I get a big exception like this::::

Error locating template/templates-hidden/blog-template.html.
Message::11:9: document must contain exactly one element

scala.xml.dtd.ValidationException: :11:9: document must contain exactly one elementnet.liftweb.util.PCDataXmlParser.reportSyntaxError(PCDataMarkupParser.scala:175)
scala.xml.parsing.MarkupParser$class.reportSyntaxError(MarkupParser.scala:858)
net.liftweb.util.PCDataXmlParser.reportSyntaxError(PCDataMarkupParser.scala:98)
scala.xml.parsing.MarkupParser$class.document(MarkupParser.scala:220)
net.liftweb.util.PCDataXmlParser.document(PCDataMarkupParser.scala:98)
net.liftweb.util.PCDataXmlParser$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(PCDataMarkupParser.scala:188)
net.liftweb.util.PCDataXmlParser$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(PCDataMarkupParser.scala:188)
net.liftweb.util.ControlHelpers$class.tryo(ControlHelpers.scala:46)
net.liftweb.util.Helpers$.tryo(Helpers.scala:34)
net.liftweb.util.ControlHelpers$class.tryo(ControlHelpers.scala:82)
--------------------------

I am unable to make anything out of this exception... Would really appriciate yoru help.

BTW, I could not find any method by name bind in SHtml, so I used the other approach.
Note: Without <lift:embed> its working perfectly fine.

Thanks
Gautam

Gautam Mr

unread,
Jul 15, 2010, 2:51:08 PM7/15/10
to lif...@googlegroups.com
Looks like in a child template (which is called with <lift:embed>) you cannot have anything with HTML tags <p> or <pre> at the very beginning.

I had a line with <p> tag at the very beginning of blog-template.html and that's why it was not working.

<p> this is template page</p>

<table>
            <tr>
                <td><b><bd:title/></b></td>
            </tr>
       
 </table>

Not sure why it should not support <p> <pre> kind of HTML tags ath the begining of a template. Though <p> and <pre> works in between.

Thanks
Gautam

David Pollak

unread,
Jul 15, 2010, 4:12:57 PM7/15/10
to lif...@googlegroups.com
This indicates that there is more than 1 tag in blog-template.html and the XML parser is barfing.  You can use <lift:children> </lift:children> around all the tags in blog-template.html and you'll be golden.

David Pollak

unread,
Jul 15, 2010, 4:13:48 PM7/15/10
to lif...@googlegroups.com
On Thu, Jul 15, 2010 at 11:51 AM, Gautam Mr <mrgau...@gmail.com> wrote:
Looks like in a child template (which is called with <lift:embed>) you cannot have anything with HTML tags <p> or <pre> at the very beginning.

I had a line with <p> tag at the very beginning of blog-template.html and that's why it was not working.

<p> this is template page</p>

<table>
            <tr>
                <td><b><bd:title/></b></td>
            </tr>
       
 </table>

Not sure why it should not support <p> <pre> kind of HTML tags ath the begining of a template. Though <p> and <pre> works in between.

An XML document must contain a single root element.  The XML parser is looking for an XML document, not a series of tags.  See my previous answer about using <lift:children>

Gautam Mr

unread,
Jul 15, 2010, 4:51:00 PM7/15/10
to lif...@googlegroups.com
Thanks for the clarification. Thanks a lot.

Gautam Mr

unread,
Jul 16, 2010, 3:40:09 AM7/16/10
to lif...@googlegroups.com
How does multiple <lift:lazy-load> behaves in one page.

I tried putting three <lift:lazy-load> tag, but looks like it only recognizes the first one, remaining ones it skips.
Here is the html code:


<lift:surround with="default" at="content">
    <table>
        <lift:lazy-load>
            <pre>First Lazy call</pre>
        </lift:lazy-load>
        <lift:lazy-load>
            <pre>Second Lazy call</pre>
        </lift:lazy-load>
        <lift:lazy-load>
            <pre>Third Lazy call</pre>
        </lift:lazy-load>
    </table>
</lift:surround>

Am I missing something? I should be able to place as many lazy-load tag in a page right?
Moreover I have seen that Comet Actor gets inserted with this tag. Does it include One Comet per tag?


Thanks
Gautam

David Pollak

unread,
Jul 16, 2010, 9:41:51 AM7/16/10
to lif...@googlegroups.com
On Fri, Jul 16, 2010 at 12:40 AM, Gautam Mr <mrgau...@gmail.com> wrote:
How does multiple <lift:lazy-load> behaves in one page.

I tried putting three <lift:lazy-load> tag, but looks like it only recognizes the first one, remaining ones it skips.
Here is the html code:


<lift:surround with="default" at="content">
    <table>
        <lift:lazy-load>
            <pre>First Lazy call</pre>

        </lift:lazy-load>
        <lift:lazy-load>
            <pre>Second Lazy call</pre>

        </lift:lazy-load>
        <lift:lazy-load>
            <pre>Third Lazy call</pre>
        </lift:lazy-load>
    </table>
</lift:surround>

Am I missing something? I should be able to place as many lazy-load tag in a page right?

You can put as many as you want on the page.  If this is not the case, open a ticket.
 
Moreover I have seen that Comet Actor gets inserted with this tag. Does it include One Comet per tag?

My reading of the code says one comet actor per page, no matter the number of lazy loads.  Maybe Marius can help us out as he implemented the code.

Gautam Mr

unread,
Jul 16, 2010, 2:03:08 PM7/16/10
to lif...@googlegroups.com
Have created one ticket.
https://www.assembla.com/spaces/liftweb/tickets/588-multiple--lift-lazy-load--in-the-same-page-does-not-work-as-expected

Hope it will get some attention as we have to rely heavily on this feature.

Thanks
Gautam

Naftoli Gugenheim

unread,
Jul 16, 2010, 3:00:24 PM7/16/10
to liftweb
You don't really need to use lazy-load for your use case, nor the comet that it uses. Try the following approach:

  def myBindLazy(xhtml: NodeSeq): NodeSeq = {
    def myActualBind = ...
    val id = "lazy"+Helpers.nextFuncName
    val (_, exp) = SHtml.ajaxInvoke{() => SetHtml(id, myActualBind) }
    
    <div id={id}>...{Script(OnLoad(exp.cmd))}</div>
  }

Not sure if you want the OnLoad -- you can leave it out.
You can use a span instead of a div, of course.
Your actual binding logic needs to be defined in myActualBind.
This is just a sketch, stripped out from actual code. You can refactor it to fit your code of course.

David Pollak

unread,
Jul 16, 2010, 3:48:03 PM7/16/10
to lif...@googlegroups.com
On Fri, Jul 16, 2010 at 12:00 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
You don't really need to use lazy-load for your use case, nor the comet that it uses.

Naftoli -- you're dead wrong.  The problem with using an Ajax based approach is connection starvation.  You're going to do the requests serially (because Lift serializes Ajax requests and even if Lift didn't, the browser will open a certain maximum number of connections to the server [2, 6, 15 depending on your browser])  That's why we added LazyLoad
 

David Pollak

unread,
Jul 16, 2010, 3:50:53 PM7/16/10
to lif...@googlegroups.com
I've written a lazy load snippet and an associate test.  To run it, put the following in your template:


  <lift:LazyLoad>
    <lift:Bog/>
  </lift:LazyLoad>

  <lift:LazyLoad>
    <lift:Bog/>
  </lift:LazyLoad>

  <lift:LazyLoad>
    <lift:Bog/>
  </lift:LazyLoad>

  <lift:LazyLoad>
    <lift:Bog/>
  </lift:LazyLoad>

  <lift:LazyLoad>
    <lift:Bog/>
  </lift:LazyLoad>

I'm enclosing the file (and will attach it to the ticket to help Marius or whoever tackles the problem with a fix).

One of the other things is that it's a snippet that a user can write (well, a very experienced Lift user).  There's very little magic in Lift that's not exposed to you as the user.  Most of Lift is layers upon a central core of code and much of Lift is just helpers for common patterns.
Bog.scala

Naftoli Gugenheim

unread,
Jul 16, 2010, 4:00:23 PM7/16/10
to liftweb
Oh whoops--forgot about that! Thanks for reminding me--I better correct my app!

Gautam Mr

unread,
Jul 17, 2010, 6:48:11 AM7/17/10
to lif...@googlegroups.com
Thanks a lot David. Appreciate your quick response and detail explanation and tips.
I will try this out and let you know.

Thanks
Gautam

Marius

unread,
Jul 17, 2010, 8:44:58 AM7/17/10
to Lift
Dave,

I addressed the issue in the existent code, tested it and now it's on
reviewboard. I did not use your approach due to a couple of problems
with Bog.scala:

1. ajax functions from lazy loaded content does not work. In my test
app I have a ajaxSelect that didn't trigger bound function.
2. It doesn't unwatch the comet actor from the client code after.
After the comet lifespan is exceeded the client code would continue
the comet cycle sending the comet guid, but this comet is dead hence
the user is resirected to the homepage. That's not really the desired
behavior. The unwatch stuff is fired right before the lifespan limit
to unlist this comet from the client.

However if someone wants to refactor LazyLoad, feel free to do so but
I don't have much time to do this.

Br's,
Marius
> >https://www.assembla.com/spaces/liftweb/tickets/588-multiple--lift-la...
>
> > Hope it will get some attention as we have to rely heavily on this feature.
>
> > Thanks
> > Gautam
>
> > On Fri, Jul 16, 2010 at 7:11 PM, David Pollak <
> > feeder.of.the.be...@gmail.com> wrote:
> >>> On Fri, Jul 16, 2010 at 2:21 AM, Gautam Mr <mrgautam...@gmail.com>wrote:
>
> >>>> Thanks for the clarification. Thanks a lot.
>
> >>>> On Fri, Jul 16, 2010 at 1:43 AM, David Pollak <
> >>>> feeder.of.the.be...@gmail.com> wrote:
>
> >>>>> On Thu, Jul 15, 2010 at 11:51 AM, Gautam Mr <mrgautam...@gmail.com>wrote:
>
> >>>>>> Looks like in a child template (which is called with <lift:embed>) you
> >>>>>> cannot have anything with HTML tags <p> or <pre> at the very beginning.
>
> >>>>>> I had a line with <p> tag at the very beginning of blog-template.html
> >>>>>> and that's why it was not working.
>
> >>>>>> <p> this is template page</p>
>
> >>>>>> <table>
> >>>>>>             <tr>
> >>>>>>                 <td><b><bd:title/></b></td>
> >>>>>>             </tr>
>
> >>>>>>  </table>
>
> >>>>>> Not sure why it should not support <p> <pre> kind of HTML tags ath the
> >>>>>> begining of a template. Though <p> and <pre> works in between.
>
> >>>>> An XML document must contain a single root element.  The XML parser is
> >>>>> looking for an XML document, not a series of tags.  See my previous answer
> >>>>> about using <lift:children>
>
> >>>>>> Thanks
> >>>>>> Gautam
>
> >>>>>>> net.liftweb.util.PCDataXmlParser$$anonfun$apply$2$$anonfun$apply$5$$anonfun $apply$6.apply(PCDataMarkupParser.scala:188)
> >>>>>>> net.liftweb.util.ControlHelpers$class.tryo(ControlHelpers.scala:46)
> >>>>>>> net.liftweb.util.Helpers$.tryo(Helpers.scala:34)
> >>>>>>> net.liftweb.util.ControlHelpers$class.tryo(ControlHelpers.scala:82)
> >>>>>>> --------------------------
>
> >>>>>>> I am unable to make anything out of this exception... Would really
> >>>>>>> appriciate yoru help.
>
> >>>>>>> BTW, I could not find any method by name bind in SHtml, so I used the
> >>>>>>> other approach.
> >>>>>>> *Note*: Without <lift:embed> its working perfectly fine.
>
> >>>>>>> Thanks
> >>>>>>> Gautam
>
> >>>>>>> On Thu, Jul 15, 2010 at 4:47 AM, David Pollak <
> >>>>>>> feeder.of.the.be...@gmail.com> wrote:
> >>>>>>>>> liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com >
> >>>>>>>>> .
> >>>>>>>>> For more options, visit this group at
> >>>>>>>>>http://groups.google.com/group/liftweb?hl=en.
>
> >>>>>>>> --
> >>>>>>>> Lift, the simply functional web frameworkhttp://liftweb.net
> >>>>>>>> Beginning Scalahttp://www.apress.com/book/view/1430219890
> >>>>>>>> Follow me:http://twitter.com/dpp
> >>>>>>>> Blog:http://goodstuff.im
> >>>>>>>> Surf the harmonics
>
> >>>>>>>> --
> >>>>>>>> You received this message because you are subscribed to the Google
> >>>>>>>> Groups "Lift" group.
> >>>>>>>> To post to this group, send email to lif...@googlegroups.com.
> >>>>>>>> To unsubscribe from this group, send email to
> >>>>>>>> liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com >
> >>>>>>>> .
> >>>>>>>> For more options, visit this group at
>
> ...
>
> citiţi mai multe »
>
>  Bog.scala
> 4KVizualizaţiDescărcaţi

Gautam Mr

unread,
Jul 17, 2010, 2:24:54 PM7/17/10
to lif...@googlegroups.com
Wow that's extraordinary speed!!! You guys are really cool!!
Once its approved and reviewed which release it would be part of?

Once again thanks a lot.

Thanks
Gautam

2010/7/17 Marius <marius...@gmail.com>
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

Marius

unread,
Jul 17, 2010, 2:55:04 PM7/17/10
to Lift
well most likely it'll be on master, not sure if it will be in other
branches as well.

Br's,
Marius

On Jul 17, 9:24 pm, Gautam Mr <mrgautam...@gmail.com> wrote:
> Wow that's extraordinary speed!!! You guys are really cool!!
> Once its approved and reviewed which release it would be part of?
>
> Once again thanks a lot.
>
> Thanks
> Gautam
>
> 2010/7/17 Marius <marius.dan...@gmail.com>
> ...
>
> read more »

Timothy Perrett

unread,
Jul 17, 2010, 2:58:03 PM7/17/10
to lif...@googlegroups.com
Err, we are not committing to master right now are we? All dev is being done on the 2.x series branches for 2.8 and 2.7.7 right?

Cheers, Tim

Marius

unread,
Jul 17, 2010, 3:01:35 PM7/17/10
to Lift
ok ... so be it.
> ...
>
> read more »

David Pollak

unread,
Jul 17, 2010, 5:44:04 PM7/17/10
to lif...@googlegroups.com


2010/7/17 Marius <marius...@gmail.com>

Dave,

I addressed the issue in the existent code, tested it and now it's on
reviewboard. I did not use your approach due to a couple of problems
with Bog.scala:

1. ajax functions from lazy loaded content does not work. In my test
app I have a ajaxSelect that didn't trigger bound function.

Okay.  On the other hand, calculating the javascript function on the CometActor thread is a serious problem because if the calculation takes a long time and there are multiple components on the page, there will be message starvation.  Further, it also means that the lazily loaded components are computed serially rather than out of the thread pool.
 
2. It doesn't unwatch the comet actor from the client code after.
After the comet lifespan is exceeded the client code would continue
the comet cycle sending the comet guid, but this comet is dead hence
the user is resirected to the homepage.

The comet lifespan is the life of the comet component after it has not been seen on a page, so if it's still on the page, the lifespan calculation won't be triggered.

Given the complexity of the issues, let's hold off on putting any code into the builds.  I'll work on a complex test that takes into account all the issues you've raised and roll it into the Example codebase so we've got something to test again.  I'm flat out between now and 3pm PDT on Tuesday (my OSCON preso), but after that I'll have some time to look.

I'm glad you identified issues that I overlooked and I'm looking forward to making the Lazy Loading component a more robust part of Lift.

To the original poster, once the code is finished and gone through a Review Board cycle (http://reviewboard.liftweb.net), it gets added to the three maintained branches of Lift (2.x-2.7, 2.x-2.8, and 3.0)  So, you can use the 2.1-SNAPSHOT code to get the latest changes.  The SNAPSHOTs are generally stable and instabilities result in the cone of shame (e.g., http://twitter.com/dpp/status/9591471689 )  We have periodic milestone builds... the next one (2.1-M1) is scheduled for August 4th.  See https://liftweb.assembla.com/spaces/liftweb/milestones


 
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890

Marius

unread,
Jul 18, 2010, 10:35:35 AM7/18/10
to Lift


On 18 iul., 00:44, David Pollak <feeder.of.the.be...@gmail.com> wrote:
> 2010/7/17 Marius <marius.dan...@gmail.com>
>
> > Dave,
>
> > I addressed the issue in the existent code, tested it and now it's on
> > reviewboard. I did not use your approach due to a couple of problems
> > with Bog.scala:
>
> > 1. ajax functions from lazy loaded content does not work. In my test
> > app I have a ajaxSelect that didn't trigger bound function.
>
> Okay.  On the other hand, calculating the javascript function on the
> CometActor thread is a serious problem because if the calculation takes a
> long time and there are multiple components on the page, there will be
> message starvation.  Further, it also means that the lazily loaded
> components are computed serially rather than out of the thread pool.

Yeah indeed. Looks like each lazy-load snippet should have its own
CometActor. Thus after each content has been rendered, the Comet Actor
should be unwatched from the client allowing it to exceed the
lifespan.


>
> > 2. It doesn't unwatch the comet actor from the client code after.
> > After the comet lifespan is exceeded the client code would continue
> > the comet cycle sending the comet guid, but this comet is dead hence
> > the user is resirected to the homepage.
>
> The comet lifespan is the life of the comet component after it has not been
> seen on a page, so if it's still on the page, the lifespan calculation won't
> be triggered.

IMHO once a certain lazy-load was rendered the comet-actor should be
unwatched from the client.

>
> Given the complexity of the issues, let's hold off on putting any code into
> the builds.  I'll work on a complex test that takes into account all the
> issues you've raised and roll it into the Example codebase so we've got
> something to test again.  I'm flat out between now and 3pm PDT on Tuesday
> (my OSCON preso), but after that I'll have some time to look.


> I'm glad you identified issues that I overlooked and I'm looking forward to
> making the Lazy Loading component a more robust part of Lift.

sure, looking forward to see what you come up with.

>
> To the original poster, once the code is finished and gone through a Review
> Board cycle (http://reviewboard.liftweb.net), it gets added to the three
> maintained branches of Lift (2.x-2.7, 2.x-2.8, and 3.0)  So, you can use the
> 2.1-SNAPSHOT code to get the latest changes.  The SNAPSHOTs are generally
> stable and instabilities result in the cone of shame (e.g.,http://twitter.com/dpp/status/9591471689)  We have periodic milestone
> builds... the next one (2.1-M1) is scheduled for August 4th.  Seehttps://liftweb.assembla.com/spaces/liftweb/milestones
> ...
>
> citiţi mai multe »

Naftoli Gugenheim

unread,
Jul 18, 2010, 1:38:38 PM7/18/10
to liftweb
From the complexity that is sounds will be necessary even using a comet actor, I'm wondering if it might be simpler to implement it in the following way without comet. I'm not clear if it will solve connection starvation.
LazyLoad could output functions that do the ajax request like I wrote above, except they won't be called yet since they're inside functions. Then one ajax request will call one function. On the server side, it will hold a chain of the requests so on returning the SetHtml for function A it will also return an invocation of function B, etc.



--
Reply all
Reply to author
Forward
0 new messages