JavaScript Text Scanner Project

The purpose of this project is to illustrate how we can use various JavaScript string manipulation techniques to create a real application.

We are going to create a JavaScript application that will scan text, extract all the numbers from the text and add up the total, and finally display the average of all the numbers. I have embedded the code at the bottom of the page so that you can see how it works and looks. Go ahead and try it out!

In order to accomplish this there are a number of things that we have to do so lets jump straight into it.

Creating the HTML Structure

We need a few HTML elements for our application. We need a text area so that we can type in some custom text for testing. The business logic of this application will be able to take in any text in the form of a string, so this could also be used on text from other sources. We also need a button that will initiate the job, and we need a label where we can display the average.

Let us start by creating the HTML code for our text area.

1. Adding a Text Area

<textarea id="customTextInput">
This is going to be some default text so that you don't have to 
type in a lot of text to try it. Lets purchase $100 worth of food, 
then we will spend 1,000 on a bike, and also lets get a burrito for 5.40 
</textarea>

Creating the text area is quite easy. We have also added some dummy text with a few numbers in it. I have added the numbers in various ways because we have to support multiple cases. Numbers can be written differently by many users, and you have to be able to support as many as possible.

2. Adding Button

The next thing we need is a button that will initiate the whole process for us. Lets add that now.

<button id="processInputButton" type="button">Start</button>

3. Creating the Label

The last thing to add is the label where we will place the average sum of all the numbers we can find on the page.

<label id="total">The average will be placed here </label>

We now have all the HTML elements that we need for this project.

Creating CSS Styling

The next thing we need to do is to add a little bit of styling to the HTML elements.

I am going to add this CSS inside style tags because I am going to embed it on this WordPress page and I don’t want to create a new file to import. If you want to replicate the project you can of course create a new CSS file and import that in the header tag. Also, all the styling will be inside a single <style> tag when I embed it on the page, but below they appear inside their own because I break it up by HTML element.

1. Add styling to the Text Area

For the text area we are going to change the color of the background as well as making sure the starting height is 200 px.

<style>
    #customTextInput{
        background-color: #d4d4d4;
        height: 200px;
    }
</style>

2. Adding Styling to the Button

For the button we just want to add a different background color. The default background color on this WP theme is white so it is a bit difficult to see that it is actually a button.

<style>
    #processInputButton{
        background-color: #41bcfa;
    }
</style>

3. Adding Styling to the Label

For the label we want to make sure that there is enough room around it by adding some margin. We also want to make it so that it is displayed on its own line, and not as an inline element.

<style>
    #total{
        display: block;
        margin:20px 0px;
    }
</style>

Creating Logic with JavaScript

We now have the HTML elements that we need, and we have added styling to them. Now it is time to write our core logic in JavaScript.

For this project we will support numbers that are typed as a number (i.e. 1000, 10.5), with US style thousand separator (i.e. 1,000), and with a dollar sign in front of the number ($1000). There are other cases that you might want to support. A great exercise is to add some more support.

1. Function to get the Text

We need a function that can retrieve our test text from the text area, so lets start by creating that. Here we simply need to get the text from the text area and return it as a string variable.

function getText(idOfTextArea){
    return document.getElementById(idOfTextArea).value + '';
}

By passing in the id of the text area like we do above we make the method more flexible so that it can be reused for other purposes. This is a lot better than hard coding the id of the specific element that you want to get.

2. Process the text

Now that we have a function we can use to retrieve the text from the text area we need some logic for parsing this text.

Lets start by adding a function that will turn the text into an array, where each index contains a word from the text. We can then more easily loop over the words to have a look at them.

Text to array

We are going to create a function that takes some string and returns it as an array. Again, we are splitting our code into independant functions so that it will be more reusable.

function textToArray(text){
    return text.split(" ").trim();
}

Process Word

After using the function above we will have an array full of words. As we loop over the words we are going to have to check if the word is a number or not. Not all the numbers will be formatted as a normal number (i.e. 1000) so we have to do some processing on them as well. Lets write a function that takes in a word and then checks if it is a number or not.

A) Remove commas

The first thing we need is a way to get rid of the commas that might be in the word. We are going to use the isNaN(..) function to check if it is a number or not, but this does not work with numbers that are formatted as “1,000”. you can get an in dept guide on how to remove commas here.

function removeComma(word){
    return word.replace(/,/g, "");
}
B) Remove dollar sign

Next we need a function that can get rid of the dollar symbol if it is attached at the front of the word. i.e. “$100” should be turned into “100”.

function removeDollarSign(word){
    if(word.charAt(0) == "$"){
        return word.replace("$", "");
    }
}

An exercise you can do is to make the two methods above more generic. For example, the remove dollar sign could take in a symbol that you would like to remove if it is exists at a given index. This would be particularly important if you want to support other symbols.

C) Check if word is a number

One of the last things we need to do before we can start piecing all these functions together is to create a function that can determine if a string is a number or not. We are going to use the isNaN() function to determine if a string is a number or not.

function wordIsANumber(word){
    return !isNaN(word);
}

That is it, now lets put all the functions together into one function that we can use to determine if a word is a number or not.

Piecing our logic together

function processWord(word){
    var withoutComma = removeComma(word); // Will remove commas if there are any
    var withoutDollarSign = removeDollarSign(withoutComma); // Will remove dollar sign
    return withoutDollarSign;
}

You can make the code above a lot more general too. For example, if you have a function that will remove any character that it is given at a given index, then you can have an array of symbols you want to remove and simply loop over it. A great exercise if you want some practice is to make this more generic.

Once we have our processed word we can pass it to the wordIsANumber() function to get back true or false.

3. Putting all our Code Together

We are now ready to put all our code together to make it usable. Here we will also create the on click even for our button so that we will initiate all this code when it is clicked.

var button = document.getElementById("processInputButton"); 

button.addEventListener("click", function(){
    var content = getText("customTextInput");
    var words =  textToArray(content);
    var average = getAverage(words);
    document.getElementById("total").innerHTML = average;
});

function getAverage(array){
    var total = 0;
    var count = 0;
  
    for(var i = 0; i < array.length; i++){
        var processedWord = processWord(array[i]);
        if(wordIsANumber(processedWord)){
            console.log(processedWord);
            total += parseFloat(processedWord);
            count++;
        }
    }

    return total / count;
}

function getText(idOfTextArea){ 
    return document.getElementById(idOfTextArea).value + '';
}

function textToArray(text){
    text = text + '';
    return text.split(' ');
}

function processWord(word){
    var withoutComma = removeComma(word); // Will remove commas if there are any
    var withoutDollarSign = removeDollarSign(withoutComma); // Will remove dollar sign
    return withoutDollarSign;
}

function removeComma(word){
    return word.replace(/,/g, "");
}

function removeDollarSign(word){
    return word.replace("$", "");
}

function wordIsANumber(word){
    return !isNaN(word);
}

Working Application

Potential Improvements

If you want something that you can do in order to practice then here is a little improvement. If the number has a period at the end of it then this will not work. We need to strip the period off the end for it to be recognized as a number.

For example, if you put a period at the end of "5.4" then it will not be picked up as a number.

You can also make it so that the average is rounded to only two decimal places.

Your task is to implement this improvements.

Conclusion

I hope you found this project tutorial helpful and that you learnt something.

Please visit the Projects page and have a look at some more projects.

Last Updated: by Ole Larsen