~ read.

How to write a Front-End

Ok – most people are kind of intimidated by that, but since we know how a node.js server is running, how a database is created, how one can read and store items it should not be a big deal.

At this point I would strongy recommend using a software like Aptana (http://aptana.com/). It's free, and it's a professional tool used by many web developers. It allows you to administer huge projects, it is an ideal solution for web projects, it supports GIT (which I will talk about later in a later post), it supports a bundle of languages, it has syntax highlighting and and and...

Ok – download it and create a new webproject.

The first thing we have to do is to create a frontend.html file, like this minimal html-file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">   
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>SYLLABUS - CREATE A FRONTEND</title>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
  </head>
  
  <body>
  
  </body>
  
</html>

Let's have a look at a few lines. There are a few information about the DOCTYPE. Why for? Because it could be an xml file instead of html – an information which is crucial if an agent tries to extract some information.

Then we have some META information, like the charset which is used on this page. That is really important – since a lot oh shit can happen if charsets do not match. German umlauts could not be displayed, thing of that kind.

We can ignore most of it – but there are a few lines which are as important as our require calls in the noce.js.

In this case we want tol use the Jquery library, which extends Javascript and allows nice visual effects.

 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
 

Here we add the sources. What happens? Our browser jumps to the ajax.googleapis.com website and fetches the respective file – but if we have downloaded them and installed them in our working directory we would have them locally. And then we would just write:

 <script src="jquery.min.js"></script>

Our script src just looks for another file.
And since we want to create a frontend it would be good to have something like also.

Let us create such a file in our directory and then embed it into the html document. Let's call it frontend.js for simplicities sake (the suffix js being an indicator that it is a javascript file.

This is cool for Aptana – but it then knows how to apply the correct syntax highlighting.

I would leave a little trace in our javascript file so that we can see it is properly loaded:

alert("HI, FRONTEND");

Next step. We want to embed the newly created javascript in our html file – which is the hub for all our resources. That's what we need:

<script src="frontend.js"></script>

Since a few functions inside this file might rely on JQuery it might be a good idea to place it after the JQuery includes.

A frontend deals with graphics – so we need to embed a *css file tool, we call it frontend.css. CSS means cascaded style sheets – and here all the informations of the layout are stored.

And that's how our minimal html file looks in the end.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>SYLLABUS - CREATE A FRONTEND</title>

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>

  <script src="frontend.js"></script>
    <link href="frontend.css" media="screen" rel="stylesheet" type="text/css" /> 

  </head>
    <body>
    </body>
  </html>
  

Let's start!

We have just prepared stuff and have not achieved anything practical. That is one of the downsides of programming. You have to be aware that the most painstaking aspect if getting your environment working.
And that's worse than working hard. Just waiting to be able to do so.

To avoid further problems let us agree on a good practice in javascript design. Before we begin to write a single line we create a thing that is called a namespace, like this:

Frontend = {};

Why should we do this? A namespace allows us to keep all variables connected to a certain codeword.

Imagine you want to define a global variabe a, like that:

var a;

How can you be sure that none of the JQuery programmers has used a variable like that and defining it yourself will break the code of others?

You can't. Exactly that is why the guys of Jquery created a namespace themselves. They used the Dollar sign as a namespace for all JQuery operations.

When you read something like this

$("body").append("This is my new frontend");

you can be sure this is a Jquery function.
Let's try if works – so just place it somewhere in our frontend.js file.

We should use it ion conjunction with another JQUery function which is called $(document).ready

What it does is something we have seen quite a few times before. It invokes a function when the whole document (all the include files, the html tags etc) is read in. And since it has to wait we see the structure of a callback function, a function nested in another function:

So here's the content of our frontend.js. Store it and reload the html page again:

Frontend = {};
$(document).ready(function () {
        $("body").append("This is my new frontend"); 
});

An what happens? All of a sudden we see this line on the screen – although we did not have entered it into the *.html page.

Why is it so? Because we can dynamically change the so colled doc, which is the document object model of HTML and contains all the html elements.

The append function allows us to write something into the dom. Actually there is just one html element.

<body>
</body>

That's how it has been noted into our frontend.html.
But please type your F12 key – and open the console.

If you use Mozilla you will see the console at the lower botton – please type here on the tab html, in Chrome click elements.

Now you can inspect the html tag. If you click on body it will look like this:

<body>       
This is my new frontend
</body>

Obviously there is no need to write any html code manually. All this can be done by javascript.

Click again the console tab and copy-paste this into the console, press ENTER:

$("body").html(""); 

What happens? Your screen is empty – and that's logical: You have replaced the content of the body tag with an empty string.

I am sure you will ask yourself: When I replace the content, can I manipulate the visuals too? Sure you can. Type this:

$("body").css("background", "red"); 

And the whole screen turns red.
Here you can see the whole paper of Javascript and a library like Jquery. With a few lines you can modify the screen, and you can apply an animation also:

  $("body").animate({
                    "backgroundColor": "cyan",
                }, 2000);

It looks like the command – although there is a slight difference. But you should recognize it, it is a JSON notation.
This one tells the brwoser render engine to change the background color to cyan – and that the animation shall last 2000 milliseconds.

Let's start to build our frontend then.

We have already chosen a namespace, "frontend". And since we want to design our frontend whe should create an object called Designer. To make sure that is does not disturb anybody elses design fantasieswe nest it in our namespace.

So here we have it:

Frontend = {};
Frontend.Designer = function(){
    
}    

Hmm. That's an object? Why is it called function then?
When we go into that matter it get's very philosophical – and you might be in the midst of some complicated disussion about OOP, inheritance etc.

These discussions are important for the advanced – but it will lead you nowhere. It is way better to understand an object when you think of it as a complex thing.

Let's make a little console experiment then. Please type:

human = {};

or

var human = {}; 

If you enter human to see what you have created, it says “object”.
Now type in Frontend. Once again: The console log say it's an object. And Frontend.Designer?

It is a function. But what if we create such a designer, like this:

var designer = new Frontend.Designer();

type designer again – and you see you have created an object.

In Javascript – that's the point – everything is an object. Event the Frontend.Designer that is explicity declared a a function is an object.

But the best would be: Don't worry about it. Just let's proceed, it's self explaining.

Let's have a look at our code.


Frontend = {};

Frontend.Designer = function(){    
}

var designer = null;

$(document).ready(function () {
    
        designer = new Frontend.Designer();
    });    
    

First we create our namespace.
Then we create the “function” that creates a frontend designer object.

Then we declare a global var (breaking our own rule by the way) – and then create it.

Once the document is fully loaded, whe have a designer object which does – nothing.

Very bad. He shall do the job of designing the frontend to us.

But that's easy. We could create an init function and make him paint it for us. That's how it is done.


Frontend.Designer = function(){
      this.init = function()
      {
          alert("I am ready to paint");    
      }    
  }

That's how it is done. Have a look at the additional lines. We have added an init function that would send an alert.

We might expect that function to be executed – but it's not.

Please enter the following line into the console:

designer.init();

And he returns: “I am ready to paint”.
But when we say smkebody is a born painter we might want it him to paint rightaway, the very moment he is born.

That's pretty simple to achieve. We need one additional line:

Frontend.Designer = function(){    
  this.init = function()
      {
          alert("I am ready to paint ");    
      }    

  this.init();
    }
  

The moment our designer gets into life the internal function init is invoked. This is done by the prefix this, which says: I should do that, not somebody selse.

Ok – when we reload the html page, the painter says he's ready.

Painting a headerbar

Ok, let's start then. Now we do something which is pretty different to the way people deal with html.

They would write their html code into the html-page and then would manipulate just the dynamic part in Javascript.

Why don't we do that?

Because we want to see our painter do the job. There are a lot of advantages. Painting and applying interaction to an element happens in the function, it's not distributed in the code. Therefore it is a pretty neat way of learning “dynamic html” (html understood as a subset of a programming language).

The first thing we would love to have is a headerbar.

Remember how easy it was to write something into our html-page?

That's what we will do now – with the only difference that we add html tags also. That looks pretty weird for the moment – but you will get used to it and see the advantages soon. Let's stop talking. Add the bar!

this.init = function()
    {
        var s = '<div id = "HeaderBar">';
    s += 'THIS IS MY BAR';
    s += '</div>';

    $("body").append(s);
    }

We change our init function. The first line means we create a local variable s. Since it is a string it will automatically of type “string”. In higher languages you are supposed to announce that, Javascript does this casting automatically.

When we look at the content we see it is a hmtl tag:

<div id = "Bar">

Div stands for divider. We see some code inside which is an identifier called "Bar". These ientifiers are pretty important when we want to change the content of it. Remember what we did with the body?

    $("body").append("This is my new frontend"); 

And that's we way we can manipulate our bar too. The only difference. The “body” is native HTML – whereas our "Bar" is a self-built thing, and therefore we have to add the identifierer token:

    $("#HeaderBar").append("This is my new frontend"); 

So this would append this sentence to my bar.
There is a simple rule in HTML. Each opening tag shall have the respective closing tag, so the opening

has a
counterpart. That it's closing is visible through the clsoing token:

 </div>

What our Frontend.Designer does is to create a string that is appended to the body.

When we reload our page we see it's working fine.
But it's so ugly!

Here *css comes into play – and it's quite handy that we have created a frontend.css already.

So we can define our bar like that:

#HeaderBar
  {
      position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 60px;
  background: gainsboro;    
  }

We see the # token – indicating that this relates to an id.
We could have used a class instead of an id. The difference is that a class is supposed to be related to many items whereas an id should be unique. Since we will have just one headerbar we opted for an id.

When we reload our html page we should see our headerbar. We gave it an absolute position, top: 0 and left:0. Width was set to 100%, so it took the whole screen, height was to 60px (which means we can mix concepts).
To make it visible we set a background: gainsboro.

The important thing with a position: absolute is that you explicitly have to set width and height of the object.

CSS – in the current version 3 - is a great and poweful tool. We just touch the surface, by adding a little shadow to our HeaderBar

#Bar
  {
      position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 60px;
  background: gainsboro;    

  -o-box-shadow:       0 2px 6px #000000;
    -moz-box-shadow:     0 2px 6px #000000;
    -webkit-box-shadow:  0 2px 6px #000000;
     box-shadow:         0 2px 6px #000000;
    }
  

Here you can see some of the downsides of current web developmentr. For each and every browser (Opera, Mozilla, Chrome = webkit) you have to add the very same line.

But it's working – that is reconciling.

Next thing we want to add is a button that opens up a form in which we can type in our databasequery.

Pretty easy. We just have to inform our painter to do so. The only thing we have to do is to replace the text line with a another html element:

var s = '<div id = "Bar">';
    
    s += '<div class ="Trigger"><img src = "QueryForm"/></div>';
    
    s += '</div>'

What is new?

s += '<div class ="Trigger" id = "Query"><img src = "db.png"/></div>';

Since we think of a few buttons to come we have chosen a class and we have inserted into the div an image element.

That means we have to add a image to our project.
There are a lot of great internet site, like the noun project – or in this case

http://www.iconfinder.com

Look for database and chose a file that fits your asthetics.

Since we use a new class we should add it to our css file. Like this:

.Trigger
  {
      position: relative;
  float: left;
  margin-left: 10px;
  margin-top: 6px;
  width: 48px;
  height: 48px;
  background: blue;    
  }

What's new? We used a class instead of an id, the . token instead of the # token (which makes css understand it's a class).

Then the position is not absolute but relative. What does it means? It means that – if there many of these items placed in a line they would be relative positioned to each other, with a margin-left of 10 pixels and a margin-top of 6px. But since they are part of the HeaderBar which is position:absolute they are relative to the absolute coordinates of this element.

Let's have a look. What happens?

The element appears in the right position but the embedded image is not properly arranged. So let's fix that. We write another css class, like this:

.Trigger img
  {
      width: 100%;
  height: 100%;    
  }

So what does this mean. When we repeat the class .Trigger and then add the img this means that this rule is applied only to images that are nested in the respective .Trigger class. All these images shall have 100% width and 100% height. Percent of what? Of its parent element which is .Trigger and has a witdh of 48px and a height ofg 48px.

Let's have a look.

Great, it works! And now we can get rid of the ugly blue background.

We can even have some simple css interactivity, like this:

 .Trigger
  {
      position: relative;
  float: left;
  margin-left: 10px;
  margin-top: 6px;
  width: 48px;
  height: 48px;
  opacity: 0.4;
  }

.Trigger:hover
  {
      opacity: 1;    
  }

What did we do here? We have added an opacity to the Trigger element and a hover function which would have another, higher opacity.

Opacity 0 means – invisible
1 menas – totally visible

So whenever I hover over this element it gets totally visible, when my mouse is not over it is of opacity 0.4.

Getting Interactive!

Since we have a button we could make it interactive.
It's easy. Just a few lines our painter should add:

<pre><code class="prettyprint lang-js">$("#Query").click(function(){
    alert("GOSH - I am clicked ");
})</code></pre>

Let's carefully analyze these lines.
First – throgh the $ - we can identify the JQuery namespace.
Then I have this . - what does it mean?

That it's an object – as nearly everything in Javascript.
This object has a method called click – and if we apply it we see it works – at least it does not produce an error: $("#Query").click();

But that's not how it should be used. Instead we see that the function has – as a parameter – a nested function. Once again: We see the logics of a callback. When we execute the click-function Jquery gives us an event callback – and it does so the very moment when I click my button.

Great, it works!

Now what we want is not an alert but a form that allows us to input a blog entry that we might send to our databse.

Ok – let's create it.So we invoke a new function

$("#Query").click(function(){
        designer.blog_form();
    })

and it's logical that we have to create it.
Since it a job our Frontend.Designer has to perform we will write it insice this function.

So it looks like this:

Frontend.Designer = function()
{    
this.blog_form = function()
    {
        alert("show my blog form");    
    }    
    
    
this.init = function()
    {
        var s = '<div id = "Bar">';
    
    s += '<div class ="Trigger" id = "Query"><img src = "db.png"/></div>';
    s += '</div>';

    $("body").append(s);
    
    $("#Query").click(function(){
         designer.blog_form();
    });
    
    }    
    
this.init();
}

We might ask why we have written designer.blog_form() instead of this.blog_form();

Once again we are touching the peculiarities of callback function. What does this inside the $("#Query") object mean? Exactly – it means $("#Query") and not the Frontend.Designer.

There is no chance to make the keyword this persistent but by replacing it through another var that we create in the object. Usually I use self as a joker for this (which might be overruled) – this time I just used the global var designer.

We can this the inevatibility of this when we add another line to our code.

$("#Query").click(function(){
        $(this).css("background", "yellow");
    designer.blog_form();
    })

Here this is refering to the div element – and rightfully so. We click it and the background gets yellow.

Just keep this in mind, it will cause you a lot of headaches if you are not aware that you are dealing with the problem, the identity loss of your Frontend.Designer.

But carry on. Let's make our form. We could do it in HTML – but since we are already used to create it via Javascript, let us keep it that way.

this.blog_form = function()
    {
        var x = documet.getElementById("blog_form");
    if (!x)
       {
           alert("We have to create this");    
       }
    }    

We modify our blog_form function a little bit.
First we ask if there is a blog_form. It is one of the oldest function and it looks for an element with a certain.

If we had written

var x = document.getElementById("HeaderBar”);

we would have been successful, but it would be a true miracle if there was a blog_form in your dom. We just have to create it.

That's what we should do now. Three lines again:

<pre><code class="prettyprint lang-js">var s = '&lt;div id = &quot;BlogForm&quot;&gt;';
s += '&lt;/div&gt;';
$(&quot;body&quot;).append(s);</code></pre>

That looks pretty familiar – and meanwhile we also should know that we should create a css-element too. Like this one:

#BlogForm
      {
          position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      width: 50%;
      height: 70%;
      background: white;
      z-index: 2;    

   -moz-box-shadow:    2px 2px 6px #000000;
     -webkit-box-shadow:  2px 2px 6px #000000;
      box-shadow:         2px 2px 6px #000000;
      }
   

If you are interseted in understanding this, read the following paragrapgh, otherwise skip it.

Some more CSS

What's new? We know position:absolute already, we know how to use shadows, we know how to set a background, the width and height of the windows.

What's new and puzzling is this:

left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;

Margin-auto it gets automatically centered. So when left and right, top and bottom are zero, the eleent is centered in the middle of the screen.
Handy function.

End of interlude

We have the form – the entry fields are missing. So let's add them, plus an additional submit button.
We could use the inbuilt html-form, but since we want to apply our own node.js communication logic we do it a little bit different. And this will make us understand input fields by the way.

We just have to add a few lines to the inner part of our blog form. Three lines of (it's always 3, like in the fairy tales)

s += '<input id = "blog_tite" type="text"/>';
s += '<textarea id = "blog_text"/>';
s += '<div id = "submit_button"/>SUBMIT</div>'

And that'sa how the function looks like:

this.blog_form = function()
    {
        var x = document.getElementById("blog_form");
    if (!x)
    {
        var s = '<div id = "BlogForm">';
    
    s += '<input id = "blog_tite" type="text"/>';
    s += '<textarea id = "blog_text"/>';
    s += '<div id = "submit_button">SUBMIT</div';
    
    s += '</div>';
    $("body").append(s); 
    }
    }

What's new? We have 2 new element types, and text input and a textarea.

We can run it immediately – but it will look really ugly. Let's write some css styling for it.


 #BlogForm input
   {
       position: relative;
   width:    80%;
   margin-left: 10%;
   margin-top: 10px;
   height: 6%;
   background: gainsboro;
   }

 #BlogForm textarea
    {
        position: relative;
    width:    80%;
    margin-left: 10%;
    margin-top: 10px;
    height: 70%;
    background: gainsboro;
    }


 #BlogForm #submit_button
    {
        position: absolute;
    width:    30%;
    height: 30px;
    bottom: 5px;
    left: 35%;
    background: gainsboro;
    text-align: center;
    }
 

We see that we have again the interitance logic. All the text inputs insiode the #BlogForm will have a certain design, as well as the textareas.

There is one differnence though the attentive reader might notice.
Why do we write #submit_button #submit_button with a hash and textarea without.

We have to differenciate between 3 different types: the ids (marked by a #), the classes (marked by a .) and the unbuilt, native HTNL tags (marked by nothing).

That is we we write image text textarea link

Basically all we need to communicate with our server is running now. What we have to add is the communication.

It will look pretty known, like the GET commands we have already used.

The difference is: This time we do not want to GET, this time we want to POST information.

To achieve that we have to add an interaction function to our submit button:

    $("#submit_button").click(function(){
        designer.submit_blog_form();
    })

Meanwhile we should know why we use the designer here – and we should see immediatelly that we have to add another function to our Frontend.Designer, this one:

this.submit_blog_form = function()
    {
        var title = $("#blog_title").val();
    var text = $("blog_text").val();
       
    // something missing     
    }

Meanwhile we should know why we use the designer here.
With the new 2 line we see how we can extract information out of our new input elements.

There is a little difference to the regular html-elements though. If I want the content of our body, I could just write:

var content = $("body").html();

And that means that the html function of the object applies here. If it is an input field, I should use the .val() function.

Nothing special. Just a convention you shold know.

When I have all the respective values, I can submit the post. Like before I use an ajax function for this.