Linkselect jQuery Plug-in Released!

Posted by Dan on Oct 17, 2008 @ 5:06 PM

My current employer (Giva, Inc) has released another jQuery plug-in today called the Linkselect jQuery Plug-in. This plug-in converts a normal <select /> element into a component that can be highly stylized via CSS. While there are a number of similar plug-ins already, there are a several of key differences which we think make this unique:

  • Drop down menus are intelligently positioned to stay in the viewport
  • Specifically designed to work in a limited amount of real estate
  • Specifically designed to work well with elements aligned on the right edge of the viewport
  • Full keyboard support (emulates IE6's <select /> element)
  • Feature rich API (for updating value, replacing options, disabling elements, etc)
  • Many callback features to control behavior (on change, on init, on format, etc.)
  • Supports tabindex

We've put together an example page that demos many of the features and how to use the plug-in.

Categories: JavaScript, jQuery

28 Comments

  • Looking pretty badass! Great demo page too.
  • I only have this to say. *yoink* Mine! Great job. I have immediate use for this. :)
  • wow!! using it already!
  • Very cool!
  • Excellent plugin, Dan, but I'm wondering about how intuitive it is. In the world of browser UI, underlined items normally mean a link that will take you to a new page or state. How do people know that clicking on a link here will produce a list that they can choose from? The traditional select may take up real-estate but at least its purpose is obvious.

    Just curious as to how quickly people get used to this.

    Congratulations on another superbly implemented plug-in though.
  • @Julian: IMHO, that's a styling issue. You can indicate that it's a drop down or make that link look like a drop down easily enough.
  • @Julian:

    As Todd stated, you can use CSS to style things however you want. Go look at Example 10 (http://www.givainc.com/labs/linkselect_example.htm...) and click on the "'Select' Style" button and you can see how you can change the style to however you want.

    As far as intuitiveness, we haven't seen any issue. I think more and more people are just expecting links just to "do something." Normally this something is move to the next page or show a new window of information, but not always. People have seem to pick up the functionality quite quickly. I will note that for many of our users there would be some form of expectation for what those fields should do (since they were previously a select element.) However, new clients have not seemed to have an issue figuring out how it works. They especially like the keyboard shortcuts that visually scroll and open up the linkselect elements.

    From a personal standpoint, this is one of those areas where I'm always torn. While I do believe breaking users expectations can cause confusion (which is very bad,) there is such a lack of sufficient UI controls for modern applications that you sometimes need to go outside the box.
  • @Julian, Dan is also in this case (I think) dealing with an application that has frequent usage so people do learn the application. There are many cases where an accelerator or new interaction design pattern like this can be overall beneficial despite breaking the "rules".

    @Dan, can you put graphics into it?
  • @Brian:

    First, as you indicated, well it's best to limit breaking users expectations, let's face it--there is still plenty of room for improvement. There are still tons of UI problems developers face that still don't have very good solutions (the whole n-select I think is a perfect example--well it's common enough that most people understand, it's a problem that can be solved better.)

    As far as how the options are selected, you have lots of options. Since it's using select and options tags, you may have problems putting inline img tags into the code (I haven't tested whether that works or not,) but you certainly can add class declarations to each option to use images or you can even use the format callback option to insert images into the option tags. So, you can definitely use images for the options, you just have to decide what method works best for you.
  • Hi,

    Love the plugin! It fixes the annoying IE6 select width bug!

    One thing though:
    http://apabc.mosaicnetworks.ca/index.html

    On that site, the third dropdown isn't aligned where it should be.

    Is there a setting that I am forgetting?
  • @Ray:

    Go into the linkselect() source code and find the getScreenDimensions() function. Change the lines:

    , width:   $("body").width()   // changed from innerWidth
    , height:   $("body").height()  // changed from innerHeight

    to:

    , width:   $(document).width()   // changed from innerWidth
    , height:   $(document).height()  // changed from innerHeight

    and see if that doesn't fix the issue.
  • Doesn't work in IE8: an error is thrown and selects remain non-replaced.
  • @Taimar:

    The problem is with the example page, not the linkselect code.

    If you look at the example on the Linkselect Plug-in page, you can see it works fine in IE8:
    http://www.givainc.com/labs/linkselect_example.htm...

    I'm looking into the issue with the example page.
  • @Taimar:

    I spoke a bit too prematurely. The problem was in the build of linkselect that was in the labs. I've updated the code and pushed out the latest version. Now everything is working in IE8.
  • Sweet, thanks for your rapid response and solution! :)
  • Great plugin! This has been the only practical (and attractive I might add) solution to IE's forced width for dropdowns...

    I am curious if there is a way I can make sub-categories within the drop down list.
    Sort of like this:

    Title
    Group A (<-- does not highlight, can not be selected)
    Water
    Fish
    Coral
    Group B (<-- does not highlight, can not be selected)
    Sand
    Snakes
    Sagebrush


    Does that make sense? I know very little Javascript and I spent about 2 hours trying to modify things to make it work but I could not get it. I was thinking something like "If the value of the <option> item is equal to 'noselect' then assign class 'noselect'" Then add a definition to the css like .linkselectContainer ul li.noselect where it can be adjusted if need be.

    Just curious. Thanks again for the awesomeness!
    -Logan
  • @Logan:

    In normal HTML you can do this with the <optgroup /> tag. Alas, I had no need for that type of functionality when I was building this plug-in.

    You might check out the Filament Group's latest project:
    http://www.filamentgroup.com/lab/jquery_ipod_style...

    While not exactly the same, it does allow for nesting of objects.
  • Thanks for the feedback!!

    I had originally designed it with <optgroup /> and liked it a lot, the problem arose because there are entries in the drop down that are wider than the original select box. In FF (and I think Safari (I don't recall)) the drop down options do what I would expect them to do, which is expand to the width of their content. Not only that but I was able to control the width of the select box AND the drop down separately via CSS. That's how it should be right?! Well as I soon learned Internet Explorer cuts off the dropdown based on the width of the select box. So the <optgroup /> made it look really nice but not in IE. Once I found your solution I attempted to keep/use the optgroups but obviously that didn't work. In the end I just made the "titles" of each group a regular <option> but made the text a different color and gave it a value of "noselection". I was unable to make them not highlight or not be selectable but if one is selected and the form is submitted the value of "noselection" returns an error that tells the user to select a valid item from the list. A valid selection goes ahead and writes to the database.

    I think my little work around is a poor, clunky solution but it works ok I suppose. I'm super stoked to use this linkselect elsewhere where I don't need to worry about the sub-groups!

    That stuff by Filament Group is intriguing too! I'm gonna play with it to see what I can come up with.

    Thanks again for the for the quick feedback and the awesome plugin!
    -Logan

    p.s. if you ever do add group/subtitle functionality I'd love to know!
  • @Logan:

    Once thing you could do as well is use the "change" callback to check if the user selected an item with a class of noselection and have it fail.

    If the callback return false, it will not allow selecting of the option.
  • I hate it when people try to have other people do the work for them so I am very intentionally not asking you to show me how to do this but instead trying my hardest to learn/figure this out by looking at the rest of the code (however if you felt so inclined I would not argue). Like I mentioned before I know very little javascript, but I am a pretty quick learner...

    Anyway from what I can figure I would need to implement something similar to this (which is in the binditems function)?:
    // trigger the change callback if it's false, stop processing
                        if( (doCallback !== false) && (($.isFunction(options.change) && (options.change.apply(self, [this, value, text, doCallback]) === false)) || ($.isFunction($select[0].onchange) && ($select[0].onchange.apply(self, [this, value, text, doCallback]) === false))) ){
                            // restore the selected classes (since we're not selecting this option)
                            $previous.addClass(options.classSelected);
                            $current.removeClass(options.classSelected)
                            return;
                        }

    And something with options.classValue...

    I just don't know where to begin. I think I understand parts of it but I am far from understanding most of it.
    Again I'm not expecting a free ride here, so please don't feel obligated to give me the answer or anything. You've already helped way more than I expected! I will continue to read articles and see if I can't learn this stuff real quick!

    Thanks again!
    -Logan
  • @Logan:

    Go to the examples page and look at Example 8:
    http://www.givainc.com/labs/linkselect_example.htm...

    You could do something like:

    $("#ex8_ls").linkselect({
     change: function (li, value, text){
      if( value == "noselection" ) return false;
     }
    });

    That should work (in theory.)
  • How can I show the select if i'm at the bottom of the page and the height is > than sd.y ?

    I didn't managed to find an option or something so I wrote this in function anchorTo($anchor, $target):
    var farBottom = $container.outerHeight() + pos.top;

    if( farBottom > sd.y){
        pos.top = pos.top - $container.outerHeight();
    }

    looks like working.

    what do u think?
  • @Mihai:

    That should make the placement above the link. In our application, none of our Linkselects ever come near the bottom edge of the screen, so it's not an issue we run into.
  • Hi, for first sorry for my english.

    I'm trying to use this plug-in with an automatic form submit after choosing a select option.

    ----
    change: function (li, value, text){
    $("#myform").submit();
    }
    ----

    Unfortunately the callback "change" trigger the submit action before the select value is loaded into the input hidden field.

    So in this case I can't have POST values after the form submit.

    Is it possible to solve this problem? How can i do?

    Thanks in advance.
  • @Yuri:

    You should be able to solve the problem by calling the submit() method asynchronously:

    change: function(){
     setTimeout(function (){ $("#myform").submit() }, 1);
    }

    If for some odd reason the value of "1" (meaning 1 millisecond delay) is still causing problems, just adjust the value to something like 100. However, just invoking it asynchronously ought to be enough to resolve your issue.
  • Thank you so much.

    I found the same solution just one hour ago, before to read your reply. :)

    With a little timeout it seems work perfectly.

    Thanks again. ;)
  • hi~
    i'm trying to use the 'close' callback, but it says '$selected is not define', in function hideOptions.

    and, i'm using ajax load function, to load some html dynamically into a div. the html contains a few <select />, which will be used as linkselect, of cause :), because these <select/> are loaded by ajax, so i have to call linkselect every time when the content was reloaded. but the problem is, linkselect will append some div to the body element, the more i call linkselect, the more it append.
    do you have any solution about this? thanks.
  • @Clark:

    I just pushed out an update (v1.2.07) which will fix the problem you're having with the close callback:

    http://www.givainc.com/labs/linkselect_jquery_plug...

    Right now there is no "destroy" method, so using this plug-in in an environment where you're going to continually replace content via AJAX is not ideal. You'll need to manually do the cleanup (although you won't be able to remove all references w/out modding the source code and creating your own this.destroy method.)

Comments for this entry have been disabled.