Creating an HTML list using CSS selectors

In the previous recipe, we learned how to show data that should be unique using a CSS selector and the id attribute of HTML tags. However, there are a lot of times when we need to show collections of data, such as the names of students in a given classroom, the list of items in a shopping cart, or a list of whatever else you can think of.

This is exactly what we will learn how to do in this recipe.

Getting ready

You can use the code from the examples we used in the previous recipe or you can start a new project.

How to do it...

A HTML list can be created by following these steps:

  1. Add the following section in the index.html file:
    <div data-lift="Animals.list">
      <ul>
        <li><span class="name"></span> - <span class="sname"></span></li>
      </ul>
    </div>
  2. Create a file called Animals.scala in the snippets folder with the following code:
    import net.liftweb.util.BindHelpers._
    import xml.Text
    
    object Animals {
      def list = {
        val animals = List(
          ("Dog", "(Canis lupus familiaris)"),
          ("Cat", "(Felis catus)"),
          ("Giraffe", "(Giraffa camelopardalis)"),
          ("Lion", "(Panthera leo)"),
          ("Horse", "(Equus ferus caballus)")
        )
    
        "li *" #> animals.map {
          a => 
            ".name *" #> Text(a._1) &
            ".sname *" #> Text(a._2)
          
        }
      }
    }
  3. Start the application and access http://localhost:8080. You'll see a page with a list of common names and scientific names of five animals, as shown in the following screenshot:
    How to do it...

How it works...

There are no secrets in HTML. We added the markup to invoke the snippet that will render the HTML file. We did this by adding l:Animals.list in the div tag.

We also added two span tags, one with class name and the other with class sname to mark where we want the content to be added when Lift transforms the HTML.

But, how did Lift change the original HTML file into a list of animal names?

As I said before, we tell Lift to invoke a method in a snippet when we add l:..... inside the class attribute of a given HTML tag. In this case, we invoked the method list of the snippet Animals.

This method receives a NodeSeq object, creates a list of tuples, and then changes the content of the <li> tag for each element in the animal list by changing the content of any tag with the name or sname classes. What we are saying to Lift is that, for each element in my list, create an <li> tag and put the first element of the tuple into a tag containing the name class and the tuple's second element into a tag containing the sname class.

You can see that the span tags are in the final HTML rendered by Lift. Why didn't Lift remove the span tags as it did in the previous recipe?

As it happens, we used #result as the CSS selector in the first example and li *, .name *, and .sname * in this one. The difference is just that of one character; that is, *.

The difference between using the character * and not using it is that when you use it, you tell Lift to change the content of the tag that matches with the CSS selector, and when you don't use it, you tell Lift to replace the tag itself. While ".name *" #> Text(...) replaces the content of a tag containing the class name with some text, ".name" #> Text(...) replaces the tag containing the class name with some text. So, the HTML for the first case will be <span class="name">some text</name>, while for the second, it will be just some text.

There's more...

You should note that, in the first recipe, we passed an integer as an argument for the #> method, while in this recipe's example, we've passed a list of CssSel. You might wonder how this is possible.

As it turns out, Lift comes with several transformation rules that are each passed as an implicit parameter to the #> method. These transformation rules "know" how to convert the parameter passed to the #> method to the correct type.

For example, if you pass an integer, the intTransform method will be used, and if you pass a list of strings, the iterableStringTransform method will be used.

Another neat and useful tool to try out while developing a Lift application is the CSS selector in the Scala REPL. You can open the Scala REPL by entering the console command in the SBT session.

Once you get the Scala REPL, import the content of Lift's Helper object, net.liftweb.util.Helper, and you are ready to start experimenting.

As a quick example, type the following code in the Scala REPL:

scala> val transformSpanContent = "span *" #> "Some Text"
scala> transformSpanContent(<span>this text will be replaced</span>)

You'll get this result:

res0: scala.xml.NodeSeq = NodeSeq(<span>Some text</span>)

As you can see, we did a quick experiment to check what happens with a scala.xml.NodeSeq object after being transformed by the CssSel we've defined.

See also

Visit http://simply.liftweb.net/index-7.10.html to learn more about CSS selectors.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.5.12