Themeforest

Change Order of Multiple Select Lists Using jQuery

In my last post I went through the code required to create an add/remove select list using jQuery.

Today’s post is going to expand on the earlier tutorial and add up/down buttons, which will allow you to change the order of the option items in the select list.

The HTML Code

The HTML code for the select lists remains the same as the earlier post, except with the addition of the “up” and “down” links:

<form>
  <fieldset>
    <select name="selectfrom" id="select-from" multiple size="5">
      <option value="1">Item 1</option>
      <option value="2">Item 2</option>
      <option value="3">Item 3</option>
      <option value="4">Item 4</option>
    </select>
    <a href="JavaScript:void(0);" id="btn-add">Add &raquo;</a>
    <a href="JavaScript:void(0);" id="btn-remove">&laquo; Remove</a>
    <select name="selectto" id="select-to" multiple size="5">
      <option value="5">Item 5</option>
      <option value="6">Item 6</option>
      <option value="7">Item 7</option>
    </select>
    <a href="JavaScript:void(0);" id="btn-up">Up</a>
    <a href="JavaScript:void(0);" id="btn-down">Down</a>
  </fieldset>
</form>

The jQuery Code

Again, keeping the same code for the add/remove functions, we just need to add the additional jQuery to handle the up/down links:

$(document).ready(function() {
    $('#btn-add').click(function(){
        $('#select-from option:selected').each( function() {
                $('#select-to').append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
            $(this).remove();
        });
    });
    $('#btn-remove').click(function(){
        $('#select-to option:selected').each( function() {
            $('#select-from').append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
            $(this).remove();
        });
    });
    $('#btn-up').bind('click', function() {
		$('#select-to option:selected').each( function() {
			var newPos = $('#select-to option').index(this) - 1;
			if (newPos > -1) {
				$('#select-to option').eq(newPos).before("<option value='"+$(this).val()+"' selected='selected'>"+$(this).text()+"</option>");
				$(this).remove();
			}
		});
	});
	$('#btn-down').bind('click', function() {
		var countOptions = $('#select-to option').size();
		$('#select-to option:selected').each( function() {
			var newPos = $('#select-to option').index(this) + 1;
			if (newPos < countOptions) {
				$('#select-to option').eq(newPos).after("<option value='"+$(this).val()+"' selected='selected'>"+$(this).text()+"</option>");
				$(this).remove();
			}
		});
	});
});

1. The “Up” Link

First we tackle the “up” link. Basically how we handle this is to retrieve the index value of each selected option, set the variable for the option items new position as … current index – 1, recreate the option HTML and insert it “before” the new index position. Finally – remove the old HTML from the list.

In order to make sure that we dont lose the option item off list list by trying to insert at an index position < 0 we do a quick check on the current position and only run the code if index > 0.

2. The “Down” Link

The down link is very similar except we set the new index postion to “current + 1″ and insert the option HTML “after” this value.

Once again we need to make sure that we dont lose the option item off the bottom of the list so we include an “if” statement, which checks the total number of items in the list and only runs the code if the new index position is less than the total items.

The above code also works for multiple selected items.

Check out the change order of select lists demo.

7 Comments

  • Any ideea how can i save the changes made by the above script ? (btw … thanks .. worked like a charm) I want to use this with opencart featured products, to order products after my needs. thanks

    • Hi,

      You will need to pass the updated list order to a server-side script, which can save it to the database

  • $(‘#btn-down’).click(function(){
    var countOptions = $(‘PerguntaConceitoConceitoId option’).size();
    var $arr = jQuery.makeArray($(‘#PerguntaConceitoConceitoId option:selected’));
    $arr.reverse(); // there is important for down if two neighbouring options
    jQuery.each($arr,function() {
    var newPos = $(‘#PerguntaConceitoConceitoId option’).index(this) + 1;
    if (newPos < countOptions) {
    $('#PerguntaConceitoConceitoId option').eq(newPos).after("”+$(this).text()+”");
    $(this).remove();
    }
    });
    });

  • Bah – the comment I’m trying to make is that the down function is broken when moving multiple items, unless you reverse the each: $($(‘#specs option:selected’).get().reverse()).each(

  • $($(‘#specs option:selected’).get().reverse()).each(

  • The down button will be right if count the number of selected options and sum it into new position:

        $('#btn-down').bind('click', function() {
            var countOptions = $('#PerguntaConceitoConceitoId option').size();
            var countSelected = $('#PerguntaConceitoConceitoId option:selected').size();
            $('#PerguntaConceitoConceitoId option:selected').each( function() {
                var newPos = $('#PerguntaConceitoConceitoId option').index(this) + countSelected;
                if (newPos &lt; countOptions) {
                    $(&#039;#PerguntaConceitoConceitoId option&#039;).eq(newPos).after(&quot;"+$(this).text()+"");
                    $(this).remove();
                }
            });
        });
    
    • Hi Wesley,

      Thanks for the update

Leave a comment

To add code to your comments wrap the code text in [text][/text] tags