tags:

views:

582

answers:

2

I am looking for a drop down list which can present the user with a series of images to choose from. Each image will be about 50x50 pixels and a small text description will be under the image. A jQuery and compatable ASP.NET solution would be preferred.

A: 

As far as I know, it is impossible to achieve this by styling a standard HTML dropdown list. you'll have to program one yourself with javascript. Since Stackoverflow is not the place to ask people for a takeaway piece of code I suggest searching for it here

Bar10
+2  A: 

I wrote a super basic jQuery plug in to accomplish this. What will happen is a a fake drop down list will be created from an existing select tag. The original select will be hidden, and the fake menu will be shown. As the new menu is being created, it will callback to get the HTML to show for each option. In this function you can pass back an image.

(function($) {
$.fn.templatedSelect = function(options) {

var defaults = {
 selectHandleImage : "selectHandle.gif",
 width : "65px",
 getOption : function(value, text) {
   return text;
  }
};
var opts = $.extend(defaults, options);

 var $originalSelect = this;

 var $container = $(document.createElement('div'))
  .css("clear", "both")
  .css("width", opts.width)
  .hover(
   function () {
    $selectBox.css("border-color", "#000000");
   }, 
   function () {
    if (!$menuItems.is(":visible"))
     $selectBox.css("border-color", "#C0C0C0");
   })
  .attr('id', "imageSelect_container_" + this.attr('id'));

 var $selectBox = $(document.createElement('div'))
  .css("border", "solid 1px #C0C0C0")
  .css("overflow", "hidden")
  .css("width", "100%")

 var $selectedItem = $(document.createElement('div'))
  .css("padding", "4px");

 var $selectHandle = $(document.createElement('div'))
  .css("float", "right")
  .css("background-color", "#F0F0F0")
  .css("padding", "4px") 
  .css("cursor", "hand")   
  .click(function(e) {
            ToggleMenuItems();
        })
  .html(
   $(document.createElement('img')).attr("src", opts.selectHandleImage)
  );

 var $menuItems = $(document.createElement('div'))
  .css("position", "absolute")
  .css("margin-top", "-1px")
  .css("border", "solid 1px #000000")
  .css("background-color", "#FFFFFF")
  .hide();

 $originalSelect.children("option").each(function(i, selected) {   
  var $menuItem = $(document.createElement('div'))
   .css("padding", "4px")
   .html(opts.getOption($(this).val(), $(this).text()))
   .val($(this).val())
   .click(function(e) {
    ToggleMenuItems();
    $originalSelect.val($(this).val());
    $selectedItem.html($(this).html());
   })
   .hover(
    function () {
     $(this).css("background-color", "#81BEF7");
    }, 
    function () {
     $(this).css("background-color", "#FFFFFF");
    })
   .appendTo($menuItems);
 });

 //preset the selectedItem
 $selectedItem.html(
  $menuItems.children("div:eq("+$originalSelect[0].selectedIndex+")").html()
 );

 //put everything together
 $selectBox.appendTo($container);
 $selectHandle.appendTo($selectBox);
 $selectedItem.appendTo($selectBox);
 $menuItems.appendTo($container);

 //hide the original select and put ours in
 $originalSelect.hide();
 $container.insertBefore($originalSelect);

 $selectHandle.height($selectBox.height());
 $menuItems.width($selectBox.width());

 function ToggleMenuItems() {
  if ($menuItems.is(":visible")) {
   $menuItems.hide();
   $selectBox.css("border", "solid 1px #C0C0C0");
  } else {
   $menuItems.show();
   $selectBox.css("border", "solid 1px #000000");
  }
 }

}})(jQuery);

To use, call templatedSelect on your existing select. Also pass in a function to resolve the template for each item

 $().ready(function() {
  $('#selectId').templatedSelect({
   getOption : function(v, t) {
    return "<img src='" + v + "'/><br/>" + t; 
   }
  });
Bob
u can pass multiple styles into .css e.g .css( {color:'red', left:'10px'} )
redsquare
Thanks for the tip, still learning the ways of jQuery.
Bob