The Code
const getValues = (event) => {
event.preventDefault();
const input = document.getElementById('userInput').value;
const palindromeResult = checkForPalindrome(input);
displayResults(palindromeResult);
}
const reverseText = text => {
let reversedText = '';
for (let i = text.length - 1; i >= 0; i--) {
reversedText += text[i];
}
return reversedText;
}
const cleanText = input => {
const regex = /\W/g;
const cleanInput = input.replace(regex, "");
return cleanInput;
}
const checkForPalindrome = (text) => {
const filteredText = cleanText(text);
const reversedText = reverseText(filteredText);
const results = {
isPalindrome: filteredText.toLowerCase() === reversedText.toLowerCase(),
reversedText: reverseText(text),
errorMessage: ''
};
if (text && !filteredText) {
results.errorMessage = "Please enter an alphanumeric character in the input.";
}
if (!text && !filteredText) {
results.errorMessage = "Please enter some text.";
}
return results;
}
const displayResults = (resultObj) => {
const alertBox = document.getElementById('alert');
const displayMessage = document.getElementById('msg');
const displayHeading = document.querySelector('.alert-heading');
alertBox.classList.remove('invisible', 'alert-danger', 'alert-success');
displayMessage.innerHTML = `Your phrase reversed is: ${resultObj.reversedText}.`
if (resultObj.isPalindrome && !resultObj.errorMessage) {
alertBox.classList.add('alert-success');
displayHeading.innerText = `Nice! You entered a palindrome`;
} else if (resultObj.isPalindrome && resultObj.errorMessage) {
alertBox.classList.add('alert-danger');
displayHeading.innerText = resultObj.errorMessage;
displayMessage.innerHTML = '';
} else {
alertBox.classList.add('alert-danger');
displayHeading.innerText = 'Oh no! Your input is not a palindrome.'
}
}
Abstract
On a high level, I set out to do the following:
- Get the user input
- Transform that input to remove spaces, special characters and ignore uppercase
- Reverse the cleaned up input
- Compare the cleaned versions of the original and reversed text
- Based on the result, display an appropriately styled response
- If the user doesn't enter any input or enters bad input, display a helpful prompt
How I got the values
My entry function for the app is getValues
(line 1). This is triggered by a form submit. A form
submission event causes a page to refresh. To avoid the page refresh, I have
event.preventDefault()
. I used getElementById
to interact with the DOM element
with the ID userInput
. In this function, I stored the return value of
checkForPalindrome(input)
to a variable palindromeResult
and passed that as an
argument to the displayResults
function.
How I checked for a Palindrome
In my function checkForPalindrome
(line 22), I used a helper function to clean the text by
using Regex. I then reversed the text by calling another function reverseText
which
decrimentally loops through the text character by character, adds each character to an initially empty
string and finally returns the reversed string. I initialize the results
object (line 26) which
contains three important attributes that will help me outside this function:
-
isPalindrome
that stores the boolean result of comparing the lowercased input and lowercased reversed string. reversedText
that I later needed to display for the user.errorMessage
that I later needed for helpful error handling.
Next I checked for two different errors and assigned a corresponding string to the
errorMessage
. If there's any string length in text
but not in
filteredText
, we can conclude that the text
only consists of spaces or symbols
because we only cleared those out in the cleanText
function. For this condition, I ask the user
to enter an alphanumeric character. I then checked for another condition where both text
and
filteredText
don't have any string length. In this condition, I nudged the user to enter some
text.
How I displayed the results
The final piece of the puzzle is plugging the transformed data back into the DOM or the UI. For this app,
that function is displayResults
(line 43).
I first removed all the existing classes that were contributing to styling the alertBox
. This
way, I was working with a blank slate visually so any CSS class I added here onwards, wouldn't clash with
existing classes.
Now logically, I had 3 cases to consider:
-
The text is a palindrome and is neither an empty string nor made up only of non-alphanumeric characters.
Depicted by
(resultObj.isPalindrome && !resultObj.errorMessage)
-
The text is a false palindrome in that, the reversed input matched the input but the input was either
empty string, whitespaces or made up only of special characters. Depicted by
(resultObj.isPalindrome && resultObj.errorMessage)
-
Finally, any other case which means, the input was valid but it's just not a palindrome. Depicted by
else
scenario.
In the first case, I added the success styling to the alertbox and manipulated the heading text to display success.
In the second case, I added the error styling to the alertbox and displayed the error message we stored in
result
object's errorMessage
property.
In the final condition, where the input is valid but not a palindrome, I added the error styling and the result text.