Same Snippet, Different Designs

You’re building a web site and the designers send you XHTML templates with essentially the same form on two different pages, but each page uses a slightly different layout. Being the good coder you are, you want to reuse the same submit-handling code on the back-end to prevent code duplication. This is easy to handle using Lift snippets.

The form lets a user add a new restaurant to our restaurant review site. So we create a snippet like this (it just prints the submitted data for now):

import scala.xml._
import net.liftweb.util.Helpers._
import net.liftweb.http._

class CreateRestaurant {
  def render(xhtml: NodeSeq): NodeSeq = {
    var name = ""
    var address = ""
    var phone = ""

    def createRestaurant() = println("Created " + name + ", " + address + ", " + phone)

    bind("form", xhtml, "name" -> SHtml.text(name, name = _),
                        "address" -> SHtml.text(address, address = _),
                        "phone" -> SHtml.text(phone, phone = _),
                        "submit" -> SHtml.submit("Add", createRestaurant))
  }
}

Next we can create two different forms in our XHTML templates and bind them to the same CreateRestaurant snippet. We are free to modify the design inside the snippet, as long as we bind the same form elements in each one.

Here’s the first form template:

  <lift:CreateRestaurant form="POST">
    <h3>Add a new restaurant</h3>
    <table>
      <tr><td>Name</td><td><form:name><input type="text"/></form:name></td></tr>
      <tr><td>Address</td><td><form:address><input type="text"/></form:address></td></tr>
      <tr><td>Phone</td><td><form:phone><input type="text"/></form:phone></td></tr>
      <tr><td></td><td><form:submit><input type="submit"/></form:submit></td></tr>
    </table>
  </lift:CreateRestaurant>

And here’s the second form template:

  <lift:CreateRestaurant form="POST">
    <table>
      <tr>
        <th>Name</th>
        <th>Address</th>
        <th>Phone</th>
        <th></th>
      </tr>
      <tr>
        <td><form:name><input type="text"/></form:name></td>
        <td><form:address><input type="text"/></form:address></td>
        <td><form:phone><input type="text"/></form:phone></td>
        <td><form:submit><input type="submit"/></form:submit></td>
      </tr>
    </table>
  </lift:CreateRestaurant>

Same form, just different layouts: the first has the fields arranged horizontally while the second lays them out vertically. When Lift renders them they both look different but behave exactly the same way on the back-end, because they both reuse the same snippet code.

CreateRestaurant1

CreateRestaurant2

No more need to duplicate back-end form submit handling code!

Advertisements

One thought on “Same Snippet, Different Designs

  1. Nice post.

    What if you want to do the opposite? Using one template with multiple snippets?
    e.g. when you have a screen showing all the messages and a screen only to show messages for a specific day.

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 )

Google+ photo

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

Connecting to %s