Robin Green
Robin Green

Reputation: 33093

How does JsCmd work in Lift?

I presume that it compiles the enclosed code into Javascript, but how does the code get compiled rather than executed? For example, this code from Simply Lift:

object AjaxExample {
  def render = {
    // state
    var name = ""
    var age = "0"
    val whence = S.referer openOr "/"
​
    // our process method returns a
    // JsCmd which will be sent back to the browser
    // as part of the response
    def process(): JsCmd= {
​
      // sleep for 400 millis to allow the user to
      // see the spinning icon
      Thread.sleep(400)

      // do the matching
      asInt(age) match {
        // display an error and otherwise do nothing
        case Full(a) if a < 13 => S.error("age", "Too young!"); Noop
​
        // redirect to the page that the user came from
        // and display notices on that page
        case Full(a) => {
          RedirectTo(whence, () => {
            S.notice("Name: "+name)
            S.notice("Age: "+a)
          })
        }

        // more errors
        case _ => S.error("age", "Age doesn't parse as a number"); Noop
      }
    }
​
    // binding looks normal
    "name=name" #> SHtml.text(name, name = _, "id" -> "the_name") &
    "name=age" #> (SHtml.text(age, age = _) ++ SHtml.hidden(process))
  }
}

Upvotes: 0

Views: 1434

Answers (2)

Hedley
Hedley

Reputation: 1122

For any process method like this that is going to be invoked by ajax, the Scala code in the method can be divided into two parts:

  1. Code that will be executed as normal on the server.
  2. Code that will be converted to javascript and sent back to the browser.

The only code that will be converted to javascript is the code returned from the method, which, as you can see from the method signature, is a Lift JsCmd object. In this specific example, the return values from the process method are the return values from the various case statements. The first case statement calls S.error, the second one calls S.notice and the third one calls S.error. It is these that will be converted to javascript to be sent back to the browser. If you want to see the actual javascript, it will be logged by Lift. e.g. if I have a form with a "title" attribute and I report an error by calling S.error("title", "wrong title"), then my log shows:

13:32:32.841 [291876857@qtp-349619216-4] DEBUG comet_trace - AJAX Response: 
8b5ruvtezi521nbful5n7s3cp
InMemoryResponse(try{jQuery("#lift__noticesContainer__").each(function(i)   
{this.innerHTML = "<div id=\"lift__noticesContainer___error\"><ul>
<li>wrong title</li>
</ul></div>";});} catch (e) {}
try{jQuery("#title").each(function(i) {
this.innerHTML = "<span id=\"title\">wrong title</span>";});} 
catch (e) {}, 
List((Content-Length,295), (Content-Type,text/javascript; charset=utf-8)), 
List(), 200)

If you want to look at a few more examples of using JsCmd, I'd recommend "Exploring Lift":

http://exploring.liftweb.net/master/index-11.html

Btw, for Lift questions I'd recommend asking on the Lift google group rather than Stack Overflow. It's the official support channel and the community is very responsive.

Upvotes: 1

pr1001
pr1001

Reputation: 21962

JsCmd doesn't compile or execute anything. Rather it's a more type-safe form of constructing Javascript strings that can be sent to the browser, where they might be executed.

Upvotes: 5

Related Questions