How do I update an HTML class from a CometActor
Question
In response to some asynchronous event on the server, I want to update the class of an HTML node in order to reflect its updated status. I know the id of the node, and the class I want to change it to. What JsCmd do I need to use to update the class? In general, where can I find a good reference on the JsCmd's and what they do?
A simple example:
case class UpdateClass(id: String, htmlClass: String)
class ClassUpdater extends CometActor {
override def lowPriority: scala.PartialFunction[scala.Any, scala.Unit] = {
case UpdateClass(id, htmlClass) =>
partialUpdate(Noop /* now what? */)
}
def render = NodeSeq.Empty
}
So if I had the HTML:
<html><body>
<lift:comet type="ClassUpdater"/>
<div id="foo" class="bar">insert text here</div>
</body></html>
If I sent the message UpdateClass("foo", "baz")
to my ClassUpdater
, I want the class of my div
to change to baz
.
Solution
Edit: I’ve found a better way to do it. The old code is now more of a blueprint for more complicated stuff.
Looks like there is a more straightforward way of doing it without jQuery:
SetElemById("foo", JE.Str("baz"), "className")
which translates to a JavaScript call
document.getElementById("foo").className = "baz";
Note that JE.Str("baz")
can be any JsExp
and if you could also do something like
SetElemById("foo", JE.Str("baz"), "firstChild", "className")
which would change the class of the first child. (See: SetElemById)
You can have a look at the code for the JsCMD trait for what else is possible with build-in commands.
In case you want to something more complicated, however, something like this might help you. It sends a jQuery command which will change the class in #oldId
to newClass
.
case class ChangeClassAtId(oldId: String, newClass: String) extends JsCmd {
def toJsCmd = """try {
$(""" + ("#" + oldId).encJs + """).attr("class", """ + newClass.encJs + """);
} catch (e) {}"""
}
Changing all occurrences of a class everywhere is a bit more complicated:
case class ChangeClass(oldClass: String, newClass: String) extends JsCmd {
def toJsCmd = """try {
$(""" + ("." + oldClass).encJs + """).each(function(){
$(this).addClass(""" + newClass.encJs + """).removeClass(""" + oldClass.encJs + """);
});
} catch (e) {}"""
}
You should use it instead of Noop
of course.
OTHER TIPS
EDIT - I misread the question. My answer merely updates the contents of the div.
You'll want something like this:
case UpdateClass(id, htmlClass) => partialUpdate(SetHtml(id, Text("TEXT TO SHOVE INTO DIV")))