Skip Navigation | Home | Code Samples | Articles | Links | About | Contact Me | Make a Payment

Rank Optgroup

Sometimes you need to be able to group rankable/sortable elements together. Until recently your only option was to break the groups into separate select lists, requiring multiple, identical interfaces, complicated scripting, etc. Well, with support for the <optgroup> tag, we can now group options all within a single select.

The interface below supports multiple selections. It will attempt to move all selected options in whichever direction you specify. Options are bound by their containing optgroups. Go ahead, play around, and see for yourself what all it can do.


function moveOption(selectObj, direction)
{
  if(selectObj.selectedIndex != -1)
  {
    var oOptgroups = selectObj.getElementsByTagName('OPTGROUP');
    if(direction < 0)
    {
      if(oOptgroups.length)
      {
        for(var i = 0; i < oOptgroups.length; i++)
        {
          var oOptions = oOptgroups[i].getElementsByTagName('OPTION');
          for(var j = 0; j < oOptions.length; j++)
          {
            swapValue = (j == 0 || oOptions[j + direction].selected) ? null : oOptions[j + direction].value;
            swapText = (j == 0 || oOptions[j + direction].selected) ? null : oOptions[j + direction].text;
            if(oOptions[j].selected && swapValue != null && swapText != null)
            {
              thisValue = oOptions[j].value;
              thisText = oOptions[j].text;
              oOptions[j].value = swapValue;
              oOptions[j].text = swapText;
              oOptions[j + direction].value = thisValue;
              oOptions[j + direction].text = thisText;
              oOptions[j].selected = false;
              oOptions[j + direction].selected = true;
            }
          }
        }
      }
      else
      {
        swapValue = (i == 0 || selectObj.options[i + direction].selected) ? null : selectObj.options[i + direction].value;
        swapText = (i == 0 || selectObj.options[i + direction].selected) ? null : selectObj.options[i + direction].text;
        if(selectObj.options[i].selected && swapValue != null && swapText != null)
        {
          thisValue = selectObj.options[i].value;
          thisText = selectObj.options[i].text;
          selectObj.options[i].value = swapValue;
          selectObj.options[i].text = swapText;
          selectObj.options[i + direction].value = thisValue;
          selectObj.options[i + direction].text = thisText;
          selectObj.options[i].selected = false;
          selectObj.options[i + direction].selected = true;
        }
      }
    }
    else
    {
      if(oOptgroups.length)
      {
        for(var i = 0; i < oOptgroups.length; i++)
        {
          var oOptions = oOptgroups[i].getElementsByTagName('OPTION');
          for(var j = oOptions.length - 1; j >= 0; j--)
          {
            swapValue = (j == oOptions.length - 1 || oOptions[j + direction].selected) ? null : oOptions[j + direction].value;
            swapText = (j == oOptions.length - 1 || oOptions[j + direction].selected) ? null : oOptions[j + direction].text;
            if(oOptions[j].selected && swapValue != null && swapText != null)
            {
              thisValue = oOptions[j].value;
              thisText = oOptions[j].text;
              oOptions[j].value = swapValue;
              oOptions[j].text = swapText;
              oOptions[j + direction].value = thisValue;
              oOptions[j + direction].text = thisText;
              oOptions[j].selected = false;
              oOptions[j + direction].selected = true;
            }

          }
        }
      }
      else
      {
        for(i = selectObj.options.length - 1; i >= 0; i--)
        {
          swapValue = (i == selectObj.options.length - 1 || selectObj.options[i + direction].selected) ? null : selectObj.options[i + direction].value;
          swapText = (i == selectObj.options.length - 1 || selectObj.options[i + direction].selected) ? null : selectObj.options[i + direction].text;
          if(selectObj.options[i].selected && swapValue != null && swapText != null)
          {
            thisValue = selectObj.options[i].value;
            thisText = selectObj.options[i].text;
            selectObj.options[i].value = swapValue;
            selectObj.options[i].text = swapText;
            selectObj.options[i + direction].value = thisValue;
            selectObj.options[i + direction].text = thisText;
            selectObj.options[i].selected = false;
            selectObj.options[i + direction].selected = true;
          }
        }
      }
    }
  }
}
function selectAll(selectObj)
{
  for(i = 0; i < selectObj.options.length; i++)
    selectObj.options[i].selected = true;
  return false;
}