Jim Driscoll's Blog

Notes on Technology and the Web

Archive for the ‘HTML5’ Category

Bootstrap for Responsive Design

leave a comment »

This post is part of a series examining the Modern Web. Currently, I’m trying to assess pain points in creating a Single Page application, and to do that, I’ve created a simple application which does inventory management. You can find the (somewhat sloppy) code on Github, if you want to follow along.

After my previous post looking at the Model layer, today we’ll examine how to handle responsive design using Bootstrap. (Please forgive the hokey formatting in this post, WordPress Markdown support is still pretty badly broken.)

I just need to say it: using Bootstrap is a treat, and I’m utterly in love. Can you love a UI framework? Apparently so.

Consider the process of making a menu that will appear at the top of your page. You want it to look nice, both on mobile devices as well as the desktop. Let’s also make it “stick” to the top of the page, even when you scroll.

To do that, you take a nav tag, and decorate it with a few CSS classes:

<nav class="navbar navbar-default navbar-static-top" role="navigation">

The part that you want to display when collapsed goes into a separate header:

<div class="navbar-header">
    <button type="button" class="navbar-toggle" 
      data-toggle="collapse" data-target="#navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="#home">JQ Product</a>
</div>

The three spans with class="icon-bar" are there to show a classic “three lines” icon when the menu is collapsed. Now, when the navigation menu is too small horizontally to display everything, only the three lines icon and your branding link are displayed.

After that, just list all the links you want to see in the navbar, as a list:

<div class="collapse navbar-collapse" id="navbar-collapse">
    <ul class="nav navbar-nav">
        <li>
            <a href="#products&page=1">Product</a>
        </li>
        <li>
            <a href="#categories&page=1">Category</a>
        </li>
    </ul>

(Note that since this div collapses, I’ve added the appropriate CSS classes. Uncollapsed, this will all appear horizontally, collapsed, this all appears vertically. It’s a nice effect on a phone.)

There’s even facilities to to add search forms, as well as to right justify elements of your menu:

        <form class="navbar-form navbar-right" role="search">
            <div class="form-group">
                <input id="searchinput" type="text" 
                    class="form-control" placeholder="Search">
            </div>
            <span id="search-nav-btn-holder">
                <div id="search-nav-btn" class="btn-group">
                    <button type="button" 
                       class="btn btn-default dropdown-toggle" 
                       data-toggle="dropdown">
                        Search
                        <span class="caret"></span>
                    </button>
                    <ul class="dropdown-menu" role="menu">
                        <li>
                            <a class="search-btn" 
                              href="#products&search=">
                                Search Products
                              </a>
                        </li>
                        <li>
                            <a class="search-btn" 
                              href="#categories&search=">
                                Search Categories
                              </a>
                        </li>
                    </ul>
                </div>
            </span>
        </form>
    </div>
</nav>

This last bit of code you see above sets up a form in the menu bar for search, pulls it all the way to the right, and adds a drop down selection button, using the dropdown-menu on a ul tag. All declaratively. Annotating an a tag with class="search-btn" even gives a nice rounded button which distinguishes search buttons from other types of buttons on the page.

As I said in the intro, I’m quite smitten with Bootstrap, and I could probably go on and on about what it does, but if this example looks interesting to you, check out their documentation on what components it offers, it’s quite good. Their whole website is a nice example of use as well, and view source is very instructive.

Next up, we’ll deal with some of the harder parts of creating your own Thin Server app – specifically, view management.

Written by jamesgdriscoll

January 25, 2014 at 12:05 PM

Posted in Bootstrap, HTML5

Thin Server the Hard Way (Model layer)

leave a comment »

This post is part of a series examining the Modern Web. Currently, I’m trying to assess pain points in creating a Single Page application, and to do that, I’ve created a simple application which does inventory management. You can find the (somewhat sloppy) code on Github, if you want to follow along.

After my previous post looking at routing, today we’ll examine how to handle the model layer of our single page app.

Architecture

The first step on something like this is to decide on an initial architecture. QEDServer has a fairly simple REST API for fetching and updating records in the database – the only mildly tricky part is to format and pass it parameters. So a fairly lightweight wrapper around the jQuery AJAX API is probably all that’s required. Let’s model what how it’d be used, in this case for fetching a page of results containing the names of Categories for our products:

        qedModel.getCategories({
            page: currentPage,
            search: search,
            error: onFetchError,
            success: onFetchSuccess,
            complete: onFetchAlways
        });

Implementation

The REST API we’re using already has a paging facility (you pass it a URL param of ?page=number) as well as search (passing a URL param of ?q=searchterm), so the JavaScript API wrapper we need to develop only needs to smartly handle parameter building for the URL, which is a pretty simple task. We’ll also want to have success, error and complete callbacks, which are handled by the jQuery AJAX API already. So, the finished code is really pretty simple:

        getCategories: function getCategories(params) {
            var error = params.error || null;
            var success = params.success || null;
            var complete = params.complete || null;
            var page = params.page || 1;
            var search = params.search;
            var endpoint = '/categories.json?';
            if (!!search) {
                endpoint = endpoint + '&q=' + search;
            }
            endpoint = endpoint + '&page=' + page;
            $.ajax({
                type: 'GET',
                url: endpoint,
                success: success,
                error: error,
                complete: complete,
                dataType: 'json'
            });
        }

A thin wrapper around the AJAX API, which simply builds a URL and returns the results in the supplied callbacks.

Much like building a front controller, this was trivially easy, but it didn’t have to be – there’s other features we could add in here, the most important of which are cacheing and pagination. Rather than always using the server to handle pagination and fetching values from the server every time, it would be far, far better to prefetch large chunks of data from the server, and let the client model layer handle the caching. But because of the design of the QEDServer REST API, which only allows fetching of 10 records at a time, that would have been counter productive in this case. And cacheing server data on the client opens up the problem of currency – making sure that the client data and server data are in sync. This implementation mostly just hand-waves that away.

Pain Points

In my simple implementation, there really were no pain points, but as I mentioned, I’d hope that any client side Model layer would handle cacheing and pagination as well as offer some hints on how to implement data synchronization.

So, with the Model and Front Controller out of the way, it’s time to move into the View Layer, which presented far more problems. But first, we’ll detour into what capabilities Bootstrap provides.

Written by jamesgdriscoll

January 25, 2014 at 11:44 AM

Posted in ajax, HTML5, REST, web

HTML5 Semantic Tags

with one comment

Over the weekend, I was reading Mark Pilgrim’s great book on HTML5 – and when I got to the part about the semantic tags, I thought it might be worth a quick mention.

In case you’ve missed out on HTML5 in general (and don’t want to take the time to read that book I linked above), the idea behind semantic tags is that many sites use div blocks to mark out the same kinds of content, over and over. Content like headers, footers, and nav bars. Changing straight <div> tags to tags like <header>, <footer>, and <nav> is granting these tags semantic meaning, hence the name – semantic tags.

Semantic tags are a great idea. They offer a lot advantages over plain vanilla divs, especially for screen readers… but support in IE is pretty broken… The essential problem is this: unlike all other major browsers, IE doesn’t know how to style unknown tags. So the following code won’t work:

 

<style>
    .border {
        border: solid black;
    }
</style>
...
<section class="border">test3</section>

Ah, I hear the more informed folks in the audience say, there exists a library to fix this problem: the HTML5 Shiv. You can use it like so:

 

<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

This simple script will allow styles to be placed on unknown tags in IE… So, that’s a good start, but there are a few problems with it. For one thing, it relies on JavaScript, so if JavaScript is disabled, your styling will fail catastrophically. Similarly, applying print styles may not work, since JavaScript won’t necessarily be run as part of the print process (note: I haven’t tested this fully, but that’s sure what it looks like in brief testing). There are reports that nesting seems to mess stuff up applying styles correctly, but my testing hasn’t found anything broken in this way that isn’t already broken in IE’s CSS support.

Of course, there is a way around even that: If you are running JSF or some other server side processing on your backend, you could do User Agent detection, and emit <div>’s to IE and the semantic tags to all other browsers. Then, by styling the tags solely with classes and ID’s, it should be possible to make something that gets around the client side issues. Here’s a section from a component that does just that.

 

@FacesComponent(value = "navtag")
public class NavTag extends UIComponentBase {
    
    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        boolean isIE = false;
        UIComponent component = getCurrentComponent(context);
        String style = (String) component.getAttributes().get("style");
        String styleClass = (String) component.getAttributes().get("styleClass");
        ResponseWriter responseWriter = context.getResponseWriter();
        String ua = context.getExternalContext().getRequestHeaderMap().get("User-Agent");
        if (ua != null && ua.contains("MSIE") && !ua.contains("Opera")) {
            isIE = true;
        }
        if (isIE) {
            responseWriter.startElement("div", null);
        } else {
            responseWriter.startElement("nav", null);
        }
        responseWriter.writeAttribute("id", getClientId(context), "id");
        responseWriter.writeAttribute("name", getClientId(context), "clientId");
        if (styleClass != null) {
            responseWriter.writeAttribute("class", styleClass, "styleClass");
        }
        if (style != null) {
            responseWriter.writeAttribute("style", style, "style");
        }
    }

Should JSF add these tags to JSF 2.1? I’d love to hear your comments, below…

Written by jamesgdriscoll

February 9, 2010 at 11:23 PM

Posted in HTML5, JSF