Practical Front End Development Part 3 - JS
Published: 2020-08-15 22:38:31

# JavaScript
.
we have style our web application, but yet to implement the main functionalities, which is to calculate GPA when a user input records.
.
now lets head to `main.js` in our js folder
.
## Table Of Content
1. [Step 1](#step1)
2. [Step 2](#step2)
3. [Step 3](#step3)
4. [Step 4](#step4)
.

## Step 1: <a name='step1'></a>
inside `main.js` we need three javascript function
* to add new row `addNewRow()`
* to calculate the gpa `addUpCreditsGpa()`
* to convert the letters to equivalent point `gradeToPoints()`
.
```js
function addNewRow(){

}

function addUpCreditsGpa(){

}

function gradeToPoints(){

}
```
.
# Step 2: <a name='step2'></a>
Inside the first function that is the function that is been invoked when when the user clicked on the add button from our `index.html` file, we populate it with the following
```js
    const tableBody = document.getElementById("tableBody");
    const tr = document.createElement("tr");

    const td = document.createElement("td");
    const td1 = document.createElement("td");
    const td2 = document.createElement("td");
    const input = document.createElement("input");
    const select1 = document.createElement("select");
    const select2 = document.createElement("select");

    const option11 = document.createElement("option");
    const option12 = document.createElement("option");
    const option13 = document.createElement("option");
    const option14 = document.createElement("option");
    const option15 = document.createElement("option");
    const option16 = document.createElement("option");
    const option21 = document.createElement("option");
    const option22 = document.createElement("option");
    const option23 = document.createElement("option");
    const option24 = document.createElement("option");
    const option25 = document.createElement("option");
    const option26 = document.createElement("option");

    input.type = "text";
    input.name = "courseCode";
    input.classList.add("code-input");

    select1.name = "creditUnit";
    select2.name = "grade";
    select1.classList.add("select");
    select2.classList.add("select");
    select1.setAttribute("onchange", "addUpCreditsGpa()");
    select2.setAttribute("onchange", "addUpCreditsGpa()");
    option11.innerHTML = "6";
    option12.innerHTML = "5";
    option13.innerHTML = "4";
    option14.innerHTML = "3";
    option15.innerHTML = "2";
    option16.innerHTML = "1";
    option21.innerHTML = "A";
    option22.innerHTML = "B";
    option23.innerHTML = "C";
    option24.innerHTML = "D";
    option25.innerHTML = "E";
    option26.innerHTML = "F";

    select1.appendChild(option11);
    select1.appendChild(option12);
    select1.appendChild(option13);
    select1.appendChild(option14);
    select1.appendChild(option15);
    select1.appendChild(option16);
    select2.appendChild(option21);
    select2.appendChild(option22);
    select2.appendChild(option23);
    select2.appendChild(option24);
    select2.appendChild(option25);
    select2.appendChild(option26);

    td.appendChild(input);
    td1.appendChild(select1);
    td2.appendChild(select2);
    tr.appendChild(td);
    tr.appendChild(td1);
    tr.appendChild(td2);

    tableBody.appendChild(tr);

```
### Explaining the code
when creating a variable in javascript you make use of 
* `let` or `const`: e.g `const table`
* `document.createElement()` is use to create new HTML element via `js` e.g `document.createElement("option")` equivalent to `<option></option>` in javascript
* in a normal input tag `<input>` attributes like type and name, can be found, class attribute if you want to style it. e.g `<input type='text' name='my-input'>`. therefore from our sourcecode above `input.type = 'text'` and ` input.name='courseCode'` and  `input.classList.add('code-input')` is equivalent to `<input type='text' name='courseCode' class='code-input'>` in a normal HTML file
* Some elements do have event listeners, eventlisteners are things that happen when a user click, when a page load, when a file is submitted etc. an example is `<from onSubmit='clearField()'></form>` therefore `select1.setAttribute("onchange", "addUpCreditsGpa()");` is equivalent to `<select onchange='addUpCreditsGpa'>...</select>` in HTML file
* The .innerHTML is use to add content to an HTML tag e.g `option11.innerHTML = "6";` in javascript is equivalent to `<option>6</option>` in HTML
* The appendchild is use to insert another HTMl element into another, for those that can be child element to one another e.g `select1.appendChild(option11);` in javascript is equivalent to `<select><option></option></select>` in HTML, here `<option></option>` is appended to `<select></select>`
.

## Step 3: <a name='step3'></a>
Inside the second function this is where the calculation takes place, we add this codes to it
```js
    const creditUnit = document.querySelectorAll('[name = creditUnit]');
    const grade = document.querySelectorAll('[name = grade]');
    let totalUnit = document.querySelector("[name = totalUnit]").value = "";
    let gpa = document.querySelector("[name = gpa]").value = "";
    let option1 = "";
    let option2 = "";
    let a  = [];
    for (let i = 0; i < creditUnit.length; ++i) {
        option1 = creditUnit[i].options[creditUnit[i].selectedIndex].text;
        let totalUnit = document.querySelector("[name = totalUnit]").value;
        totalUnit = Number(totalUnit) + Number(option1);
        a.push(totalUnit);
    }
    let asum = a.reduce((partial_sum, a) => partial_sum + a,0); 

    let b = [];
    for (let i = 0; i < grade.length; ++i) {
        option2 = grade[i].options[grade[i].selectedIndex].text;
        let gpa = document.querySelector("[name = gpa]").value;
        let letterPoint = gradeToPoints(option2);
        let totalPoint = letterPoint;
        b.push(totalPoint);
    }
    let addAB = a.reduce(function(r,a,i){return r+a*b[i]},0);
    

    let gpaScore = parseFloat(addAB / asum).toFixed(2);
    document.querySelector("[name = totalUnit]").value = asum;
    document.querySelector("[name = gpa]").value = gpaScore;
```
### Explaining the code
* The `document.querySelectorAll()` is use to select html elements/tags, id's, class, anything that can be traversed by the DOM e.g `document.querySelectorAll('[name = creditUnit]')` will select all element with attribute name as 'creditsUnit' when you have a `.value = "";` method added to it, it means an empty value is been assigned here.
* The first for loop will loop through the all the creditunit put every thing in an array and sum up all the unit.
* The second for loop will loop through the grade, convert them to the equivalent point, store everything in an array and sum up all the values
* The `parseFloat(addAB / asum).toFixed(2);` will calculate the GPA and correct it to 2 significant figures
* The `document.querySelector("[name = totalUnit]").value = asum;` will search for an HTML element in index.html with attribute `name='totalUnit'` then assign the `asum` which is the sum of the totalunit and 
 `document.querySelector("[name = gpa]").value = gpaScore;` will search for an HTML element in index.html with attribute `name='gpa'` then assign the `gpaScore` which is the quotient of `addAB / asum` where `addAB` is total of value of grade to points and `asum` is the total credit unit.
.

## Step 4: <a name='step4'></a>
inside the last function you paste this
```js
    if ("A" == grade) {
        return 5.0;
    }
    else if ("B" == grade) {
        return 4.0;
    }
    else if ("C" == grade) {
        return 3.0;
    }
    else if ("D" == grade) {
        return 2.0;
    }
    else if ("E" == grade) {
        return 1.0;
    }
    else if ("F" == grade) {
        return 0.0;
    }
    else {
        //XXX! Should we throw an exception here?
        return Invalid;
```
Save your file and open index.html in your browser to see how it now work, as you change the values, the gpa and total credit unit are been updated
you can view the demo application here [here](https://mygpa.netlify.com)  
.

Github repo
{% github https://github.com/mdjibril/spya-dev-crash-course %}
Happy Coding