Lift is a Scala based web framework and recently i have had the chance to work on it.
One can produce web page content using very few lines of code – some credit here goes to the power of Scala.
Wicket is too a beautiful component oriented web framework -
but one has to write considerable amount of code in java – again mostly due to the absence of support
for closures and other features seen in Scala.
However both are excellent frameworks and in this blog i will attempt to recreate the GuestBook Example
seen in Wicket.
So here goes -
Use case: Tts a simple form which allows users to add a comment – all comments are public.
So a comment added by a user can be seen by another.
Code
HTML code:
<pre>
<div class="lift:surround?with=default;at=content">
<hr />
<h2>GuestBook</h2>
<hr />
<form class="lift:Form.ajax">
<!-- Comments is the name of snippet being used -->
<div class="lift:Comments">
<h3><strong> Add your comment here </strong></h3>
<!-- this will render the textarea for entering comments -->
<pre><field:entry/></pre>
<!-- this will make an Ajax call to the back end for adding/rendering the new comments -->
<pre><field:add/></pre>
<!-- For lazily loading the comments - which may take time -->
<pre>
<div class="lift:LazyLoad">
<ul id="container" class="lift:Comments.showComments">
<span id="placeholder"/>
</ul>
</div>
</pre>
</div>
</form>
</div>
<pre>
Now – The Snippet code
class Comments extends DispatchSnippet{
/***
* Map the method names in HTML to Snippet Methods to avoid reflection
* Also Not shown over here - but Comments needs a mapping in Boot.scala
*/
def dispatch = {
case "showComments" => showComments
case "render" => render
case _ => render
}
def showComments = {
val opList = UserComments.msgs.map {
el => <li>{el}</li><li>{new Date().toString}</li>
}
var res =""
opList.foreach {buffer => {
var bufferAsString = ""
buffer.foreach (el => bufferAsString = bufferAsString + el )
res = res + bufferAsString
}
}
"#placeholder" #> Unparsed(res)
}
// Render the initial page.
def render(n:NodeSeq) = {
bind("field" ,n,
"entry" -> SHtml.textarea("",(x:String) => {UserComments.msgs = x :: UserComments.msgs},"rows"->"5","cols" -> "10"),
"add" -> (SHtml.hidden(addEntry) ++ <input type="submit" value="Add"/>)
)
}
// Handler called during the click of Add/submit from UI.
// Since the new comment is already added during the setter callback of textarea,
// this simply returns the XHTML required to show the new comment along
// with old ones.
private def addEntry():JsCmd = {
Thread.sleep(500)
val opList = UserComments.msgs.map {
el => <li>{el}</li><li>{new Date().toString}</li>
}
var res =""
opList.foreach {buffer => {
var bufferAsString = ""
buffer.foreach (el => bufferAsString = bufferAsString + el )
res = res + bufferAsString
}
}
JsRaw("document.getElementById('container').innerHTML ='"+res+"'")
}
}
}
}