Monday, November 4, 2024

Convert a List into a Select Dropdown using jQuery

Convert a List into a Select Dropdown using jQuery

Look around the Internet and you’ll find lots of JavaScript in-place editor libraries that allow you to convert display text into an editable field. Just as interesting, but less common, is the select-in-place list. That works much the same way as in-place text editing, but allows the user to select from an ordered or unordered list by converting it into a <SELECT> element. There may very well be some libraries for that, but it’s so easy to do that you might as well just write it yourself! I’ll show you how.

What’s Your Favorite Fruit?

Changing a list into a <SELECT> dropdown lends itself very well to voting polls. Say that you had a list of fruits. You could decide to submit your own choice by clicking on it. That might be a frivolous thing to be voting on, but in a world where the color of a dress can break the Internet, why not?

Depending on whether we wanted to list the items in order of importance, we could use either an ordered or unordered list. Both have exactly the same syntax, except for the outer tags, which are <OL> and <UL> respectively. Here is the markup and resulting lists produced by both tags:

<UL class="dropdown">
  <LH>What's your favorite fruit?</LH>
  <LI>apples</LI>
  <LI>oranges</LI>
  <LI>bananas</LI>
  <LI>strawberries</LI>
  <LI>raspberries</LI>
  <LI>melons</LI>
  <LI>grapes</LI>
  <LI>tangerines</LI>
</UL>

Did you know that lists support the <LH> tag? It’s short for List Header and acts much like the <TH> Table Header tag. It semantically adds a heading to a list.

Referencing jQuery

As alluded to in the title, we’re going to use jQuery to generate the <SELECT> dropdown markup. One of jQuery’s greatest strengths is in DOM manipulation so it will make our job a lot easier. It’s really simple to reference too, thanks to Google hosting. Just add a script tags to your document and point the src attribute to Google:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Binding to a List’s Onclick Event

There is no reason to touch the HTML markup because jQuery allows us to bind to an element’s onclick event from within the JavaScript file. Binding code should be placed in the document.ready() function that fires once all of the page has loaded. There is a click() handler that can be invoked from an element collection returned via the special $() selector. I chose to assign a class of “dropdown” to those lists that I wanted to be editable:

jQuery(document).ready(function() {
  $('.dropdown').click(function() {
    //build the SELECT control...
  });
});

A Basic Conversion

Our conversion code makes use of jQuery’s powerful $() selector and replaceWith() functions. The former both wraps the list element, which is passed to the handler via the this pointer as well as creates a new <SELECT> by passing in the tag name. The replaceWith() function instantly swaps the list with the new <SELECT> element in the DOM.

Of course, that would produce an empty list. We also have to convert the list items. The children() function restricts the selection to lt;LI> elements because of the ‘li’ argument. In jQuery, all DOM collections possess the each() iterator function. We can invoke it to append a new option to the <SELECT> element. The option text is retrieved from the list element and set on the option using the html() function. The value attribute is set using the index argument that is passed to the each() function. Feel free to substitute a more meaningful value for your application.

 var $list   = $(this),
     $select = $('<select />');

$list.children('li').each(function(index) {
  $select.append($('<option />').attr('value', index).html($(this).html()));
});

$list.replaceWith($select);

Giving the <SELECT> an ID

Depending on how many editable lists you have in your page, you may want to assign each of them a unique ID so that you may refer to the new element later. We can’t just call it “converted_dropdown” because that will be replicated across all generated dropdowns, but we cn make it unique by appending a number to the end. It turns out that jQuery has just the thing called the DOM collection index() function. Given a set of elements, it takes a selector string or element and returns it’s position in the DOM collection. In our case, we want to include all of the .dropdown lists as well as converted dropdowns to search against. Then we pass in the this pointer to see where it resides in the collection. The returned index is zero-based, so you can add one to it if you want to start there instead:

var $list   = $(this),
    index   = $('.dropdown, select[id^="converted_dropdown_"]').index( this ),
    $select = $('<select />').attr('id', 'converted_dropdown_' + (index + 1));

The neat thing about the above code is that it always returns the element’s true position on the page. Hence, the further down the page an element is, the higher the index. The order in which elements are converted is inconsequential.

Here is some sample output, which has been formatted for readability:

<select id="converted_dropdown_2">
  <option value="0">apples</option>
  <option value="1">oranges</option>
  <option value="2">bananas</option>
  <option value="3">strawberries</option>
  <option value="4">raspberries</option>
  <option value="5">melons</option>
  <option value="6">grapes</option>
  <option value="7">tangerines</option>
</select>

Conclusion

There would obviously need to be a voting button there somewhere that sends an Ajax request to the server. We’ll get to that next time, along with how to handle the LH tag, assign optional attributes, and some other neat stuff!

Rob Gravelle
Rob Gravelle
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.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Popular Articles

Featured