Introduction to programming
More challenges
In this part of the series we are going to have a go at build one or two little standalone projects, which will give you some coding practice, introduce a couple of new concepts; we can hopefully and hopefully give you some fun at the same time.
A shopping list
The first example we'll look at is a simple little program that allows you to enter items into an input field and then submit them to add them to a list that appears below. The final working example can be seen at My shopping list — but no peeking at the code until you've tried it yourself!
The brief
- The interface should contain a form input field and two buttons — Submit item and Clear items.
- When an item is entered in the form input and Submit item is clicked, then item should be added to an unordered list and the form input should be cleared.
- When the Clear items button is pressed, the listed items should be deleted, and anything inside the form input should be cleared out.
New things in this challenge
We have already seen how you can alter the content of an HTML element by capturing the element in a variable using something like
var element = document.querySelector(".class");
and then setting the innerHTML
property of that variable to anything you like:
element.innerHTML = "Hello!";
Well, you can also create new HTML elements from nothing, using the document.createElement()
method and passing it an element name. For example:
var myNewElement = document.createElement('p');
You can then do many things with this element, but in this case we are going to look at adding the element to the document inside another element. For example:
var myExistingElement = document.querySelector(".myClass");
myNewElement.innerHTML = "My paragraph now has some content!";
myExistingElement.appendChild(myNewElement);
This would result in the following HTML now existing in the page:
<div class="myClass">
<!-- This div element was already in the HTML -->
<p>My paragraph now has some content!</p>
<!-- This p element was created by JavaScript -->
</div>
Let's do it
- Create a new copy of the template file to write this example into, into the usual way.
- As a first step, let's add some HTML inside our HTML area.
- Now we need to grab all of the items we want to do stuff to and store them in variables. We ought to grab the form input, both buttons, and the empty unordered list (
<ul>
) element: - Next, we need a function that will grab whatever value is inside the form input at the time it is run, and put it inside a list item (
<li>
element) inside the unordered list. This should happen when the Submit item button is clicked. Inside our function we need to:- Store the current value of the form input in a variable (remember we can access the value with
formElement.value
). - Create a new list item (
<li>
element) usingdocument.createElement()
, like we discussed above. - Set the value of the list item's
innerHTML
property to the form input value we captured in the above step. - Append the list item as a child of the unordered list using
appendChild()
, like we discussed above. - Set the value of the form input to equal an empty string ("") to empty it.
- Store the current value of the form input in a variable (remember we can access the value with
- The only other major bit of work is to create a function that deletes the existing list items and empties the form input element when the clear button is clicked. to do this, we need to create a function that
- sets the
innerHTML
of the unordered list to nothing ("") - sets the value of the form input to equal an empty string ("").
- sets the
<div class="form">
<label for="item">Add item to list: </label>
<input type="text" class="item" id="item">
<button class="submit">Submit item</button>
<button class="clear">Clear items</button>
</div>
<ul>
</ul>
var itemInput = document.querySelector(".item");
var clear = document.querySelector(".clear");
var submit = document.querySelector(".submit");
var list = document.querySelector("ul");
Note: Outside the function we need to attach an onclick
event handler to the Submit item button so it runs the function we just wrote when it is clicked.
Add this code to your JavaScript area:
function addItem() {
var currentItem = itemInput.value;
var listItem = document.createElement("li");
listItem.innerHTML = currentItem;
list.appendChild(listItem);
itemInput.value = "";
}
submit.onclick = addItem;
Enter the following into the JaavScript area, below your previous function.
clear.onclick = function() {
list.innerHTML = "";
itemInput.value = "";
}
You'll notice in my final code that I used an anonymous function for this second part, and just attached it directly to the onclick
handler. But you could do it a different way if you like.
A text search app
Our second example is slightly more complex, and highlights one of the main uses of JavaScript: processing text. In this demo we will create an app that will take a big chunk of text you feed into it and a search term, search through it, and then highlight where the search term appears in the chunk of text.
The brief
- The user interface should contain a big text area to enter the block of text to be searched through, a text input to enter the search term into, and two buttons, one to perform the search and one to clear the entries and start again.
- When the Search button is pressed and nothing has been entered into one or both of the text entry fields, the user should be told to enter some text and try again!
- When the Search button is pressed and text has been entered into both text entry fields:
- If the search term is matched in the main text block, it will be highlighted in a new version of the text, printed at the bottom of the display. A message will appear to tell the user this.
- If not, a message will be displayed telling the user that no results were found.
- When the Clear button is pressed, the text entry fields, the message and the results will all be cleared, resetting the application.
When looking at a brief like this, it helps to examine what is needed, and write out a list of all the items, so we are clear:
- A big text area
- A single line text input
- A Search button
- A Clear button
- A container element to display the result messages in
- A container element to display the actual search results with the highlighted search terms
Grabbing a piece of paper and sketching out a rouch mock of the thing you are about to build can also be tremendously helpful.
New things in this challenge
JavaScript contains many built in features for manipulating strings. We've already seen how you can concatenate strings together:
var myName = 'Chris';
var myAge = 35;
alert('My name is ' + myName + ' and I am ' + myAge + ' years old.');
Here we are concatenating some raw text strings and variable values together to make one big string. But we can go a lot further than this. Here we'll be using two new string manipulation functions.
The first one is called indexOf()
, and it finds an instance of one string inside another. For example:
var result = 'My name is Chris'.indexOf('Chris');
So here we are writing out a string, then invoking the indexOf()
function of the string, with an argument of "Chris"
. This causes the browser to search through the string, check whether "Chris" appears inside the string, and store the position that it appears in, in the result
variable. The result should be 11, because "Chris" starts (the letter "C" appears) at character 12 of the string (remember that computers start counting from 0, not 1).
Note: If the indexOf()
argument is not found in the string, it will return a result of -1. This is pretty useful, as we shall see later.
The second new function is called replace()
. This is a function that allows you to replace parts of a string with something else, and then return the updated string. For example:
var result = 'My name is Chris'.replace('Chris', 'Bob');
Here we are writing out a string, then invoking the replace()
function of the string. In this case it is taking two arguments, the string we want to find ("Chris") and the string we want to replace it with ("Bob"). The replacement is caried out, and the updated string is stored in the result
variable. The result should be "My name is Bob".
replace()
can also take an optional third argument containing a regular expression (a string matching pattern), which sets some rules about how the replacement should occur, for example if you want to ignore case sensitivity, or replace all instances of a string or just one. These are pretty complicated so I won't be covering these in detail; the only one I'll be covering is the "g" option, which causes the replace()
function to replace all instances of the replace string, not just the first one. So for example, try this:
var result1 = 'My name is Chris Chris Chris'.replace('Chris', 'Bob');
var result2 = 'My name is Chris Chris Chris'.replace('Chris', 'Bob', 'g');
result1
should be equal to "My name is Bob Chris Chris", while result2 should be "My name is Bob Bob Bob".
Let's do it
Ok, so let's get to it, and build this thing. Again start with a new copy of the template file. In the HTML area, add the following HTML:
<div class="form">
<div>
<label for="text">Enter your text to search: </label><textarea class="text" id="text" cols="80" rows="15"></textarea>
</div>
<div>
<label for="searchString">Enter text to search for: </label><input type="text" class="searchString" id="searchString">
</div>
<button class="submit">Search</button><button class="clear">Clear</button>
</div>
<p class="resultMessage"></p>
<p class="results"></p>
Now we'll go through the following steps, writing the JavaScript in the JavaScript pane:
- First we'll capture both buttons and the two paragraphs at the bottom of the HTML in variables:
- The next task is the biggest and most difficult part of the application. We now need to write a central function that carries out the main search and result reporting tasks. First, create an empty function:
- Inside this function, we'll grab the current text values inside the
textarea
element and the textinput
element and store them in variables. Add the following inside the function's curly braces: - Next, we'll use the
indexOf()
function we explored earlier to check whether thesearchString
is contained inside thetext
, and store the result in a variable. Add this line below: - Next, add the following
if...else
code> structure, which gives the user a message if thesearchString
,text
or both are empty, to tell them to fill in the text boxes. If this is not the case, we will do something else, to be covered below. - Now we will look at what needs to go inside the else part of the code. First we need to nest another
if ... else
structure inside this block. We need to do something magical if theindexOf()
test says that thesearchString
is found inside the text (which we'll cover in the next step). If it isn't, then we want to give the user a message to tell them that the search term has not been found in the text block, and clear the contents of theresults
paragraph (in case anything was set there in previous searches.) Put the next block of code inside the previouselse { ... }
block. - Finally for this function, add the following code into the inner
if(confirmResult !== -1) { ... }
block. IfconfirmResult
doesn't have a value of -1, it means that thesearchString
has been found in thetext
block, so we will usetext.replace()
to find where, and highlight all instances. This is done by replacing all instances of the term with the same term wrapped in an HTML<strong>
element. - We also need a function that will clear everything out, effectively resetting the whole app. You need to empty both form fields (
input
andtextarea
), and empty both paragraphs (resultsMessage
andresults
.) Add the following below the first function: - The last step is to add
onclick
handlers to the Search and Clear buttons so that they run the two functions we just wrote. This is the easy bit! Add the following to the bottom of the JavaScript area:
var searchButton = document.querySelector(".submit");
var clearButton = document.querySelector(".clear");
var resultMessage = document.querySelector(".resultMessage");
var results = document.querySelector(".results");
function runSearch() {
}
var text = document.querySelector(".text").value;
var searchString = document.querySelector(".searchString").value;
var confirmResult = text.indexOf(searchString);
if(text === "" || searchString === "") {
resultMessage.innerHTML = "You need to enter a search term and block of text to search!";
} else {
}
if(confirmResult !== -1) {
} else {
resultMessage.innerHTML = "Your search term has not been found in the text";
results.innerHTML = "";
}
var newText = text.replace(searchString, "<strong>" + searchString + "</strong>", "g");
results.innerHTML = newText;
resultMessage.innerHTML = "Search term highlighted in text";
function clearFields() {
document.getElementById("text").value = "";
document.getElementById("searchString").value = "";
resultMessage.innerHTML = "";
results.innerHTML = "";
}
searchButton.onclick = runSearch;
clearButton.onclick = clearFields;
This work is licensed under a Creative Commons Attribution 4.0 International License. Share it, make it better, use it for good.