Here is the actual code (only the names have been shortened):
def getWidgetsBlock: NodeSeq = {
val widgets =
Model.createNamedQuery[Widget]("findAllWidgets")
.findAll
.toList.map((x: Widget) => {(x.id.toString, x.name)})
val currentWidgets = JPA.setToWrapper(thing.widgets)
.toList.map((x: Widget) => {(x.id.toString, x.name)})
val unusedWidgets = (widgets -- currentWidgets)
<div>
<h3>Widgets</h3>
{JPA.setToWrapper(thing.widgets).toList.map(
(x: Widget) => {
<div id={"ap" + x.id.toString} class="block clear">
<div class="column span-1">{SHtml.ajaxButton("-",
() => {
val w = Model.getReference[Widget](classOf[Widget], x.id)
val t = Model.getReference[Thing](classOf[Thing], thing.id)
p.widgets.remove(w)
Model.merge(t)
Model.flush()
SetHtml("widgetsBlock", getWidgetsBlock)
}, ("title", "Remove this widget"), ("class", "removeButton")
)}</div>
<div class="column span-18 last"
style="clear:right">{x.name}</div>
</div>
})}
{(if (unusedWidgets.isEmpty) Text("") else
<div id="addAp" class="block clear">
<h4>Add an widget</h4>
{SHtml.ajaxForm(
<div class="column span-1"><input type="submit" value="+"
class="addButton" title="Add this widget"/></div>
<div class="column span-18 last">{
SHtml.select(unusedWidgets, Empty,
(id: String) => {
val w = Model.getReference[Widget](classOf[Widget],
id.toLong)
val t = Model.getReference[Thing](classOf[Thing],
thing.id)
p.widgets.add(w)
Model.merge(t)
Model.flush()
SetHtml("widgetsBlock", getWidgetsBlock)
}, ("id", "selectWidget")
)
}</div>)}
<hr class="space"/>
</div>
)}</div>
}
bind("thing", xhtml,
"widgetsBlock" -> getWidgetsBlock
)
And on the page:
<div id="widgetsBlock" class="block clear">
<project:widgetsBlock/>
</div>
Attached is a screen shot of what this actually looks like on the live
site for anyone who's interested. (Assessment Purpose = Widget, Project
= Thing.)
I see that SetHtml should work, but am not sure what I'm doing wrong.
I think this is a pretty cool way to handle many-to-many relationships,
so if I can get this to work, maybe Derek can sneak it into the JPA
example somehow. If he agrees with my assessment, that is.
Chas.
David Pollak wrote:
>
>
> On Sun, Jan 11, 2009 at 4:58 PM, Charles F. Munat <[email protected]
> <mailto:[email protected]>> wrote:
>
>
> Yeah, I found this and have been playing with it, but am sort of stuck.
> What I'm doing looks something like this (but is much more complicated):
>
> def getForm: NodeSeq = {
> val widgets = [List(id,name) of unused widgets]
>
> if (widgets.isEmpty)
> <span>All widgets are in use.</span>
> else
> SHtml.ajaxForm(
> <input type="submit" value="+" class="addButton"/>
> {SHtml.select(
> widgets,
> Empty,
> (id: String) => {
> val w = Model.getReference[Widget](classOf[Widget], id.toLong)
> val t = Model.getReference[Thing](classOf[Thing], thing.id
> <http://thing.id>)
> t.widgets.add(w)
> Model.merge(t)
> Model.flush()
> SetHtml("widgetForm", getForm)
> }
> }, ("id", "optionSelector")
> )
> }
>
> def view(xhtml: NodeSeq): NodeSeq = {
> bind("widgets", xhtml, "addForm" -> getForm)
> }
>
> Then I want to insert it here:
>
> <lift:ThingOps.view>
> <div id="widgetForm"><widgets:addForm/></div>
> </lift:ThingOps.view>
>
> If I replace "getForm" in SetHtml above with <span>Rats!</span>, then it
> works perfectly and when I click the + button the entire form is
> replaced by "Rats!" But I need it to regenerate the form with either one
> fewer widgets in the select *or* the entire form replaced by an "All
> widgets are in use" message. But calling getForm from within getForm
> doesn't work... I get the current form, not the form *after* the widget
> has been added.
>
> I say the real one is more complicated because it also lists the widgets
> with "-" buttons next to them which permits them to be removed from the
> set. Each of these actions also requires the XHTML to be recalculated
> and redisplayed.
>
> Does this make any sense?
>
>
> Yes. The problem as far as I can see is the place that state is
> maintained (the list of what widgets are on the page) is missing.
> You've got the t.widgets.add call, but the whole state management thing
> seems like a mystery and I think that's where the problem is coming from.
>
>
>
>
>
>
> Chas.
>
> David Pollak wrote:
> > SetHtml(id: String, stuff: NodeSeq)
> >
> > It's a JsCmd and it replaces the contents of the Elem with the
> give id
> > on the page with stuff.
> >
> > Is this what you were looking for?
> >
> > On Sun, Jan 11, 2009 at 2:58 PM, Charles F. Munat <[email protected]
> <mailto:[email protected]>
> > <mailto:[email protected] <mailto:[email protected]>>> wrote:
> >
> >
> > Is there a JsCmd for replacing a NodeSeq? I want an AJAX
> button to run
> > some code on the server, generate a NodeSeq, and then replace the
> > similar NodeSeq on the page. I'm looking through the commands
> and I
> > don't see how to do that, except to use Run and then JQuery...
> >
> > Am I missing something? This seems like a common scenario, so I'm
> > thinking it's probably in there.
> >
> > Thanks,
> > Chas.
> >
> >
> >
> >
> >
> > --
> > Lift, the simply functional web framework http://liftweb.net
> > Collaborative Task Management http://much4.us
> > Follow me: http://twitter.com/dpp
> > Git some: http://github.com/dpp
> >
> > >
>
>
>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
> >
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
<<inline: Picture 2.png>>
