Twelve, er, Ten, er, Eight HTML Attributes Explained...
25 May 2016


UPDATE: Jiri made the point that using ic-poll I can simplify the example even more. Thanks Jiri!

In my last post I mentioned a nifty little live stock quote app that I built using only twelve intercooler attributes and a couple of lines of javascript. I restructured things a bit and managed to knock it down to just ten attributes just eight! Even better.

Again, here is the demo:

In this post, I will explain the details of the app, which was built in SparkJava, looking at each piece of functionality.

The Ticker Input Form

The ticker input form consists of the following html:

  <form id="form" ic-post-to="/" ic-target="#main"
                 autocomplete="off">
    <input type='text' id='ticker-input'
           class='form-control input-lg' name='ticker'
           placeholder="Enter a stock ticker..."/>
  </form>

There are two intercooler attributes here, telling the form to post to / and to target the #main div, which surrounds the entire main body of the application.

Making Newly Added Tickers Flash

You will notice a green flash on the row when a ticker is added to the table. To do this, a class is added to the row of a newly added ticker, new-ticker. Then the following CSS was added:

  .ic-transitioning .new-ticker td {
    background-color: #a5d1a6;
  }

  .new-ticker td {
    background-color: transparent;
    transition: all 1s;
  }

This sets the background of the newly added row to a light green when intercooler first swaps in the content (the ic-transitioning class is on the parent content) and then transitions it to transparent. This gives the flashing effect you see above.

Deleting A Ticker

On each row you will see a trashcan icon that can be used to remove a given ticker. The HTML for this element looks like so:

  <a ic-target="#main" ic-delete-from="/$ticker.symbol">
    <i class="fa fa-trash" aria-hidden="true"></i>
  </a>

This tells intercooler to issue a DELETE to the URL corresponding to the tickers symbol, which rerenders the table and then replaces the content of the #main div (just like the form above).

Clearing All Tickers

The link to clear all tickers is implemented very similarly to the link to clear a single ticker. Here is the HTML:

<a ic-target="#main" ic-delete-from="/"><i>Clear All</i></a>

We issue a DELETE but to /, which clears the tickers and re-renders the main UI.

Making The Table "Live"

Now the tricky part, making the table update. To do this, we add the following intercooler attributes a div surrounding the table:

  <div ic-poll="5s" ic-src="/">

This div will hit the / URL every five seconds. The returned content is going to be just the table of updated ticker information.

We use / to serve both the top level page as well as this request. How do we do that?

Intercooler includes a parameter, ic-request, when it issues an AJAX request, so we can test for that parameter when determining what to render to the client:

if( "true".equals( req.queryParams( "ic-request" ) ) )
{
  return View.renderRaw( "ticker_table.html.vm",
                         "tickers", tickers,
                         "states", states );
} else {
  return View.renderPage( "index.html.vm",
                          "tickers", tickers,
                          "states", states);
}

We could get even fancier and test for the target of the request, which is also included as a parameter, but this is enough for now.

Making The Price Flash

In order to make the price flash green or red, depending on if it has gone up or down relative to the last price we saw. This is done by adding an up or down class to the td holding the asking price, and then adding this bit of CSS:

.ask {
  color: rgb(51, 51, 51);
  transition: all 2s ease;
}

.ic-transitioning .ask.up {
  color: green;
}

.ic-transitioning .ask.down {
  color: red;
}

When intercooler inserts the new table, cells with the up class will start with color set to green. Then intercooler removes the .ic-transitioning class from the element that was updated and the CSS transition takes the colors back to the default semi-black, causing the nice flash effect.

A Bit of Javascript

I said there were two lines of javascript. That was exaggerating a bit, there are nine lines if you include the boilerplate as well, so lets look at it:

$(function(){
  $('body').on('applicationError', function(elt, msg){
    $.jGrowl(msg, { header: 'ERROR' });
  });
})

Intercooler.ready(function(){
  $("#ticker-input").focus()
})

There are two sections here: first the standard jQuery ready function which hooks up an event handler on the applicationError event and shows a jGrowl notification. This is used on the server side to communicate error messages to the client side using the X-IC-Trigger response header, like so:

  res.header( "X-IC-Trigger",
              "{\"applicationError\":[\"Ticker Not Valid!\"]}" );

This is a very clean way to communicate from the server to the client.

The second bit of javascript is run in the Intercooler.ready() method, which is the intercooler equivalent of the jQuery ready concept, but is run on every completed Intercooler request. We use this to refocus the ticker input.

That's It!

And that's it! Not a lot of code for a pretty slick little UI with some nice visual effects. I hope this gives you an idea of how powerful intercooler is.

Here are links to the raw code:


| The Comments Section |