skip to main | skip to sidebar

Many times in web forms we need to provide a listbox with lots of elements, A good solution is to filter and page these elements to speedup page loading and optimize DB/Network usage..

Update! I've rewritten the code as jQuery plugin, made few enhancements and provided a complete sample code in VB.Net and C#. check-out the new plugin of Paging Listbox.

This is a complete implementation of a paging listbox using jQuery on client side and ASP.Net on server side. and should look like this..
Paging Listbox
The form web page, which also contains the JavaScript class to build the select box, of course don't forget to download the jQuery library.
<html>
<head>
<title>jQuery & Ajax Fun: Implementing a Paging Listbox</title>
<script type="text/javascript" src="JS/jquery-1.3.min.js"></script>
<script type="text/javascript">
function AjaxListBox() {
   this.source = '';
   this.divID= '';
   this.keyID= '';
   this.buttonID= '';
   this.lastKey= '';
   this.startup= true;
   this.minWidth=0;
   this.position = {'top':0,'left':0};
   var self = this;
   this.init= function() {
      $(document).ready(function(){
         //calc position and min-width for listbox
         self.minWidth = $('#'+self.keyID).width()+ $('#'+self.buttonID).width()+4;
         self.position = $('#'+self.keyID).position();
         self.position.top= self.position.top + $('#'+self.keyID).height()+2;
         // Position and hide div
         $('#'+self.divID).css({'display':'none','border':'gray 1px solid','position':'absolute','z-index':5,'top':self.position.top,'left':self.position.left});
         // bind onclick handler for 'toggle' button
         $('#'+self.buttonID).bind('click',null,self.toggle);
         // bind onkeydown handler for 'Key' textinput and call find function
         $('#'+self.keyID).bind('keydown',null,self.keydown);
         //load list
         self.load();
      });
   }
   this.load= function(key,pi) {
      if(key==null ||key=='undefined') key='';
      if(pi==null ||pi=='undefined') pi='';
      //Save key to use when move through pages
      this.lastKey= key;
      
      $('#'+this.divID).html('please wait..');
      $.get(this.source,{'key':key,'pi': pi},this.loaded,'html' );
   }
   this.loaded = function(data,txtStatus) {
      //Set Inner html with response of Ajax request
      $('#'+self.divID).html(data);
      $('#'+self.divID+' > select').css({'border-width':'0'});
      //Add handler for onchange to reload when another page is requested
      $('#'+self.divID+' > select').bind('change',null,self.change);
      //Add handler for onblur to hide box
      $('#'+self.divID+' > select').bind('blur',null,self.hide);

      if (self.startup) self.startup=false;
      else self.show();
   }
   this.change = function() {
      //Get Value of Select Box
      var v = $('#'+self.divID+' > select').val();
      //To do paging the value must be like 'pi=2' which means go to page 2
      if (/^pi=\d+$/i.test(v)) {
         var pi= v.replace(/pi=/i,'');
         self.load(self.lastKey,pi);
      }   
   }
   this.toggle = function(e) {
      if ($('#'+self.divID).css('display')=='none') self.show();
      else self.hide();
   }
   this.show = function(e){
      $('#'+self.divID).show();
      //Insure width is more than min-width
      var w = $('#'+self.divID+' > select').width();
      if (w>0 && w<self.minWidth) $('#'+self.divID+' > select').width(self.minWidth);
   }
   this.hide = function(e){
      $('#'+self.divID).hide();
   }
   this.find = function() {
      //text to search for
      self.load($('#'+self.keyID).val());
   }
   this.keydown = function(e) {
      // this will catch pressing enter and call find function
      var intKey = e.keyCode;
      if(intKey == 13) {
         self.find();
         //and prevent submitting the form that contain this input box
         return false;
      }   
   }
}
</script>
<style type="text/css">
   * {
      font:12px arial
   }
   .AjaxListBoxKey {
      border:gray 1px solid;
      width:120px;
   }
   .AjaxListBoxKeyBTN{
      border:silver 1px solid;
      background-color:#333333;
      color:white;
      padding:.5px;
      font:12px arial;
   }
</style>
</head>
<body>
   <form id="form1" action="" method="post">
      Select Product
      <input id="key" name="key" type="text" class="AjaxListBoxKey" /><input type="button" id="find" class="AjaxListBoxKeyBTN" value="&#9660;" />
      <div id="box"></div>
      <script type="text/javascript">
         var box = new AjaxListBox();
         box.source = "listbox.aspx";
         box.divID = "box";
         box.keyID = "key";
         box.buttonID= "find";
         box.init();
      </script>
    </form>
</body>
</html>


The server side page(whatever the language is!) is requested to handle query string parameters (pi: PageIndex, key: Search keyword) and response with just a list box(no other tags!) that contains the matched elements at the requested page index, plus 2 extra elements to go to previous and next pages indexes with value like 'pi=3' which means go to page 3. Of course you can select the PageSize and listbox size that works for you.

Here is server side page "listbox.aspx"
<%@ Page Language="VB" %>
<script runat="server" language="VB">
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      Dim key As String = Request.QueryString("key") & ""
      Dim PageIndex As Integer = 1
      Try
         PageIndex = Integer.Parse(Request.QueryString("PI"))
      Catch ex As Exception
         PageIndex = 1
      End Try

      Dim ps As New Products
      ps.PageSize = 5
      ps.PageIndex = PageIndex
      ps.SelectItems(Product.ProductStatus.Active, key)
      Response.Write(ps.PagingBox("ProductID", 0, , , 5))
      ps = Nothing
   End Sub
</script>


On Listbox.aspx I'm using my favorite[Traditional yet Powerful : Data Access Layer for ASP.Net] to access the products Table after adding the following function to the collection class to build the listbox.
Public Function PagingBox(ByVal FieldID As String, ByVal SelectedID As Integer, Optional ByVal FieldClass As String = "", Optional ByVal Onchange As String = "", Optional ByVal size As Integer = 0) As String
   Dim ret As New StringBuilder("<select name=""" & FieldID & """ id=""" & FieldID & """")
   If FieldClass > "" Then ret.Append(" FieldClass=""" & FieldClass & """")
   If Onchange > "" Then ret.Append(" Onchange=""" & Onchange & """")
   If size > 0 Then ret.Append(" size=""" & size + 2 & """")
   ret.Append(">")

   If Me.Count = 0 Then
      ret.Append("<option value="""">-- No Results! --</option>")
   End If

   If PageIndex > 1 Then
      ret.Append("<option value=""pi=" & (PageIndex - 1) & """>" & _
             "-- to Page " & (PageIndex - 1) & " of " & PageCount & " --</option>")
   End If
   For i As Integer = 0 To Me.Count - 1
      Dim P As Product = Item(i)
      ret.Append("<option value=""" & P.ID & """")
      If P.ID = SelectedID Then ret.Append(" selected")
      ret.Append(">" & P.Name & "</option>")
   Next

   If PageIndex < PageCount And PageIndex > 0 Then
      ret.Append("<option value=""pi=" & (PageIndex + 1) & """>" & _
             "-- to Page " & (PageIndex + 1) & " of " & PageCount & " --</option>")
   End If

   ret.Append("</select>")
   Return ret.ToString
End Function


Many greetings to jQuery folks..

3 comments

  1. Anonymous // June 30, 2009 at 2:32:00 PM GMT+10  

    I tried to implement this article with my code. i have a dataset which contain value more than 10,000+ . So i want to implement this paging mechanism but how can i embeed my dataset with this code. Also i do in C sharp. Plz help me to bind with dataset.

  2. Mike // July 1, 2009 at 9:03:00 AM GMT+10  

    @Anonymous,
    Wherever data is coming from.. you need to have an aspx page that loops your dataset and response.write the <select> and <option> tags that constructs the listbox.. without using master page or any extra html..

  3. Anonymous // November 21, 2009 at 7:03:00 PM GMT+11  

    Like that...

    good articles..

    thank u

Post a Comment

Thank you for taking the time to comment..
* If you have a tech issue with one of my plugins, you may email me on mike[at]moretechtips.net

Mike

Mike MoreWeb developer, jQuery plugin author, social media fan and Technology Blogger.
My favorite topics are: jQuery , Javascript , ASP.Net , Twitter , Google..
<connect with="me"> </connect>

Subscribe by email

Enter your email address:

or via RSS