One of the fun little exercises that used to get thrown at us aspiring programmers, was a palindrome checker. In the console, we'd ask the user for a string, and then see if the string was a palindrome. Trite? Completely. But it brings me back. So screw it, we're doing that today.
What's a palindrome? Well, that's a string of text that's spelled the same backwards and forwards.
"Wow."
"Madam, I'm Adam."
"Able was I ere I saw Elba."
The rules are simple - all punctuations and spaces get removed for the purposes of evaluating the text. Anything below three valid characters doesn't count. Optionally, comparison may be case-insensitive.
I don't intend to stick to best practices for this. So my CSS naming choices might be dodgy and I'm not going to insist on good semantic HTML.
Let's get to it!
Here's some starting HTML. Have divs outlined in
red.
<!DOCTYPE html>
<html>
<head>
<title>Palindrome Checker</title>
<style>
body
{
font-size: 16px;
font-family: Verdana;
}
div { outline: 1px solid red; }
</style>
<script>
</script>
</head>
<body>
</body>
</html>
Add three divs.
<body>
<div id="pnlString">
</div>
<div id="pnlOptions">
</div>
<div id="pnlOutput">
</div>
</body>
This is the CSS. All of these divs are 800 pixels in width, centered via the
margin property with a bit of spacing at the top. The text is also aligned center. For
pnlOutput, we even have a
grey dotted border.
<style>
body
{
font-size: 16px;
font-family: Verdana;
}
div { outline: 1px solid red; }
#pnlString
{
width: 800px;
margin: 50px auto 0 auto;
text-align: center;
}
#pnlOutput
{
width: 800px;
height: auto;
margin: 10px auto 0 auto;
text-align: center;
border: 3px dotted rgb(100, 100, 100);
border-radius: 30px;
}
#pnlOptions
{
width: 800px;
margin: 0 auto 0 auto;
text-align: center;
}
</style>
In
pnlString, we want a label and checkbox. Have some examples of a palindrome in the placeholder attribute.
<div id="pnlString">
<input id="txtString" placeholder="Enter text, e.g, Kayak" />
</div>
More CSS. We want
txtString to look a certain way. Or rather, I do. It's all visual; let your taste define the look.
#pnlString
{
width: 800px;
margin: 50px auto 0 auto;
text-align: center;
}
#txtString
{
display: inline-block;
width: 20em;
height: 1.5em;
font-size: 2em;
font-face: "Courier New", monospace;
text-align: center;
border-radius: 10px;
border: 4px solid rgb(200, 200, 200);
}
#pnlOutput
{
width: 800px;
height: auto;
margin: 10px auto 0 auto;
text-align: center;
border: 3px dotted rgb(100, 100, 100);
border-radius: 30px;
}
So far, this is what we have.
Add two divs in
pnlOutput, ids
pnlResult and
pnlVerification. Have some default text in them.
<div id="pnlOutput">
<div id="pnlResult">(no text yet)</div>
<div id="pnlVerification">Enter some text above</div>
</div>
Some CSS for these divs. They both take up full width of their parent, have a defined height and have text aligned center. I'll keep the text color for
pnlResult a
deep grey.
#pnlOutput
{
width: 800px;
height: auto;
margin: 10px auto 0 auto;
text-align: center;
border: 3px dotted rgb(100, 100, 100);
border-radius: 30px;
}
#pnlResult
{
width: 100%;
height: 1.5em;
font-size: 2.5em;
font-face: Georgia;
text-align: center;
color: rgb(100, 100, 100);
}
#pnlVerification
{
width: 100%;
height: 1.5em;
text-align: center;
}
#pnlOptions
{
width: 800px;
margin: 0 auto 0 auto;
text-align: center;
}
Thus, we have display text for statuses.
Add a checkbox and label. The checkbox should have an id.
<div id="pnlOptions">
<label><input type="checkbox" id="cbIgnoreCase">Ignore Case</label>
</div>
Here is CSS for the label. It's basically bolded text.
#pnlOptions
{
width: 800px;
margin: 0 auto 0 auto;
text-align: center;
}
label
{
font-weight: bold;
}
</style>
And this is the beginning state.
Run
checkPalindrome() when text changes. And when the checkbox is clicked.
<div id="pnlString">
<input id="txtString" oninput="checkPalindrome();" placeholder="Enter text, e.g, Kayak" />
</div>
<div id="pnlOptions">
<label><input type="checkbox" id="cbIgnoreCase" onclick="checkPalindrome();">Ignore Case</label>
</div>
As we create
checkPalindrome(), let's create two more functions -
setResult() and
setVerification(). They are used to populate the divs with information. Also create
isPalindrome(). All these functions will be called by
checkPalindrome().
<script>
function checkPalindrome()
{
}
function isPalindrome()
{
}
function setResult()
{
}
function setVerification()
{
}
</script>
setResult() is probably the easiest. We give it a parameter,
str.
pnlResult's content will be set with
str.
function setResult(str)
{
document.getElementById("pnlResult").innerHTML = str;
return;
}
setVerification() has two parameters;
str - just like in
setResult() and
colorCode, which has a default value. We begin with a
return statement at the end.
function setVerification(str, colorCode = "default")
{
return;
}
Then we have an object,
colors. It has four properties, each one with a corresponding color string as a value.
function setVerification(str, colorCode = "default")
{
let colors =
{
"default": "black",
"success": "green",
"failure": "red",
"pending": "grey"
};
return;
}
We set
pnlVerification as the DOM element
pnlVerification. Then we set its
color property by referencing the
colors object with the value of
colorCode, and set the content using
str.
function setVerification(str, colorCode = "default")
{
let colors =
{
"default": "black",
"success": "green",
"failure": "red",
"pending": "grey"
};
let pnlVerification = document.getElementById("pnlVerification");
pnlVerification.style.color = colors[colorCode];
pnlVerification.innerHTML = str;
return;
}
isPalindrome() has a parameter,
str. Its job is to determine if str is a palindrome. For this, we declare
arr as an array of all letters of
str. We use the
Spread operator for this.
function isPalindrome(str)
{
let arr = [...str];
}
We return a Boolean value, determined by reversing
arr and turning it back into a string using the
join() method (with an empty string as the argument) and then comparing the result to
str.
function isPalindrome(str)
{
let arr = [...str];
return (arr.reverse().join("") == str);
}
Now we're finally going to work on
checkPalindrome(). We start by declaring
txtString as the DOM element by the same id. We then declare
processed, and use it to store the value of the sanitized value of
txtString, by stripping out anything that isn't an alphabetical character.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
return;
}
And if
processed turns out to have zero usable characters, reset to factory settings.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
if (processed.length == 0)
{
setResult("(no text yet)");
setVerification("Enter some text above", "default");
}
return;
}
Now that's out of the way, we should, regardless, make
processed visible by using it as an argument in
setResult(). Then we'll have an
If-else block to check if
processed has 1 character or less. In that case, we'll set the text to "Inconclusive..." with a different color code. If later
processed turns out to have zero characters, it will be handled by the
If block at the bottom.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
setResult(processed);
if (processed.length <= 1)
{
setVerification("Inconclusive...", "pending");
}
else
{
}
if (processed.length == 0)
{
setResult("(no text yet)");
setVerification("Enter some text above", "default");
}
return;
}
If there's 2 or more characters, we check if
processed is a palindrome using the
isPalindome() function, then use
setVerification() accordingly.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
setResult(processed);
if (processed.length <= 1)
{
setVerification("Inconclusive...", "pending");
}
else
{
if (isPalindrome(processed))
{
setVerification("This is a Palindrome!", "success");
}
else
{
setVerification("This is not a Palindrome!", "failure");
}
}
if (processed.length == 0)
{
setResult("(no text yet)");
setVerification("Enter some text above", "default");
}
return;
}
But what about the checkbox?
Well, glad you asked. Declare
cbIgnoreCase as the checkbox.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
let cbIgnoreCase = document.getElementById("cbIgnoreCase");
setResult(processed);
if (processed.length <= 1)
{
setVerification("Inconclusive...", "pending");
}
else
{
if (isPalindrome(processed))
{
setVerification("This is a Palindrome!", "success");
}
else
{
setVerification("This is not a Palindrome!", "failure");
}
}
if (processed.length == 0)
{
setResult("(no text yet)");
setVerification("Enter some text above", "default");
}
return;
}
Now we see if
cbIgnoreCase is checked. If so, we set
processed to be all in lowercase. Which means that when it's eventually run through
isPalindrome(), it will be treated as though it's in all lowercase regardless of what case
txtString is in.
function checkPalindrome()
{
let txtString = document.getElementById("txtString");
let processed = txtString.value.replace(/[^a-zA-Z]/g, "");
let cbIgnoreCase = document.getElementById("cbIgnoreCase");
if (cbIgnoreCase.checked) processed = processed.toLowerCase();
setResult(processed);
if (processed.length <= 1)
{
setVerification("Inconclusive...", "pending");
}
else
{
if (isPalindrome(processed))
{
setVerification("This is a Palindrome!", "success");
}
else
{
setVerification("This is not a Palindrome!", "failure");
}
}
if (processed.length == 0)
{
setResult("(no text yet)");
setVerification("Enter some text above", "default");
}
return;
}
Time to test!
Remove the
red outlines.
div { outline: 0px solid red; }
We'll use "kayak". Start by adding a "k". It should read as "inconclusive", because there's only 1 character.
Add "a". Now the interface is sure; this is
not a palindrome.
Add "12345". The script screens all these out, so the string to be compared is still "ka".
Now add "yaK". Note the capitalization. So the resultant string is "kayaK".
If you click on the checkbox, now the resultant string is "kayak". It's a palindrome!
Are you Wow-ed yet?
This wasn't flashy, but boy did I feel like a young programmer again! Simple enough to hand-code, small enough to digest!
xoxox,
T___T