Guestbook in LiftWeb

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+"'")
  }

}

}

}

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.