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.