The Code for ABRACADABRA
//get values from user input
//starts or controller function
function getValues(){
let abraValue = document.getElementById("startValue").value;
let cadabraValue = document.getElementById("endValue").value;
//validate input to make sure that input is numbers
//parse input for integers
abraValue = parseInt(abraValue);
cadabraValue = parseInt(cadabraValue);
if(Number.isInteger(abraValue) && Number.isInteger(cadabraValue)) {
//call abracadabra
let acArray = abraCadabraC(abraValue,cadabraValue);
//call displayData and write the values to the screen
displayData(acArray);
} else {
alert("You must enter integers")
}
}
//Possible functions one can use to "abracadabra" (original abraCadabra, B, or C)
function abraCadabra(abraValue,cadabraValue) {
let returnArray = [];
//loop from 1 to 100
for (let index = 1; index <= 100; index++) {
//need to check current integer in three steps
//(1) Check to see if divisible by both (3 and 5); if so, push Abracadabra.
if (index % abraValue == 0 && index % cadabraValue == 0) {
returnArray.push("Abracadabra");
}
//(2) Check to see if divisible by abra value (3); if so, push Abra.
else if (index % abraValue == 0) {
returnArray.push("Abra");
}
//(3) Check to see if divisible by cadabra value (5); if so, push Cadabra.
else if (index % cadabraValue == 0) {
returnArray.push("cadabra");
}
//if divisible by none, push the number into the array
else {
returnArray.push(index);
}
}
return returnArray;
}
function abraCadabraB(abraValue, cadabraValue){
let returnArray = [];
let Abra = false;
let Cadabra = false;
for (let i = 1; i < 100; i++) {
Abra = i % abraValue == 0;
Cadabra = i % cadabraValue == 0;
switch(true)
{
case Abra && Cadabra:{
returnArray.push('Abracadabra');
break;
}
case Abra:{
returnArray.push('Abra');
break;
}
case Cadabra:{
returnArray.push('Cadabra');
break;
}
default:{
returnArray.push(i);
break;
}
}
}
return returnArray;
}
function abraCadabraC(abraValue, cadabraValue){
let returnArray = [];
for (let i = 1; i <= 100; i++) {
let value = ((i % abraValue == 0 ? 'Abra' : '') + (i % cadabraValue == 0 ? 'cadabra' : '') || i );
returnArray.push(value);
}
return returnArray;
}
//loop over the array and create a tablerow for each item
function displayData(acArray) {
//get the table body element from the page
let tableBody = document.getElementById("results");
//get the template itself
let templateRow = document.getElementById("fbTemplate");
//clear the table
tableBody.innerHTML = "";
for (let index = 0; index < acArray.length; index+= 5) {
let tableRow = document.importNode(templateRow.content, true);
//grab the td to put into array
let rowCols = tableRow.querySelectorAll("td");
rowCols[0].classList.add(acArray[index]);
rowCols[0].textContent = acArray[index];
rowCols[1].classList.add(acArray[index+1]);
rowCols[1].textContent = acArray[index+1];
rowCols[2].classList.add(acArray[index+2]);
rowCols[2].textContent = acArray[index+2];
rowCols[3].classList.add(acArray[index+3]);
rowCols[3].textContent = acArray[index+3];
rowCols[4].classList.add(acArray[index+4]);
rowCols[4].textContent = acArray[index+4];
tableBody.appendChild(tableRow);
}
//add all the rows to the table
}
//inline script from app.html
The code shown contains all of the Javascript used in this project. Most of the Javascript is contained inside of an external script, site.js. One line of Javascript runs inline inside of app.html. A few key pieces of it are explained below.
getValues
getValues is a function that is triggered when the "Start the Magic!" button is clicked on the app webpage. (See the bottom of the Javascript.)
It first declares two variables, abraValue and cadabraValue. It pulls both of those from the two html number inputs which can be changed. They are set initially to 3 and 5.
The function then parses abraValue and cadabraValue to change the strings from the two inputs into integers.
An if/else statement is created and checks to see if both abraValue and cadabraValue are integers. If so, the variable acArray, which is set equal to one of our three possible Abracadabra functions, is declared. abraValue and cadabraValue are passed in as parameters. If both of the inputs are not integers, an alert is shown.
The Abracadabra Functions
I will not attempt to explain all three of these in great detail, but I will explain at a high level what their intent is. (I will explain the last function as it is fairly interesting.)
All three of these functions declare an empty array, returnArray.
All three of these functions use a for loop to go from 1 to 100. As it loops, the function will change out numbers with "Abra," "Cadabra," or "Abracadabra." Or it will keep the number if certain parameters are not met. Then, returnArray is returned at the end. It will be used when its function acArray is passed into another function, displayData.
abraCadabraC:
This function uses abraValue and cadabraValue as parameters. It declares a variable called returnArray which is set equal to an empty array.
A for loop is created that loops from 1 to 100, but the statement that it uses is quite a bit different from the other functions.
The statement it uses is called a conditional (ternary) operator. Ternary means composed of three parts, which is how this statement is composed. In a ternary operator, you have three things that show up: a condition followed by a question mark(?), an expression followed by a colon(:) to execute if the condition is truthy, and an expression following that to execute if the condition is falsy.
In our ternary operator, we have two conditions with each condition having a truthy and falsy expression able to be executed. Finally at the end, we have an OR (||) operator that will be triggered if none of the conditions are true.
So, for our first condition, if i (index) divided by our abraValue returns a remainder that is equal to 0, then the string "Abra" is added to the variable value. If not, an empty string is added. (basically nothing)
For our second condition, if i (index) divided by our cadabraValue returns a remainder that is equal to 0, then the string "Cadabra" is added to the variable value. If not, an empty string is added. (basically nothing)
Realize that if both conditions are true, "Abra" and "cadabra" will both be added as strings to value which will result in a string containing "Abracadabra." And if neither are true, then our OR (||) operator will be triggered and the i (index) will be returned.
After the loop finishes, then the variable returnArray is returned.
displayData
Now that we have all the strings and indexes we need within our array returnArray which is contained in our function abraCadabraC, remember that the function acArray has been set equal to abraCadabraC back up in our getValues function. Basically, that just means we have access to our array within displayData by using acArray as the parameter. (as seen below)
function displayData(acArray)
Two variables, tableBody and templateRow, are declared and set equal to html elements within app.html. We will use these variables to alter these html elements.
Then we use the variable tableBody and the .innerHTML property to set our HTML table equal to an empty string. This is important so that multiple tables do not appear if we want to use the app more than once.
One last loop...
In our array, we have a total of 100 indices, 0-99. So our loop will continue until it reaches an index greater than our array length. We also want 20 rows with five values on each row, which equals to our total array length of 100 (first index (0) + 99 indices). It is for this reason that each time the loop loops, that we add (+=) 5 to our index. This is so we get five new values on each row rather than just the same first five indices.
Now that the loop has five values, it's going to insert them into our html. But first, we need html in which to insert them. The variable tableRow is declared and set equal to our html template we pulled into our tableRow variable.
.importNode is a property that allows us to take a fragment of html from another document. Having true at the end is important. It allows us to also grab the child elements of the HTML element we have selected.
The variable rowCols is declared and set equal to the td element within our tableRow variable. This means that when we use rowCols and pass in an index as a parameter, (for example, rowCols[0]) we can access with precision each individual td element within our HTML template.
Let's break down one these pairs of statements. Look at line 112-113. rowCols[0] grabs the first td element. .classList.add(acArray[index]) allows us to add a class to our td element from our acArray at whatever the current index is. Since we have named our classes (in site.css) the same name as our strings: "Abra," "Cadabra," and "Abracadabra," we can use these array strings as class names. Okay, so we targeted the first td element, and we inserted a class with one of the same names as one of the strings in our array.
Check out line 113. rowCols[0] again grabs the first td element, but this time, using .textContent, we will place text into the td element. This text content comes from our array acArray, at whichever index we are currently using.
Finally, tableBody.appendChild(tableRow) (line 127) takes our tableRow we have created with our new td elements, and it places it at the end of tableBody.