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>
<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>
<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>
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>
<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;
}
{
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>
<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;
}
{
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>
<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>
{
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>
<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>
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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];
}
{
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);
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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;
}
{
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
T___T























