GitHub Octocat
found a bug/improvement?
Saltar al contenido principal
12 min web development 14/09/2021

Medium JavaScript Project: Calculate DNI Letter and Deploy to GitHub Pages

Learn how to create a pure JavaScript project to calculate the DNI letter and deploy it to GitHub Pages for free.

Hello world! My name is Francisco, fcoterroba on the Internet and today I’m bringing you a post related to front-end. We’re going to do a very simple project (but which increases in difficulty due to the deploy topic) written in pure JavaScript where, given a DNI number, we’ll return the corresponding letter.

No matter how simple it may seem, in the IT sector, although studies and experience are valued, having a portfolio with projects, more or less simple, also counts. And that’s why I’ll explain this very simple project but which, with a bit of imagination, can become something very cool and catch the attention of IT recruiters.

Before starting the project, you should know a bit about JavaScript as well as how servers work, what deploying is, the pros of deploying using JavaScript, etc. On the internet you can find a lot of information about this but you can start by reviewing the posts I have written under the JavaScript category.

For basic JavaScript projects (without Node or dependencies) we won’t need any type of server. In fact, we won’t need more than a browser and a code editor like VSCodium or Sublime Text, among others.

Before we begin, although I’ll explain what it is later, I recommend you visit a post I uploaded more than a month ago, where I explain many of the most used computer terms in our daily lives. Since, in this post, you’ll see words that probably won’t sound familiar to you. 🤯 You can read the post here.

I also want to remind you that a few months ago I uploaded a video to my YouTube channel, very interesting, focused on home automation. Specifically, we connected, configured, and installed a smart light bulb 💡 with which you can change its color, turn it off, turn it on, and much more simply by using your mobile phone and/or voice assistants like Google, Alexa, etc. 👇🏻

Now let’s begin 👇

It may be normal that you don’t know what the DNI is since you might be reading me from the other side of the pond and have no idea what this is.

I’m not an expert in legality but the DNI is the identity document issued in Spain. Since March 2006 it has been electronic. It’s a polycarbonate card that incorporates a chip with digital information, which has dimensions identical to commonly used credit cards. It’s mandatory from the age of 14, although it can be requested from the minor’s registration in the Civil Registry. As of October 2015, more than 44 million electronic DNIs had been issued in Spain.

Basically, without Wikipedia, it’s a mandatory identity card used in Spain.

1️⃣ FIRST STEP 1️⃣

We must understand what algorithm the government uses to choose one letter or another based on your DNI numbers. It’s not really complicated but you have to keep it very present to do this project, obviously.

You simply have to divide your DNI number by the number 23 and the remainder you get from that operation is replaced by the corresponding letter:

| REMAINDER | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | | LETTER | T | R | W | A | G | M | Y | F | P | D | X | B |

| REMAINDER | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | LETTER | N | J | Z | S | Q | V | H | L | C | K | E |

2️⃣ SECOND STEP 2️⃣

The second thing we’re going to do is create our basic project structure.

You know, as always, a little folder with its corresponding name, an .html file, a .js file, and a .css file if we want to style it.

Project structure

3️⃣ THIRD STEP 3️⃣

Let’s start with the HTML structure which can be the simplest part of the project.

We create a basic HTML structure. In my case I used the Materialize library so the only “out of the ordinary” thing in this structure are the compiled CSS and JS of this library.

Let’s not forget, even though it doesn’t do anything for now, to add the styles and script at the beginning of the body.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calculate DNI Letter - @fcoterroba.com</title>
    
    <!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

    <link rel="stylesheet" href="style.css">
            
</head>
<body>
    <script src="script.js"></script>
    <nav>
        <div class="nav-wrapper">
          <a href="#" class="brand-logo center">DNI Letter</a>
        </div>
    </nav>
    <center>
        <div class="contenedor">
            <img class="center" id="dni" src="unnamed-removebg-preview.png"  alt="" srcset="">
            <div class="texto_imagen"><input type="number" name="" id="" minlength="8"></div>
            <div id="nombre_random"></div>
            <div id="apellido_random"></div>
            <div id="fecha_random"></div>
            <div id="img_random"></div>
            <h3 id="letra"></h3>
        </div>
    </center>
    <footer class="page-footer">
          <div class="container">
          © 2021 
          <a class="grey-text text-lighten-4 right" href="https://www.fcoterroba.com" target="_blank">fcoterroba</a>
          </div>
    </footer>
</body>
</html>

Project view

4️⃣ FOURTH STEP 4️⃣

Now let’s make it minimally visible, because this is very 2000s.

For the styles I mainly used two “families” since we were playing with the edited DNI image. One version for moderately large screens (computers, laptops, and tablets) and another version for mobile.

For this difference we use the @media property of CSS where we can pass a maximum size and apply rules according to this.

.contenedor{
    position: relative;
    display: inline-block;
    text-align: center;
}

.texto_imagen{
    position: absolute;
    top: 430px;
    left: 40px;
    font-size: large;
}

#nombre_random{
    position: absolute;
    top: 177px;
    left: 185px;
    font-size: large;
}

#apellido_random{
    position: absolute;
    top: 208px;
    left: 185px;
    font-size: large;
}

#fecha_random{
    position: absolute;
    top: 240px;
    left: 185px;
    font-size: large;
}

#img_random{
    position: absolute;
    top: 300px;
    left: 420px;
    font-size: large;
}

#dni{
    width: 600px;
}

#img_dni{
    width: 100px;
}

#letra{
    margin-top: -70px;
}

/*From here, the rules will only apply on mobile*/
@media only screen and (max-width : 480px) {
    #dni{
        width: 340px;
    }
    .texto_imagen{
        position: absolute;
        top: 235px;
        left: 22px;
        font-size: large;
    }
    #nombre_random{
        position: absolute;
        top: 97px;
        left: 105px;
        font-size: small;
    }
    #apellido_random{
        position: absolute;
        top: 114px;
        left: 105px;
        font-size: small;
    }
    #fecha_random{
        position: absolute;
        top: 132px;
        left: 105px;
        font-size: medium;
    }
    #img_random{
        position: absolute;
        top: 145px;
        left: 235px;
        font-size: large;
    }
    #img_dni{
        width: 80px;
    }
    #letra{
        margin-top: -50px;
    }   
}

Responsive view

5️⃣ FIFTH STEP 5️⃣

Let’s go with the logic, the script.

Although, first of all, we’re going to add the onchange property to the input since we’ll want to check this field every time it’s modified.

In the onkeyup property we’ll pass the name of the function we create later and the this.value property which refers, as the name says, to the value written in that tag.

<div class="texto_imagen"><input type="number" name="" id="" minlength="8" onkeyup="get_letter(this.value)"></div>

Now yes, let’s go to the script.

As Imagine Dragons say, first things first, the first thing we’re going to do is create the function in question. I’ve given it that name to be practical but you can really put whatever name you want.

The first thing we must do inside this function is check if the parameter we’ve passed to the function has more than 8 characters. For this, the .length function exists

In the incorrect case we won’t do anything (there comes your imagination. You can put an alert, prohibit it, put a message, etc.) but in the correct case we’ll create a key-value type variable where each character will correspond to the number in question. Something like this:

if (dni.length == 8) {
    const letters = {
        "T": 0,
        "R": 1,
        "W": 2,
        "A": 3,
        "G": 4,
        "M": 5,
        "Y": 6,
        "F": 7,
        "P": 8,
        "D": 9,
        "X": 10,
        "B": 11,
        "N": 12,
        "J": 13,
        "Z": 14,
        "S": 15,
        "Q": 16,
        "V": 17,
        "H": 18,
        "L": 19,
        "C": 20,
        "K": 21,
        "E": 22
    }; 
}

Then, we’re going to edit the DNI letter to show the corresponding value according to the number that came up. For that it will be necessary to create another function that returns the corresponding key according to the value we pass it. We can do this directly using the % operator which you already know gives us the remainder of a division

function getKeyByValue(object, value) {
    return Object.keys(object).find(key => 
            object[key] === value);
}

function get_letter(dni){
    if (dni.length == 8) {
        const letters = {
        "T": 0,
        "R": 1,
        "W": 2,
        "A": 3,
        "G": 4,
        "M": 5,
        "Y": 6,
        "F": 7,
        "P": 8,
        "D": 9,
        "X": 10,
        "B": 11,
        "N": 12,
        "J": 13,
        "Z": 14,
        "S": 15,
        "Q": 16,
        "V": 17,
        "H": 18,
        "L": 19,
        "C": 20,
        "K": 21,
        "E": 22
    };
      document.getElementById("letra").innerHTML = getKeyByValue(letters, (dni%23));
}

With this we would already have the project done BUT WHAT HAPPENS? That absolutely all junior developers fill their portfolios with the same ideas and practically copied.

Is having a large portfolio good? Of course. But should we also add a bit of originality, even if the purpose is the same? Absolutely yes.

That’s why, even if it’s silly, I’m going to upgrade this project by adding that, when the letter calculation process is complete, it directly paints information about famous people on the DNI. It’s silly but it catches attention both to make yourself known and to let IT recruiters know that you have imagination.

Basically opening your imagination you’d get something this cool:

Project demo

6️⃣ SIXTH STEP 6️⃣

Finally, we’re going to proceed to upload our project to the internet using a static server like GitHub Pages. There you can basically have, and summarizing a lot, your own website. And for projects like this, which don’t require databases and/or files to store at all, it’s great.

There are many alternatives to GH Pages but we’ll start with this one and gradually see the most famous ones.

The first thing we must do is create a repository and then upload our project files. We can do this using the terminal via git commands, via the GitHub Desktop desktop application, or from the GitHub web interface itself. For this test we’ll use the latter. It looks like this:

GitHub repository

Then, we go to settings and modify the main branch to gh-pages

GitHub Pages configuration

Finally, we go back to settings and a new section called pages will appear. That’s when we’ll have our website 🆙.

That’s all for today, guys! I hope you liked the reflection, how to play around a bit more with JavaScript, and the possibility we have with this language to have free hosting!

Finally, remember that if you like my content and want to contribute financially (since I don’t earn anything from Adsense), you can send me whatever amount you want via Paypal. Any amount is truly appreciated! 🙂

I also hope you have a great week and we’ll see each other here soon! Greetings and remember to follow me on social media like Twitter, Facebook, Instagram, GitHub and LinkedIn. 🤟🏻

Sources: Wikipedia, CadenaSer, DevCode.la