ajaxButton not working when using Lift Wiring
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
精彩评论