views:

2368

answers:

5

In asp.net if you define an asp:ListBox as follows:

<asp:ListBox ID="listBox2" runat="server" SelectionMode="Single" Rows="3">
  <asp:ListItem>1</asp:ListItem>
  <asp:ListItem>2</asp:ListItem>
  <asp:ListItem>3</asp:ListItem>
  <asp:ListItem>4</asp:ListItem>
  <asp:ListItem>5</asp:ListItem>
  <asp:ListItem>6</asp:ListItem>
  <asp:ListItem>7</asp:ListItem>
  <asp:ListItem Selected="True">8</asp:ListItem>
  <asp:ListItem>9</asp:ListItem>
  <asp:ListItem>10</asp:ListItem>
</asp:ListBox>

You will see that the selected item is visible at the top. But if you define it as a multiple selection list box, the selected items are not visible, and you have to scroll down the list to find them.

<asp:ListBox ID="listBox1" runat="server" SelectionMode="Multiple" Rows="3">
  <asp:ListItem>1</asp:ListItem>
  <asp:ListItem>2</asp:ListItem>
  <asp:ListItem>3</asp:ListItem>
  <asp:ListItem>4</asp:ListItem>
  <asp:ListItem>5</asp:ListItem>
  <asp:ListItem>6</asp:ListItem>
  <asp:ListItem>7</asp:ListItem>
  <asp:ListItem Selected="True">8</asp:ListItem>
  <asp:ListItem Selected="True">9</asp:ListItem>
  <asp:ListItem>10</asp:ListItem>
</asp:ListBox>

I've done a bit of google searching, and see that this is not an uncommon problem. But I did not find any good solutions, so thought I would ask here.

My first thought was to try a bit of JQuery to solve this. What are some of your solutions?

Several of the answers don't even understand my problem. I only care about ensuring that the first selected option is visible. Make sure it is scrolled into view.

I played around with JQuery, and came up with the following:

<script type="text/javascript">
$(document).ready(function() {
   $("#listBox1 option:nth-child(8)").attr('selected',true);
 });
</script>

But I think I like @Cerebrus's answer the best.

A: 

It's bit clumsy, but I've done this once, and would welcome a better solution.

        //get the selected value
        var selected = (from l in lstFilterUsers.Items.Cast<ListItem>()
                 orderby l.Value
                where l.Selected == true
                select l).Take(1);
        //get all the values except for that first selection
        var all = (from l in lstFilterUsers.Items.Cast<ListItem>()
                   where l != selected
                 orderby l.Value
                 select l);
        //create a temp array and fill it
        ListItem[] lic = new ListItem[lstFilterUsers.Items.Count];
        lic[0] = (ListItem)selected;
        int i = 1;
        foreach (var li in all)
        {
            lic[i++] = li;
        }
        //clear the listbox
        lstFilterUsers.Items.Clear();
        //readd the list
        lstFilterUsers.Items.AddRange(lic);
weffey
how is that supposed to make the object visible at the top?
ck
I accidentally hit the post button when I was bringing the focus back to firefox, when I was copying the next snippet of code over. Sorry! Edited to reflect the whole snippet.
weffey
A: 

How are you looking to call this?

From Javascript:

<script type="text/javascript">

var myselect=document.getElementById("listBox1")
for (var i=0; i<myselect.options.length; i++){
    if (myselect.options[i].selected==true){
        alert("Selected Option's index: "+i)
        break;
    }
}

From the Code Behind:

foreach (ListItem li in listBox1.Items)
{
    if (li.Selected)
    {
        return li;
    }
}
Paige Watson
Again, the OP wants the selected items at the top of the listbox, not to know which are selected...
ck
yeah, I guess I didn't read the question well enough. +1 for Cerebrus
Paige Watson
A: 

In my limited experimentation, both Chrome and Firefox do the scrolling automatically.

For IE, I cooked this hacky bit of jQuery code up (tested on IE7):

$(document).ready(function(){
 scrollToFirstSelection('select');  
});

function scrollToFirstSelection(query) {
 var select = $(query);
 var singleOption = select.find('option')[0];
 var heightOfSingleOption = select[0].offsetHeight / select.attr('size');
 var indexOfFirstSelection = select.find('option').index($('option[selected=true]:first'));
 select[0].scrollTop = heightOfSingleOption * indexOfFirstSelection;
}

It might not be exact if you use any crazy padding or margins, but it should be close enough.

Daniel Schaffer
+3  A: 

Here's how I've done it in the past. Note that this scrolls the view to the last item in the listbox.

function FocusSelected()
{
  var lb = document.getElementById("listBox1");
  if (lb != null)
  {
    var options = lb.options;
    for (var i = options.length - 1; i > 0 ; i--)
    {
      if (options[i].selected == true)
      {
        options[i].focus();
        options[i].selected = true;
        return;
      }
    }
  }
}

It works for me on IE 7 and FF 3.0.

Cerebrus