This tutorial is the follow up to last month’s Convert a List into a Select Dropdown using jQuery article. In it, we learned how to create an in-place editor for an ordered or unordered list by converting it into a <SELECT> dropdown. Today we’ll be modifying our conversion code to make it more efficient as well as adding more functionality.
New and Improved
To save you from having to visit the original article again, here is what the conversion code looked like:
Devin Weaver pointed out some issues with using the html() function to set the content of the option tag. Besides the fact that HTML markup should not go into an option tag, including HTML tags opens up the potential for a script injection attack. For those reasons, the text() method should be employed instead. It strips out the HTML and returns the sanitized text content. Mr. Weaver also suggests using map() instead of each() to return the newly created options as an array and then append them all at once. That will save jQuery from having to manipulate the DOM every loop iteration, which could slow down the browser.
Devin, I heard you on both counts, so I updated the existing code accordingly:
The only caveat to using map() – and it’s a small one – is that the append() function can only accept an array of raw elements – i.e. non-jQuery wrapped. To fetch the unwrapped element, we invoke the jQuery Collection .get() method, passing in an element index of zero (0) because the $() element constructor generates a collection of exactly one <option> element.
Advertisement
Handling the List Header tag
Did you know that lists may have a List Header (<LH>) tag, similar to the <TH> tag in tables? It’s true!
Rather than waste a perfectly good tag, we can convert it into a Label to go along with our new SELECT control:
var $list = $(this),
id = 'converted_dropdown_' + (index + 1),
$lh = $('lh');
//set the list options
$select.append($list.children('li').map(function(index) {
return $('<option />').attr('value', index).text($(this).text()).get(0);
}));
//convert the LH element into a labelif ($lh) {
$('<label />').attr('for', id).html($lh.html() + ':<br />').insertBefore($list);
}
$list.replaceWith($select);
When creating the label, it’s OK to use the html() function because it could potentially contain HTML markup.
Advertisement
Class Power
Adding your own attributes to existing element tags is frowned upon. Instead, add your own classes to elements to organize and reference them, just as you would with CSS. For instance, including a class of “dropdown” could be used to identify all editable lists:
<ULclass="dropdown"><!-- options --></UL>
Now we can convert all of them on a common event such as a button click.
The following code attaches our conversion code to the “editButton”‘s click() event. Notice the use of the $(‘.dropdown’) selector to collect all elements with the “dropdown” class. The each() method accepts an index argument, so we don’t have to use the index() function anymore to create the unique IDs.
jQuery(document).ready(function() {
$('#editButton').click(function() {
$('.dropdown').each(function(index) {
var $list = $(this),
id = 'converted_dropdown_' + (index + 1),
$select = $('<select />').attr('id', id),
$lh = $('lh');
//set the list options
$select.append($list.children('li').map(function(index) {
return $('<option />').attr('value', index).text($(this).text()).get(0);
}));
//convert the LH element into a labelif ($lh) {
$('<label />').attr('for', id).html($lh.html() + ':<br />').insertBefore($list);
}
$list.replaceWith($select);
});
});
});
Adding Custom Attributes
We can expand on the class technique to introduce custom attributes as well.
Here’s a list with a couple of extra classes that affect the appearance of our converted list:
The “multiple” attribute can be transfered to our converted select list so that it is displayed with a listbox style rather than a combobox. The “autoheight” attribute tells our script to set the list SIZE to the length of the options – in other words, the same height as the list contents:
Clicking the Edit button produces the following SELECT controls:
Advertisement
Conclusion
With one page Web apps being all the rage right now, providing in-pace editing is a feature that’s sure to be appreciated by your visitors. Just make sure to have a workaround for the 0.1 percent of users who have JavaScript turned off!
Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.
The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.
Advertiser Disclosure: Some of the products that appear on
this site are from companies from which TechnologyAdvice
receives compensation. This compensation may impact how and
where products appear on this site including, for example,
the order in which they appear. TechnologyAdvice does not
include all companies or all types of products available in
the marketplace.