Tutorial: Building an Invoice Template with MaterializeCSS and Jquery

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@gotgame·
0.000 HBD
Tutorial: Building an Invoice Template with MaterializeCSS and Jquery
#### Repository

https://github.com/olatundeee

#### What Will I Learn?

In this tutorial we will learn how to perform the following operations on the client side of our web applications

- Get and store the value of form inputs
- Output the value of form inputs in our browser

In addition we will be implementing an invoice template that can be used by businesses to issue receipts and invoices to their customers.

#### Requirements

-   [Ionicons Library For Icons](http://ionicons.com/)
-   [JQuery Library](https://jquery.com/)
-   [MaterializeCSS Framework](https://next.materialize.com/)
-   You can download the full source code for this tutorial on  [Github](https://github.com/olatundeee/invoice-template)

#### Difficulty

- Basic

#### Tutorial Contents

Before starting out we have to setup MaterializeCSS and other dependencies for this tutorial (jquery and ionicons). 

Information on how to do that can be found in my earlier tutorial on [how to build a landing page with MaterializeCSS](https://steemit.com/utopian-io/@gotgame/building-a-landing-page-with-materializecss-1).

After setting up materialize the next step is to build our template. 

The template is divided into three sections including

1. Header which contains addresses of both buyer and seller

2. Input form where the seller can enter details about the products including the product name, price and quantity bought. 

	This form will feature a submit button which when clicked will update a list directly below the form with the data entered into the form.

3. The third part of the form will contain a list of products and information about each updated through the form.

After the entire process we should have a simple interface like the one below

![](https://image.ibb.co/cVokOT/header_invoice.png)
![](https://image.ibb.co/dJLoco/invoice_form.png)
![](https://preview.ibb.co/mi1KHo/invoice_details.png)

Let's create our template.

The HTML code for creating this template

```markup
<!DOCTYPE html>

<html>

<head>

<!--Import Google Icon Font-->

<link  href="https://fonts.googleapis.com/icon?family=Material+Icons"  rel="stylesheet">

<!--Import materialize.css-->

<link  type="text/css"  rel="stylesheet"  href="css/materialize.css"  media="screen,projection"/>

<link  type="text/css"  rel="stylesheet"  href="css/invoice.css"  media="screen,projection"/>

<link  type="text/css"  rel="stylesheet"  href="css/ionicons.css"  media="screen,projection"/>

  

<!--Let browser know website is optimized for mobile-->

<meta  name="viewport"  content="width=device-width, initial-scale=1.0"/>

</head>

  

<body>

  

<div  class="container invoice-body">

<div  class="row">

<div  class="col l6 m6 s12 left-align">

<p>

Lorem Ipsum Company<br>

P.O. Box 18728, Non-Conformity Way<br>

Someplace Somewhere<br>

VAT No: 2617 348 2752<br>

</p>

</div>

<div  class="col l6 m6 s12 right-align">

<p>

Billed To:<br>

Sam Donald Ripley<br>

Also Living Somewhere PO Box 29618<br>

VAT No: 295 3932 6119<br>

</p>

</div>

<div  class="col l6 m6 s12 left-align">

<p><strong>Invoice No:</strong> A - 21637</p>

</div>

<div  class="col l6 m6 s12 right-align">

<p><strong>Invoice Date:</strong> 07/06/2018</p>

</div>

<div  class="col l12 m12 s12 invoice-header center-align">

<h4>INVOICE</h4>

</div>

<div  class="col l12 m12 s12 invoice-sub-header-input center-align grey lighten-3">

<div  class="container">

<div  class="row">

<form  action=""  class="col l12 m12 s12">

<div  class="row invoice-sub-header-form">

<div  class="input-field col l12 m12 s12">

<input  placeholder="Item"  id="item_sold"  type="text"  class="black-text invoice-input-form">

</div>

<div  class="input-field col l6 m6 s12">

<input  placeholder="Price"  id="price_sold"  type="number"  class="black-text invoice-input-form-half">

</div>

<div  class="input-field col l6 m6 s12">

<input  placeholder="Quantity"  id="quantity_sold"  type="number"  class="black-text invoice-input-form-half">

</div>

</div>

</form>

<div  class="submit-button center">

<a  class="waves-effect waves-light btn add-new-item"><i  class="ion-android-add left"></i>ADD ITEM</a>

</div>

</div>

</div>

</div>

<div  class="col l12 m12 s12 invoice-sub-header-output center-align">

<div  class="container item-details-output">

</div>

<div  class="container right">

<p  class="net-total"></p>

</div>

</div>

</div>

</div>

  

<!--JavaScript at end of body for optimized loading-->

<script  type="text/javascript"  src="js/jquery.js"></script>

<script  type="text/javascript"  src="js/materialize.js"></script>

<script  type="text/javascript"  src="js/invoice.js"></script>

</body>

</html>
```

---

The CSS code for our template 

```markup
body {

background: #eeeeee;

}

  

.invoice-body {

margin-top: 100px;

margin-bottom: 100px;

border: 1px  solid  #000;

padding: 50px;

background: #fff;

color: #757575;

}

  

.invoice-header {

margin-top: 100px;

}

  

.invoice-sub-header-input {

margin-top: 50px;

}

  

.invoice-sub-header-output {

margin-top: 50px;

}

  

.invoice-input-form {

border: 1px  solid  #000  !important;

padding-left: 20px  !important;

}

  

.invoice-input-form-half {

border: 1px  solid  #000  !important;

padding-left: 10px  !important;

margin-left: 3px  !important;

}

  

#item_sold:focus {

border: 1px  solid  #000  !important;

}

  

.invoice-sub-header-form {

margin-top: 30px;

}

  

.item-details {

margin-top: -25px  !important;

width: 185.7px  !important;

}

  

.item-details-data {

margin-top: -15px  !important;

}

  

.item-header {

padding: 15px;

}
```

---


In the `<body></body>` tag for our html we have we first of all create a container for all elements to give the layout a closely packed look.

The container  is created using this syntax

`<div   class="container invoice-body"></div>`

The class attribute `invoice-body` is responsible for setting the following styles in our CSS file 

```
.invoice-body {

margin-top: 100px;

margin-bottom: 100px;

border: 1px  solid  #000;

padding: 50px;

background: #fff;

color: #757575;

}
```

To create the header/address section we create a new row with the following tag

```
<div class="row"></div>
```

Inside our row the first column contains a paragraph holding the address of the invoice sender. This column was created using the following tag

```
<div  class="col l6 m6 s12 left-align">

<p>

Lorem Ipsum Company<br>

P.O. Box 18728, Non-Conformity Way<br>

Someplace Somewhere<br>

VAT No: 2617 348 2752<br>

</p>

</div>
```

----

The second column was created using the same template as above and it holds the address of the buyer. The code for this column is as thus

```
<div  class="col l6 m6 s12 right-align">

<p>

Billed To:<br>

Sam Donald Ripley<br>

Also Living Somewhere PO Box 29618<br>

VAT No: 295 3932 6119<br>

</p>

</div>
```
----

In both column the class attributes `left-align` and `right-align` will align the text contents of both columns to the left and right respectively.

We add additional information to the header section by creating two new columns just like the ones we created earlier

The code for this new columns

```
<div  class="col l6 m6 s12 left-align">

<p><strong>Invoice No:</strong> A - 21637</p>

</div>

<div  class="col l6 m6 s12 right-align">

<p><strong>Invoice Date:</strong> 07/06/2018</p>

</div>
```
----

Each newly added column contains a paragraph and some text content as can be seen in the code above

Here is a screenshot of the section after it has been created

![](https://image.ibb.co/cVokOT/header_invoice.png)

----

Next we add the form that will be responsible for inputting values that will be collated as item information for each sold product.

To create the form area we use the following code

```
<div  class="col l12 m12 s12 invoice-sub-header-input center-align grey lighten-3">

<div  class="container">

<div  class="row">

<form  action=""  class="col l12 m12 s12">

<div  class="row invoice-sub-header-form">

<div  class="input-field col l12 m12 s12">

<input  placeholder="Item"  id="item_sold"  type="text"  class="black-text invoice-input-form">

</div>

<div  class="input-field col l6 m6 s12">

<input  placeholder="Price"  id="price_sold"  type="number"  class="black-text invoice-input-form-half">

</div>

<div  class="input-field col l6 m6 s12">

<input  placeholder="Quantity"  id="quantity_sold"  type="number"  class="black-text invoice-input-form-half">

</div>

</div>

</form>

<div  class="submit-button center">

<a  class="waves-effect waves-light btn add-new-item"><i  class="ion-android-add left"></i>ADD ITEM</a>

</div>

</div>

</div>

</div>
```

The form section was opened using 

```
<div  class="col l12 m12 s12 invoice-sub-header-input center-align grey lighten-3"></div>
```

The class attribute `invoice-sub-header-input` will set the following CSS styles for our form section.

```
.invoice-sub-header-input {

margin-top: 50px;

}
```
A container and a new row that will hold the contents of our form was added using the following syntax.

```
<div  class="container">

<div  class="row">

</div>

</div>
```

Inside the new row we have a full-width form. This was achieved using the following HTML tag 

```
<form  action=""  class="col l12 m12 s12"></form>
```
The contents of our `<form></form>` tag are housed in a row created using  `<div></div>` with a class attribute of `invoice-sub-header-form` which sets the following CSS styles for this section

```
.invoice-input-form {

border: 1px  solid  #000  !important;

padding-left: 20px  !important;

}
```
The new row contains three text inputs and each was created using 

```
<div  class="input-field col l12 m12 s12">

<input type="text">

</div>
```
The only distinctions among these three text inputs lies in their `id` and `class` attributes

All three forms have the `id` attribute values `item_sold, price_sold and quantity_sold` respectively.

The first text input has a class attribute value `invoice-input-form`  while the remaining two have a class value attribute `invoice-input-form-half` 

The CSS styles being handled by `invoice-input-form` have been referred to above, as for `invoice-input-form-half` the following are the CSS styles it is responsible for

```
.invoice-input-form-half {

border: 1px  solid  #000  !important;

padding-left: 10px  !important;

margin-left: 3px  !important;

}
```

Here is a screenshot of the form section after it has been created

![](https://image.ibb.co/dJLoco/invoice_form.png)

Directly below our form we create another fullwidth column using the syntax

```
<div  class="col l12 m12 s12 invoice-sub-header-output center-align">

<div  class="container item-details-output">

</div>

</div>
```

There is only one notable class attribute linked to this section, this class attribute is the `invoice-sub-header-output` which is responsible for the following CSS styles

```
.invoice-sub-header-output {

margin-top: 50px;

}
```

The contents of this section will be added dynamically using Jquery, what we want is for the contents of this section to be updated every time the appropriate values are entered in the form section above it and the button with the text `ADD ITEM` is clicked.

The  following is the JavaScript code responsible for the contents of this section

```
$(document).ready(function() {

$('.add-new-item').click(function () {

var  itemName  =  $('#item_sold').val(); // Value for item sold

var  itemPrice  =  $('#price_sold').val(); // Price per each item sold

var  itemQuantity  =  $('#quantity_sold').val(); // Quantity sold per item

var  itemTotal  =  itemPrice  *  itemQuantity; // Total price of item sold

var  newItemRow  =  '<div class="container item-details-output"><div class="col l12 m12 s12"><h5 class="center-align grey lighten-1 item-header item-name"></h5></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Price per Item</p><p class="center-align grey lighten-2 item-details-data item-price"></p></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Quantity</p><p class="center-align grey lighten-2 item-details-data item-quantity"></p></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Total Sold</p><p class="center-align grey lighten-2 item-details-data item-total"></p></div></div>'; // Add new element

$('.invoice-sub-header-output').append([newItemRow]);

$('.item-name').text('Product: '  +  itemName);

$('.item-price').text('$'  +  itemPrice);

$('.item-quantity').text(itemQuantity);

$('.item-total').text('$'  +  itemTotal);

$('.item-name').removeClass('item-name');

$('.item-price').removeClass('item-price');

$('.item-quantity').removeClass('item-quantity');

$('.item-total').removeClass('item-total');

});

});
```

The opening function for these Jquery script `$(document).ready(function() {});` will prevent the script from  running until the HTML document has finished loading and the script is ready to be used.

Inside this opening function we have another function `$('.add-new-item').click(function () {});`. What this expression states is just that whenever the element with the class attribute `.add-new-item` is clicked.

The `click()` is nothing more than a Jquery event listener which notifies the script that the specified element has been clicked and then goes on to provide the set of statements to be executed in that instance.


When the element in question is clicked the following happens sequentially

- First, the script gets the value of current contents of the text inputs in the form we created earlier and stores each one in a variable. This is done using the following statements

```
var  itemName  =  $('#item_sold').val();

var  itemPrice  =  $('#price_sold').val();

var  itemQuantity  =  $('#quantity_sold').val();

var  itemTotal  =  itemPrice  *  itemQuantity;
```

Each variable highlighted above stores the value of an input value. However the last variable `itemTotal` doesn't do so directly, instead it stores the result of multiplying the values of the variables `itemPrice` and `itemQuantity`.

In the first three variables above, the `.val()` function gets and stores the value of any form element indicated in the parentheses before it.

We also have an additional variable in the script storing a different type of value. The value being stored here is the HTML template to be used by the script to output data collected in the form for each product to be included in the invoice.

```
var  newItemRow  =  '<div class="container item-details-output"><div class="col l12 m12 s12"><h5 class="center-align grey lighten-1 item-header item-name"></h5></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Price per Item</p><p class="center-align grey lighten-2 item-details-data item-price"></p></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Quantity</p><p class="center-align grey lighten-2 item-details-data item-quantity"></p></div><div class="col l4 m4 s12 item-details"><p class="center-align grey lighten-3">Total Sold</p><p class="center-align grey lighten-2 item-details-data item-total"></p></div></div>';
```

Every vital element in the template featured above  has a class attribute value that will be used to identify and manipulate it in the rest of the script.

After creating this template variable, the script is then instructed to append the value of the variable to the page contents.

This is achieved using the following syntax 

```
$('.invoice-sub-header-output').append([newItemRow]);
```
What the above statement translates to is that the contents of the variable `newItemRow`should be appended using the Jquery `append()` function inside the element with a class of `.invoice-sub-header-output`.

We then set the values for the contents of the template by adding the following

```
$('.item-name').text('Product: '  +  itemName);

$('.item-price').text('$'  +  itemPrice);

$('.item-quantity').text(itemQuantity);

$('.item-total').text('$'  +  itemTotal);
```

`.text()` is a jquery function that is usually used to set the contents of A HTML element.

In our created program 

`$('.item-name').text('Product: '  +  itemName);` will set the text content of the element with a class attribute `.item-name` to the value of the variable `itemName`.

`$('.item-price').text('$'  +  itemPrice);` will set the text content of the element with a class attribute `.item-price` to the value of the variable `itemPrice`.

`$('.item-quantity').text(itemQuantity);` will set the text content of the element with a class attribute `.item-quantity` to the value of the variable `itemQuantity`.

And finally,

`$('.item-total').text('$'  +  itemTotal);` will set the text content of the element with a class attribute `.item-total` to the value of the variable `itemTotal`.


Now whenever we enter a new set of values into the form area and click on the button `ADD LINK` the template added in our script will be appended and the new values entered in the form will be set as its text content as designated.

We have one final line of action, whenever the button is clicked you might notice that instead of the new values to be included in the newly appended template it actually updates all of the values of the templates appended before that to the new values. 

To prevent this from happening we then proceed to remove the classes responsible for setting the text contents in the script after each template has been appended. This is achieved using the Jquery `removeClass()` function.

The code below would help us get that done.

```
$('.item-name').removeClass('item-name');

$('.item-price').removeClass('item-price');

$('.item-quantity').removeClass('item-quantity');

$('.item-total').removeClass('item-total');
```
`removeClass()` is a Jquery function that is used to remove a previously set class attribute value from a HTML element.

What the code above does is that it simply picks the element with the specified class and after it does that it then removes any indicated class from the HTML element. 

That way any future append operation will not affect previous appends since the class attribute value responsible for that has been removed.

Below is a screenshot of the section we just created after some values have been added with the form

![](https://preview.ibb.co/mi1KHo/invoice_details.png)

#### Curriculum

1. [Simple Shopping Cart Using Vue.js and Materialize - 2](https://steemit.com/utopian-io/@gotgame/simple-shopping-cart-using-vue-js-and-materialize-2)

2. [Simple Shopping Cart using Vuejs and MaterializeCSS - 1](https://steemit.com/utopian-io/@gotgame/simple-shopping-cart-using-vue-js-and-materialize)

3. [Building a Landing Page with MaterializeCSS - 2](https://steemit.com/utopian-io/@gotgame/building-a-landing-page-with-materializecss-2)

4. [Building a Landing Page with MaterializeCSS - 1](https://steemit.com/utopian-io/@gotgame/building-a-landing-page-with-materializecss-1)

#### Proof Of Work Done

https://github.com/olatundeee/invoice-template
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,