My goal is to have text displayed normally on initial load, but when an 'Edit' button is pressed, the text changes to be an input text box. The html is this:
<div class="user">
<div>
<span>Edit</span><lift:WiredUser.edit />
</div>
<div class="details">
<lift:WiredUser.email />
</div>
</div>
My wiring class looks like so:
class WiredUser {
val userToWire = (Users.userForDisplay or userDetail.currentValue).get
private object User {
val entity = ValueCell(userToWire)
val edit = ValueCell(false)
val email = edit.lift(b => entity.lift(_.getEmail.asScala.headOptio开发者_如何转开发n).get)
}
def edit = {
WiringUI.toNode(User.edit, JqWiringSupport.fade)((mode: Boolean, ns:NodeSeq) => { Wired.editable(
mode,
mode,
(b: Boolean) => ajaxButton(h("Done"), () => {User.edit.set(false); JsCmds.Noop}),
(b: Boolean) => ajaxButton(h("Edit"), () => {User.edit.set(true); JsCmds.Noop})
)})
}
def email = WiringUI.toNode(User.email, JqWiringSupport.fade)((email: Option[String], ns: NodeSeq) => {
Wired.editable(
email.getOrElse(""),
User.edit.get,
(n: String) => ajaxText(n, s => {refresh(setEmail(_, s)); JsCmds.Noop}),
(n: String) => h(n)
)
})
}
object Wired {
def editable[T](o: T, mode: Boolean, t: (T)=> NodeSeq, f: (T) => NodeSeq) : NodeSeq = {
mode match {
case true => t(o)
case false => f(o)
}
}
}
On initial load, there is an 'Edit' button that is displayed. When that button is pressed, an ajax call with the form data "F531904251245BAWYT:true" is executed, however the function attached to the ajax call is never executed: () => {User.edit.set(true); JsCmds.Noop} and the result is empty:
jQuery(document).ready(function() {
});
Any thoughts on what I might be missing?
Note that I have submitted this to the Lift google group without a response.
I have created a working example: https://github.com/OleTraveler/scala-wiring-example
I have faced with the same problem and I've found some solution. I created my custom version of net.liftweb.WiringUI (MyWiringUI), where I changed the following methods
def toNode[T](in: NodeSeq, cell: Cell[T], jsEffect: (String, Boolean, JsCmd) => JsCmd)(f: (T, NodeSeq) => NodeSeq): NodeSeq = {
val myElem: Elem = in.find {
case e: Elem => true
case _ => false
}.map(_.asInstanceOf[Elem]).getOrElse(<span id={Helpers.nextFuncName}>{in}</span>)
val (elem: Elem, id: String) = Helpers.findOrAddId(myElem)
addJsFunc(cell, (t: T, first: Boolean) => {
jsEffect(id, first, SetHtml(id, f(t, elem.child)))
})
f(cell.currentValue._1, elem)
}
and
def addJsFunc[T](cell: Cell[T], f: (T, Boolean) => JsCmd) {
for {
cometActor <- S.currentCometActor
} cell.addDependent(cometActor)
val trc = TransientRequestCell(cell)
var lastTime: Long = 0L
var lastValue: T = null.asInstanceOf[T]
for {
sess <- S.session
} sess.addPostPageJavaScript(() => {
val (value, ct) = trc.get
val first = lastTime == 0L
if (first || (ct > lastTime && value != lastValue)) {
lastValue = value
lastTime = ct
if(first) Noop
else f(value, first)
}else{
Noop
}
})
}
The most important change is:
if(first) Noop
else f(value, first)
Thats all.
Whole example you can find at here https://github.com/mmigacz/lift_wiring
Some additional information about my problem you can find on lift forum https://groups.google.com/group/liftweb/browse_thread/thread/932ce4d45ccd6582?hl=pl
精彩评论