Up: Chapter 13

13.5 Getting Ajaxy

The ClickMe snippet is a little more complex, but it demonstrates, especially on the “Second Page” the power of Lift’s View First in which no particular component on the page is the dominant component. Here’s the ClickMe code:
ClickMe.scala
// make sure this is the snippet package so Lift
// can find the snippet
package code
package snippet
​
// some inputs
import net.liftweb._
import util._
import Helpers._
import http._
import js.JsCmds._
​
// our snippet
object ClickMe {
  // variables associated with the request
  private object pos extends RequestVar(0)
  private object cnt extends RequestVar(0)
​
  // create a function (NodeSeq => NodeSeq)
  // set the onClick method of the button
  def render = {
    // capture our position on the page
    val posOnPage = pos.set(pos.is + 1)
​
    "button [onclick]" #> 
    SHtml.ajaxInvoke(() => {
      cnt.set(cnt.is + 1) // increment the click count
      Alert("Thanks pos: "+posOnPage+
          " click count "+cnt)
    })
  }
}
We define two RequestVars that hold request-scoped values. For Lift, the scope of a request is the initial full HTML page load plus any Ajax requests associated with that page.
When the snippet’s render method is called, we capture the current value for the pos RequestVar.
The snippet associates the invocation of an Ajax call with the button’s onclick method. When the button is clicked, the function is invoked.
The function closed over the scope of the position of the button on the page. The buttons all share the cnt RequestVar and thus for a single page load, the number of button-presses are counted. If you have 5 different browser tabs open to the same page, each tab will have a unique page count.
This demonstrates the component nature of Lift and why having complex items on a page means not having a front-controller, but having lots of behaviors associated with lots of HTML elements.
Up: Chapter 13

(C) 2012 David Pollak