I do it like this:
Let's say it's a list of companies in which the name of the company
links to the company's website.
So you have a snippet that handles these Companies. Let's call it
CompanyOps.scala. In the snippet, you have a method which we'll call
list. In the method, you get the list of companies and their URLs, and
then you loop through that list and bind each name and url to an XML
element that will be passed in by the bind method.
Here's an example method, much like Derek's:
def list(xhtml: NodeSeq): NodeSeq = {
val companies = (however you get the data as a Seq of Company objects)
companies.flatMap(company =>
bind("company", xhtml,
"link" -> <td><a href={company.url}>company.name</a></td>
)
)
}
The "list" method on the CompanyOps snippet takes a NodeSeq and returns
a NodeSeq. You pull the list of companies out of the database and store
it in the val "companies". Then you use flatMap to loop through that
list of companies. For each company, you call the method bind and pass
in the namespace ("company"), the NodeSeq that was passed in from the
view, and a map of element names to data.
So if the company is Google, then an XML element like this:
<company:link/>
Will be replaced with <td><a href="http://google.com/">Google</a></td>
In your view template, you create your table, and you put a call to this
snippet method around the part you want to call:
<table>
<lift:CompanyOps.list>
<tr>
<company:link/>
</tr>
</lift:CompanyOps.list>
</table>
The "lift:CompanyOps.list" element calls the "list" method in the
CompanyOps snippet and passes it the NodeSeq it contains. Then the call
to bind in the list method takes that NodeSeq (<tr><company...</tr>)
repeatedly and makes a list of <tr> elements in which the
<company:link/> element is replaces with the <td><a...></a></td> element.
Note that bind works with NodeSeqs, so you can't do this:
bind("company", xhtml,
"name" -> company.name,
"url" -> company.url
)
You have to do this:
bind("company", xhtml,
"name" -> Text(company.name),
"url" -> Text(company.url)
)
Which wraps each string in an XML Text node.
Lift does not permit *any* code in the view, so you *cannot* do the
looping or call methods directly in the view. You use XML elements to
call a snippet, and then either return XHTML directly, or use bind to
bind to XML elements in your view.
Note that you could also do the whole thing in the snippet:
def getList: NodeSeq = {
val companies = ...
for (company <- companies) yield <tr><td>{company.name}</td></tr>
}
Then in your view:
<table>
<lift:CompanyOps.getList/>
</tr>
Does this help, or did I misunderstand your question?
Chas.
Derek Chen-Becker wrote:
> I would do this with a snippet tag that looked like:
>
> <lift:MyTable.foo>
> <table>
> <tb:entries>
> <tr><td><entry:name /></td></tr>
> </tb:entries>
> </table>
> </lift:MyTable.foo>
>
> Then the snippet would look like
>
> class MyTable {
> def foo (xhtml : NodeSeq) : NodeSeq = {
> val data = ... fill this in ...
>
> val entries =
> data.flatMap(bind("entry", chooseTemplate("tb", "entries", xhtml),
> "name" -> Text(_.name)))
>
> bind("tb", xhtml, "entries" -> entries)
> }
> }
>
> That's from memory so I may be a little off. I'm also assuming that data
> is some sort of Scala collection. Anyways, the combination of bind and
> chooseTemplate lets you keep all the presentation XML and Scala logic
> cleanly separated.
>
> Derek
>
> On Sun, Apr 12, 2009 at 10:03 PM, [email protected]
> <mailto:[email protected]> <[email protected]
> <mailto:[email protected]>> wrote:
>
>
> Hello:
>
> Thanks for the previous answers of my questions.
> I would like to know how to make the following example work by Lift:
> ( I use the old style Java scriptlet for example ).
>
> <table>
> <% for (int i = 0; i < data.size(); i++) { %>
> <tr><td><%= data.name <http://data.name> %></td></tr>
> <% } %>
> </table>
>
> I cannot find an example like this, and I don't know if it should be
> done by a single snippet with all the rows, or some list/array to
> iterate in the view.
>
> Thanks.
>
>
>
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---