Newbie
Newbie

Reputation: 1714

Open Select using Javascript/jQuery?

Is there a way to open a select box using Javascript (and jQuery)?

<select style="width:150px;">
    <option value="1">1</option>
    <option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc arcu nunc, rhoncus ac dignissim at, rhoncus ac tellus.</option>
    <option value="3">3</option>
</select>

I have to open my select, cause of IE bug. All versions of IE (6,7,8) cut my options. As far as I know, there is no CSS bugfix for this. At the moment I try to do the following:

var original_width = 0;
var selected_val = false;

if (jQuery.browser.msie) {
    $('select').click(function(){
        if (selected_val == false){
            if(original_width == 0)
                original_width = $(this).width();

            $(this).css({
                'position' : 'absolute',
                'width' : 'auto'
            });
        }else{
            $(this).css({
                'position' : 'relative',
                'width' : original_width
            });
            selected_val = false;
        }
    });

    $('select').blur(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });

    $('select').blur(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });
            
    $('select').change(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    });

    $('select option').click(function(){
        $(this).css({
            'position' : 'relative',
            'width' : original_width
        });
    
        selected_val = true;
    });

}

But clicking on my select the first time will change the width of the select but I have to click again to open it.

Upvotes: 32

Views: 92154

Answers (13)

fp007
fp007

Reputation: 480

As an alternative you can use the select2 plugin and do the following:

$(element_select).focus(); 
$(element_select).select2('open').trigger('open');

It worked perfectly for me in Firefox version 79.0

Upvotes: 0

Harijs Krūtainis
Harijs Krūtainis

Reputation: 1270

NO jQuery solution.

<SCRIPT>
    function toggleDropdown(element){
        if(element.size == 0) {
            element.size = element.length;
            element.focus();
            }
        else element.size = 0;
        }
</SCRIPT>

Found this here.

Upvotes: 2

joseantgv
joseantgv

Reputation: 2023

Try this:

dropDown = function (elementId) {
    var dropdown = document.getElementById(elementId);
    try {
        showDropdown(dropdown);
    } catch(e) {

    }
    return false;
};

showDropdown = function (element) {
    var event;
    event = document.createEvent('MouseEvents');
    event.initMouseEvent('mousedown', true, true, window);
    element.dispatchEvent(event);
};

Then call the function:

dropDown('elementId');

Upvotes: 4

uesports135
uesports135

Reputation: 1123

Try this:

var myDropDown=$("#myDropDown");
var length = $('#myDropDown> option').length;
//open dropdown
myDropDown.attr('size',length);

and this to close:

//close dropdown
myDropDown.attr('size',0);

Upvotes: 8

Jasbir Singh Sohanpal
Jasbir Singh Sohanpal

Reputation: 181

There is an alternate solution i found for this problem. Just add a theme to your select box like Selectize.js it will convert your select box into ul li html tags but works as select box. You can easily hide show ul li's on jquery events.

Upvotes: -1

Vishal
Vishal

Reputation: 826

you can not open the select list but you can do it by changing the size of theselect list on click or any other event you want

        $("#drpdwn").mousedown(bodyevent);
        function bodyevent()
        {
            console.log("size changed");
            $(this).attr('size',3);
        }
        $("#drpdwn").focus(function()
        {
            //alert("txt  clicked from ");
            var $el = $("#drpdwn");
            var offset = $el.offset();
            var event = jQuery.Event( "mousedown", {
                which: 1,
                pageX: offset.left,
                pageY: offset.top
            });
            $el.trigger(event);
        });

Upvotes: 0

Matt H
Matt H

Reputation: 6532

I know this is pretty old and answered, but this worked for me in Safari and iOS UIWebView - I have it hidden, but want it to show and open when a different button is clicked.

$('#select-id').show().focus().click();

Upvotes: 7

Jni
Jni

Reputation: 172

The mousedown event is raise before the click event :

  1. first mousedown raise -> set the width to 'auto' (if the state of the dropdown is 'close')
  2. click raise -> store in a var the state of the dropdown : 'open'
  3. We select a value, the second mousedown is raised : nothing to do
  4. click raise -> we need to restore the original width of the dropdown and change the state of the var to : 'close'

The blur and change event are needed to close the dropdown if the user clicked outside the dropdown.

Here the complete solution with Brendan's code :

(function ($) {
var open = {}
$.fn.IELongDropDown = function (cln) {
    if (jQuery.browser.msie) { //only IE has problems with long select boxes
        var el = this;
        var id = el.attr('id');
        var margin = 2; //Need to set a margin however the arrow is cut
        var previousWidth = el.width() + margin;
        var divWrapper = "<div style='padding:0;margin:0;overflow:hidden;width:" + previousWidth + "px'></div>";
        el.wrap(divWrapper);
        var newWidth = el.width("auto").width();
        el.width(previousWidth);
        if (newWidth > previousWidth) {
            el.mousedown(function () {
                if (!open[id]) {
                    el.width("auto");
                    el.focus();
                }
            });
            el.click(function () {
                if (!open[id])
                    open[id] = true;
                else {
                    open[id] = false;
                    return el.width(previousWidth);
                }
            });
            el.blur(function () {
                open[id] = false;
                return el.width(previousWidth);
            });
            el.change(function () {
                open[id] = false;
                return el.width(previousWidth);
            });
        }
    }
    return this;
};
})(jQuery);

Call the function :

<script type="text/javascript" language="javascript">
    $(document).ready(function () {
        $('#mydropdownlist').IELongDropDown();
    });
</script>

Upvotes: 0

Yoni
Yoni

Reputation: 10321

I think that you need to return true from your event handlers (click, blur, etc.) so after your handler executes, the browser continues to propagate the event and open the select.

It is similar with href links, if they have an onclick handler and the handler returns false, the link is not followed (the browser stops the event after your handler executes).

EDIT: Based on your comment and answer, it seems that your handler gets the first chance to execute only after the browser decides to open the box.
I suggest that you try the focus event handler, it might get a chance to run earlier than the click handler and perhaps before the browser actually opens the box. It is also more consistent (applies both to mouse and keyboard navigation).

Upvotes: 1

Brendan Kowitz
Brendan Kowitz

Reputation: 1795

First of all, I feel the pain of this limitation in IE - bleh! Just thought I'd also share this as it seems to be working for me. I've taken almost the same approach, but on a per select element. In my case I know which lists could have long data.

Instead of making the select elements absolute, I've kept them inline and wrap them in a DIV with a hidden overflow as appearance needed to be consistent, also it only applies this 'hack' if it is IE and the expanded width is greater than the current width.

To use this for all select boxes you could use something like:

$("select").each(function(){ 
        $(this).IELongDropDown(); 
     });

Or obviously on a per element bases by id. Here's the jquery plugin:

(function($) {
    $.fn.IELongDropDown = function(cln) {
        if (jQuery.browser.msie) { //only IE has problems with long select boxes
            var el = this;
            var previousWidth = el.width();
            var divWrapper = "<div style='padding:0;margin:0;overflow:hidden;width:"+ previousWidth +"px'></div>";
            el.wrap(divWrapper);
            var newWidth = el.width("auto").width();
            el.width(previousWidth);
            if(newWidth > previousWidth) {
                el.bind("mousedown", function(){ return el.width("auto").focus(); }); 
                el.bind("blur", function(){ return el.width(previousWidth); });
                el.bind("change", function(){ return el.width(previousWidth); });
            }
        }
        return this;
    };
})(jQuery);

Hope this helps someone

Upvotes: 1

Newbie
Newbie

Reputation: 1714

Okay, I found another way fixing this problem. Here is the fix:

Please give me feedback! I'm kind of proud on myself ;)

$(document).ready(function() {
    if (jQuery.browser.msie) {
            select_init();
    }
});


function select_init () {
    var selects = $('select');
    for (var i = 0; i < selects.length; i++) {
        _resizeselect.init(selects[i]);
    }
}


var _resizeselect = {
    obj : new Array(),
    init : function (el) {
        this.obj[el] = new resizeselect (el);
    }
}

function resizeselect (el) {

    this.el = el;
    this.p = el.parentNode;
    this.ht = el.parentNode.offsetHeight;
    var obj = this;
    this.set = false;

    el.onmousedown = function () {
        obj.set_select("mousedown");
    }
    el.onblur = function () {
        obj.reset_select("blur");
    }
    el.onchange = function () {
        obj.reset_select("change");
    }

}

resizeselect.prototype.set_select = function (str) {

    if (this.set) {
        this.set = false;
        return;
    }

    this.el.style.width = "auto";
    this.el.style.position = "absolute";
    this.p.style.height = this.ht + "px";
    this.p.style.zIndex = 100;
    this.set = true;
    this.el.focus();
}

resizeselect.prototype.reset_select = function (str) {
    this.el.style.width = "";
    this.el.style.position = "";
    this.p.style.height = "";
    this.p.style.zIndex = 1;
    this.set = false;
    window.focus();
}

Upvotes: 0

jake the snake
jake the snake

Reputation:

Instead of using click, you could use the mousedown handler to capture the mousedown event. mousedown fires before click, so you could call stopPropogation to break the event queue.

Upvotes: 6

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

I prefer to set my CSS in a CSS file and then "addClass" but even so, your code (portion)

   $('select').blur(function(){ 
        $(this).css({ 
            'position' : 'relative', 
            'width' : original_width 
        }); 
    }); 

    $('select').blur(function(){ 
        $(this).css({ 
            'position' : 'relative', 
            'width' : original_width 
        }); 
    }); 

seems to be a duplicate

I would make it:

$('select').blur().css({ 
        'position' : 'relative', 
        'width' : original_width 
}); 

Not sure you really even need the .blur() here what with the .change() event (try taking it out see see if that addresses your issue...I use select often on IE and do not seem to have an issue.

Upvotes: 0

Related Questions