Title: Programing Assignment 2 – Styling your App

The purpose of this assignment is to introduce you to styling web pages in Grails and includes:

  • Grails Plugin
  • HTML and CSS
  • Groovy
  • Twitter Bootstrap CSS framework
  •  g-tags

You are to complete this programming assignment individually. In this assignment you will make new “responsive” public views for the book store’s website using Twitter Bootstrap. In particular you will make responsive home page, and list views for books and authors.

Step 1: Learn HTML and CSS

If you do not already know HTML and CSS read the brief tutorial at W3Schools:

http://www.w3schools.com/html/default.asp
http://www.w3schools.com/css/default.asp

You do not have to be an expert in HTML and CSS, but you should know the basis. Read through the tutorial in the above links and get an idea of the language and the material that is in these tutorials. This will take you about 60 minutes. When you need to use the language, you’ll know where to look.

Step 2: Study Twitter Bootstrap Framework

Read the Twitter Bootstrap documentation. In particular read about the CSS styling and the components documentations:

http://getbootstrap.com/css/
http://getbootstrap.com/components/

Read this material should take you about 60 minutes. Pay particular attention to the section about the bootstrap grid system:

http://getbootstrap.com/css/#grid

This is the heart of the bootstrap’s responsiveness. Realize when you read about the grid system that it is mobile first. This implies that on small devices the columns in a row will be stacked. When you set the div class, you specify how it will look for the larger devices. You will have to experiment with grid system to fully understand it.

Also study the Navbar component:

http://getbootstrap.com/components/#navbar

Step 3: Add the Bootstrap Plug-in

Add the Bootstrap CSS framework plugin to your Authors and Books web app that you made in the previous assignment:

http://grails.org/plugin/twitter-bootstrap

1. Add to BuildConfig.groovy

Adding the plugin only requires adding one line to the BuildConfig.groovy configuration file in the plugin closure:

runtime ':twitter-bootstrap:3.1.1.3'

You can add it anywhere in the plugin closure, but I put all the plugins that I add to the bottom of the closure. They required files are automatically downloaded and added to your project files.

2. You also need to add two lines to the Config.groovy file.

grails.plugins.twitterbootstrap.fixtaglib = true
grails.plugins.twitterbootstrap.defaultBundle = 'bundle_bootstrap'

You can add these lines to the bottom of the Config.groovy file.

3. You need to add the following line to the grails-apps/assests/stylesheets/application.css file

*= require bootstrap

Add this line above the last “*/” line.

4. You also need to add the following line to the grails-app/assets/javascript/application.js file

//= require bootstrap

Add this line to the bottom of the comments section and above the if-statement for JQuery.

Now when you run the app the first time, you’ll see that bootstrap is compiled with the app. If you view the web site not much will have changed. The font looks better, but you have not made any views using bootstrap components.

Step 4: Add the Site Layout and Navbar template and Home Pages

I like to save the Grails generated views for the administrative backed of the web site because they do not have to look as pretty as the public views and the generated pages look well enough for administrative use. For the public pages, I like to separate the views and style and use bootstrap from scratch or cut and paste code from the generated views.

1. To make the bookstore home page create a HomeController using the grail command create-controller. Call the controller Home. You will not have to add any code to the controller.

2. Read about Grails templates and layout at the Grails documentation:

http://grails.org/doc/latest/guide/theWebLayer.html#viewsAndTemplates
http://grails.org/doc/latest/guide/theWebLayer.html#layouts

You should notice that there is already a main.gsp layout in views/layout/ directory. Your public pages will use a different layout, so create a gsp file in the views/layout/. Call it site.gsp.

3. Read about how to use bootstrap in your views in the bootstrap plugin documentation.

https://github.com/groovydev/twitter-bootstrap-grails-plugin/blob/master/README.md#usage-in-grails-resources-support

Copy and paste the code in the documentation to your site.gsp

Change the title of the layout page from “Grails” to “Book Store”

We want the Book Store public pages to have a navigation bar. Because the navigation bar will appear on every page it should be rendered by the site layout. Just below the “body” tag and above the <g:layoutBody/> add the line

<g:render template="/navbar" />

Your site.gsp file should look like

<!DOCTYPE html>
<html>
<head>
   <title><g:layoutTitle default="Book Store"/></title>
   <asset:stylesheet src="application.css"/>
   <g:layoutHead/>
</head>
<body>
    <g:render template="/navbar" />
    <g:layoutBody/>
    <asset:javascript src="application.js"/>
</body>
</html>

4. Make the navigation bar template.

Add the “_navbar.gsp” file to the views directory. Note the leading underscore. You need it in the name of the file so that Grails can identify it as a template view.

Read about navbar in the bootstrap documentation:

http://getbootstrap.com/components/#navbar

Copy and paste the code into your _navbar.gsp template view.

<nav class="navbar navbar-default navbar-static-top" role="navigation">
   <div class="container-fluid">
 
       <!-- Brand and toggle get grouped for better mobile display -->
       <div class="navbar-header">
            <!-- This makes the button for collapsed navbar -->
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            </button>
            <g:link controller="Home"><div class="navbar-brand title-name">Book Store</div></g:link>
       </div>
 
       <!-- Collect the nav links, forms, and other content for toggling -->
       <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">
                  <li><a href="#">Books</a></li>
                  <li><a href="#">Authors</a></li> 
            </ul>
       </div><!-- /.navbar-collapse --> 
 
    </div><!-- /.container-fluid -->
</nav>

5. Make the home view.

Make the index.gsp view in the views/home/ directory. Note that the home/ directory has already been made for you when you created the HomeController.

Study the Examples in the bootstrap getting started page.

http://getbootstrap.com/getting-started/#examples

Decide how you want the Book Store home page to look. For example you may want to use a Jumbotron for the home page. Look at the page source for how the Jumbotron is coded. If you lack initiative you can use code below for your home page.

<html>
 <head>
      <meta name="layout" content="site"/>
      <title>Book Store Home</title>
 </head>
 
 <body>
      <div class="jumbotron jumb-margin">
            <div class="container">
                 <h1>Book Store</h1>
            </div>
      </div>
 </body>
</html>

Now stop and run the app again. On the start index page click on HomeController and you should see the public home page.

Step 5: Add Styling to the home Page

The public home page probably does not look as good as you like. You should add some styling.

1. Add style sheet.

Add the file “myStyles.css” to the directory grails-app/assets/stylesheet/, and then cut and paste the content below into the myStyles.css:

body{
    margin: auto;
    height: inherit;
    max-width: inherit;
}
/* Might want to move the Jumbotron by adding top margin */
.jumbotron{ 
     margin-top: 75px;
}

Now you must link your style sheet to the site.gsp file. In the head of the site.gsp file just below the asset:stylesheet tag for application.css and the link to your style sheet so that your styles will over write bootstrap styles:

<asset:stylesheet src="application.css"/>
 <asset:stylesheet src="myStyles.css"/>

If you should reverse the order the below then bootstrap styles will overwrite your styles and your styles will have no effect.

2. Adding bootstrap styling to the jumbotron.

In the home/index.gsp add the center class to the h1 tag:

<h1 class="text-center">Book Store</h1>

3. Experiment and more styling to the myStyles.css file.

Use the Chrome browser to inspect element styles. Open the Chrome browser, and cut and paste the URL into the browser’s address bar. Right click on the page and select inspect element. This will open the Developer’s Tools. The tool allows you examine styling inheritance and temporally add new styles to elements.

Note that you do not have to stop and stop the app to view your style changes. Generally, the app only needs restarting when you change the domain class.

Step 6: Make the Public Book page.

I like to use the index view pages for the controller’s public pages, so I change the names of the generated controller’s index method to “list” and the corresponding index view to “list.gsp.” We can then rewrite the code for the index method and make the view for the public pages. We can then reserve the list view for the administrative pages.

1. Change the name of Book controller’s index method and view to “list.”

2. Add the index method book.

Cut and paste the code below for the Book controller methods.

static final boolean debugIndex = true
 def index(){
 
     // Book.list() gets all Book instances from the database and puts them in a list.
     def bks = Book.listOrderByTitle()
 
     // println outputs to console
     if(debugIndex){
          println ""
          bks.each{ println it.title+" by "+Author.get(it.authorId).name}
     }
 
    // Make a list of all books title and authors
    def bkList = []
    for(int i=0; i<bks.size; i++){
         def bkAuthor = [:]
         bkAuthor.put('title', bks[i].title)
         bkAuthor.put('author', Author.get(bks[i].authorId).name)
         bkList << bkAuthor
    }
    if(debugIndex){
        println " "
        println bkList
     }
 
     // View expects a Map
     // This a Map to the list of title-author maps 
     [bkList: bkList]
 }

3. Make the new Book controller index view.

Cut and paste the code below into the views/book/index.gsp.

<html>
 <head>
    <meta name="layout" content="site"/>
    <title>Book Store Books</title>
 </head>
 
 <body>
     <h1> BOOKS </h1>
     <ul>
        <g:each in="${bkList}">
            <li> ${it.title} by ${it.author} </li>
        </g:each> 
     </ul> 
 </body>
</html>

4. Study the groovy and html code.

After stop and starting the app you should be able to view the new public book controller by clicking on the book controller link in the start page. Note that the outputs from println appear in the console. You can modify the either code and refresh page in the browser without “stopping and running” the app. Always long as no new classes are not made the browser will pick up the changes.

The programming language in the Book controller is groovy. Groovy is a scripting language built on top of Java.

http://groovy.codehaus.org/

While you study the index method code you will want to reference groovy documentation

http://groovy.codehaus.org/Documentation

You may want to read the first few tutorials in the “Getting Started Guide.”

http://groovy.codehaus.org/Getting+Started+Guide

The code in the index method makes heavy use of lists and maps. Example for using them can be found in Collections documentation.

http://groovy.codehaus.org/JN1015-Collections

In addition the code in the index method makes use of Domain class method. You can find documentation for them in the “Quick Reference” on the right of every Grails documentation page.

http://grails.org/doc/latest/ref/Domain%20Classes/listOrderBy.html
http://grails.org/doc/latest/ref/Domain%20Classes/get.html

The index view makes use of the Grails tags, g-tags. Documentation for g-tags are also found in the “Quick Reference” at the bottom under “Tags.” In particular the “each” tag is at

http://grails.org/doc/latest/ref/Tags/each.html

5. Add link to Books in the navbar.

In the _navbar.gsp file, replace the anchor tag with the g-link tag. Replace the tag

<li><a href="#">Books</a></li>

with

<li><g:link controller="Book">Books</g:link></li>

6. Test the new link.

In the browser use the navbar to navigate back and forth from the books view to the home view.

Step 7: Make the Authors public views.

You are on your own making the new Author index method and view. Use what you have learned from the steps above.

We want the page to look a little different than the Books view. The Author public view should be hierarchical list. The top most list should be an alphabetical list of author and below each author should be an indented alphabetical list of book titles for the author. In other words we want the view to appear similar to:

Authors

Mark Twain
    Huckleberry Finn
    Tom Sawyer
Stephen King
    The Shining
    The Stand

Also do not forget to change the link for the Authors menu item in the navbar.

Step 9: Make the Screen Shot and Email Me

After creating the public Author index view, make a screen shoot of the public Author view. The URL is

http://localhost:8080/cs4760progassign/author/index

Email me (pastel at mtu.edu) the screen shot if you are a cs4760 student. The subject of the email should be

“cs4760 Programming Assignment 2 Proof”

If you are an hu4642 student, email Stefka the screen shot. The subject of the email should be

“hu4642 Programming Assignment 1 Proof”

Congratulations, you have completed your second programming assignment and made you’re your own index controller method and view.