Howdy, and welcome to today's web tutorial!
We're going to make what I call a
Smart Drop-down List. Not only can you select from this list, you can type in text and the list will show you only the options corresponding to that text. It's one of the most ubiquitous features in many UI packages today and you could probably just download one from the plethora of packages out there... or we could have some fun instead and make our own.
For that, let's first implement a classic drop-down list. It will be a very standard select element, id
ddlCountries. The first option will be blank, and after that, I simply copied an entire list of countries from
this site.
<!DOCTYPE html>
<html>
<head>
<title>Smart Drop-down List</title>
<style>
</style>
<script>
</script>
</head>
<body>
<select id="ddlCountries">
<option value="">(select one)</option>
<option value="AF">Afghanistan</option>
<option value="AX">Ã…land Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
... (get the rest of the code
here)
</select>
</body>
</html>
That's a
very long list...
And what comes next, is that we wrap this within a div with a class of
ddl_wrapper.
<div class="ddl_wrapper">
<select id="ddlCountries">
<option value="">(select one)</option>
<option value="AF">Afghanistan</option>
<option value="AX">Ã…land Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
... (get the rest of the code
here)
</select>
</div>
Let's write the style for
ddl_wrapper. Give it a
black outline so we can see what's going on, set
overflow to
visible so that nothing gets cut off, and maybe a width and height, though height isn't really necessary.
<style>
.ddl_wrapper
{
outline: 1px solid black;
overflow: visible;
width: 200px;
height: 30px;
}
</style>
Now you see that your drop-down list is encased within the div!
OK, here's the deal. We'll create something that simulates what this drop-down list does, and later hide this drop-down list.
So first, let's put in a div.
<div class="ddl_wrapper">
<div>
</div>
<select id="ddlCountries">
<option value="">(select one)</option>
<option value="AF">Afghanistan</option>
<option value="AX">Ã…land Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
... (get the rest of the code here)
</select>
</div>
Then add in two things - a text box with an id of
txtCountries and another div containing the ▼ symbol.
<div class="ddl_wrapper">
<div>
<input placeholder="Countries" id="txtCountries">
<div>▼</div>
</div>
<select id="ddlCountries">
<option value="">(select one)</option>
<option value="AF">Afghanistan</option>
<option value="AX">Ã…land Islands</option>
<option value="AL">Albania</option>
<option value="DZ">Algeria</option>
<option value="AS">American Samoa</option>
<option value="AD">Andorra</option>
... (get the rest of the code here)
</select>
</div>
Things looking a bit messy at the moment. Not to worry, we'll clean it up with some styling.
First, remove the
black border in the
ddl_wrapper CSS class.
<style>
.ddl_wrapper
{
outline: 0px solid black;
overflow: visible;
width: 200px;
height: 30px;
}
</style>
Now, for the main div within the
ddl_wrapper CSS class, give it a light
grey border, and set the width to 100%. That means it'll occupy the entirety of the parent div.
<style>
.ddl_wrapper
{
outline: 0px solid black;
overflow: visible;
width: 200px;
height: 30px;
}
.ddl_wrapper div
{
border: 1px solid #DDDDDD;
width: 100%;
}
</style>
For the div with the ▼ symbol, it's supposed to be clickable. So set the
cursor property to
pointer, give it a width of 10% and make it float right. Text alignment, border and padding are up to you, though I think the values I've used below work best.
<style>
.ddl_wrapper
{
outline: 0px solid black;
overflow: visible;
width: 200px;
height: 30px;
}
.ddl_wrapper div
{
border: 1px solid #DDDDDD;
width: 100%;
}
.ddl_wrapper div div
{
width: 10%;
float: right;
text-align: center;
cursor: pointer;
padding: 0;
border: none;
}
</style>
As for the text box, give it 80% width, 90% height and set both the
border and
outline properties to
none. This will make it totally seamless.
<style>
.ddl_wrapper
{
outline: 0px solid black;
overflow: visible;
width: 200px;
height: 30px;
}
.ddl_wrapper div
{
border: 1px solid #DDDDDD;
width: 100%;
}
.ddl_wrapper div div
{
width: 10%;
float: right;
text-align: center;
cursor: pointer;
padding: 0;
border: none;
}
.ddl_wrapper div input
{
width: 80%;
height: 90%;
border: none;
outline: none;
}
</style>
Looking much better now.
Now let's make it perform like a drop-down list! Insert an unordered list after the first div inside the div styled with
ddl_wrapper. The id will be
ulCountries. Make it disappear using an inline style attribute and
display: none. Then put an
onclick event in the "button". It should run the
showList() function, passing in "Countries" and
true as arguments.
<div>
<input placeholder="Countries" id="txtCountries">
<div onclick="showList('Countries', true)">▼</div>
</div>
<ul id="ulCountries" style="display:none;"></ul>
Let's write some JavaScript! The
showList() function accepts two parameters -
objName and
showAll.
objName is the name of the object you'll be accessing. In this case, it will be "Countries".
showAll is a Boolean variable that tells you if we need to show the entire list or filter it by search. If we're clicking on the "button", that value is
true. Because clicking on that button will show
all results.
Declare two variables -
ddl and
ul. We'll use the
objName parameter and the
getElementById() method to derive the drop-down list and the unordered list. Initially, the unordered list will be empty.
<script>
function showList(objName, showAll)
{
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
ul.innerHTML = "";
}
</script>
Now let's toggle the unordered list. Each time you click on the "button", if the
ulCountries list is hidden, it'll be displayed. If it's displayed, it'll be hidden. Bear in mind that this is only if
showAll is true, which means the "button" has been clicked.
<script>
function showList(objName, showAll)
{
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
ul.innerHTML = "";
if (showAll)
{
if (ul.style.display == "none")
{
ul.style.display = "block";
}
else
{
ul.style.display = "none";
}
}
}
</script>
After that, iterate through
ddlCountries's options and add them, one by one, into the
ulCountries! We do this by calling the
addListItem() function and passing in
objName, the current option's value and text as arguments.
<script>
function showList(objName, showAll)
{
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
ul.innerHTML = "";
if (showAll)
{
if (ul.style.display == "none")
{
ul.style.display = "block";
for (var i = 0; i < ddl.options.length; i++)
{
var opt = ddl.options[i];
addListItem(objName, opt.value, opt.text);
}
}
else
{
ul.style.display = "none";
}
}
}
</script>
Now let's write the
addListItem() function. It will accept the name of the object, and two other strings as parameters.
val is the value of each option, and
text is the displayed value.
<script>
function showList(objName, showAll)
{
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
ul.innerHTML = "";
if (showAll)
{
if (ul.style.display == "none")
{
ul.style.display = "block";
for (var i = 0; i < ddl.options.length; i++)
{
var opt = ddl.options[i];
addListItem(objName, opt.value, opt.text);
}
}
else
{
ul.style.display = "none";
}
}
}
function addListItem(objName, val, text)
{
}
</script>
Here, we declare the variable
ul and repeat what we did in the
showList() function. Then we use the
createElement() method to create a list item.
function addListItem(objName, val, text)
{
var ul = document.getElementById("ul" + objName);
var li = document.createElement("li");
}
Next, set the list item's displayed text to
text, and append it to
ddlCountries. For the time being, we won't use the
val parameter.
function addListItem(objName, val, text)
{
var ul = document.getElementById("ul" + objName);
var li = document.createElement("li");
li.innerHTML = text;
ul.appendChild(li);
}
Let's test this! Clicking on the "button" should toggle the list on and off! I know it looks shitty right now, but our objective is first to get it to work.
Now, what else should we implement? The list toggles on and off, but we can't select anything. That's what we'll do next. After setting the text, add an
onclick handler that will run the
selectOption() function with
objName,
val and
text as arguments. Then create said function.
function addListItem(objName, val, text)
{
var ul = document.getElementById("ul" + objName);
var li = document.createElement("li");
li.innerHTML = text;
li.onclick = function()
{
selectOption(objName, val, text);
}
ul.appendChild(li);
}
function selectOption(objName, val, text)
{
}
Here, we use
objName to first do pretty much what we did for the other two functions, except that now we'll grab the textbox, txtCountries as well.
function selectOption(objName, val, text)
{
var txt = document.getElementById("txt" + objName);
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
}
Then we set the text in the
txtCountries text box to text and ensure that
ddlCountries is also set to
val. After that, hide
ulCountries.
function selectOption(objName, val, text)
{
var txt = document.getElementById("txt" + objName);
var ddl = document.getElementById("ddl" + objName);
var ul = document.getElementById("ul" + objName);
txt.value = text;
ddl.value = val;
ul.style.display = "none";
}
Now try this. Click on the "button" and select, say, Ghana. Does "Ghana" appear in the text box? Does
ddlCountries select Ghana too?
Next
It looks messy right now, so in the next part, we're going to pretty it up a bit. Stay with me!