Problem with jQuery mouseleave firing when container has select box - javascript

I have a two containers -- one is nested inside of another. When I hover over the parent, I want the child container to appear. When I mouseout, I want the child container to fadeout. The problem I'm having is the child container has a form that contains a "select box". When the user selects the select box -- the mouseleave event is accidentally fired.
How can I stop the select box from tripping the mouseleave event?
You can see my working code here: http://jsfiddle.net/rsturim/9TZyh/3/
Here's a summary of my script:
$('#parent-container').live("mouseenter", function () {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0);
}).live("mouseleave", function (e) {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
});
edit: appears fine in WebKit-based browsers. Fails in Firefox and IE7-IE9.

In most cases you should simply be able to check to see if the event target was a select element, and only continue in the case that it wasn't. Seems much cleaner than the accepted solution, and worked well in my case.
I've modified the fiddle: http://jsfiddle.net/Dygerati/uj3ZC/5/
$('#parent-container').live("mouseenter", function() {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0);
}).live("mouseleave", function(e) {
if(e.target.tagName.toLowerCase() != "select") {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
}
});

$('#parent-container').live("mouseenter", function () {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0);
}).live("mouseleave", function (e) {
/* Solution */
if(e.relatedTarget == null) return;
/************/
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
});

Since mouseleave and mouseenter events are non-standard you can get such lags here and there. The only method I can suggest to fix that is using some hacks. Here is http://jsfiddle.net/mPDcu/1/ improved version of you code.
var selectOpened = false;
$('#select-grind-type').click(function(e){
selectOpened = !selectOpened;
e.stopPropagation();
});
$('body').click(function(){
if (selectOpened) {
selectOpened = false;
}
})
$('#parent-container').on("mouseenter", function() {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0);
}).live("mouseleave", function(e) {
if (!selectOpened) {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
}
});

I had the same problem in a project in which I am contributing, and the other answers didn't work fine for me. My tricky solution was to check if the mouse position inside the event object is inside the parent container. Works pretty good!
var layer = $('#parent-container'),
layerPos = {};
$(layer).mouseenter(function () {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0, function(){
layerPos.x = {
min: $(layer).offset().left,
max: $(layer).offset().left + $(layer).width()
};
layerPos.y = {
min: $(layer).offset().top,
max: $(layer).offset().top + $(layer).height()
};
});
})
$(layer).mouseleave(function(e) {
// check if event mouse position is inside parent container
var x_con = e.pageX >= layerPos.x.min && e.pageX <= layerPos.x.max;
var y_con = e.pageY >= layerPos.y.min && e.pageY <= layerPos.y.max;
if ( x_con && y_con ) {
return false;
}
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
});
You can also check the navigator version to avoid this code to execute in browsers that support this functionality like Chrome.

This partly solves the problem.
Unbind the mouseleave event when the select box gains focus and bind again when it loses focus.
http://jsfiddle.net/9TZyh/5/
$('#parent-container').live("mouseenter", function() {
var $this = $(this);
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().fadeTo('slow', 1.0);
}).live("mouseleave",focusOut);
$("#select-grind-type").live("focus",function(){
$('#parent-container').die("mouseleave");
});
$("#select-grind-type").live("focusout change",function(){
$('#parent-container').live("mouseleave",focusOut);
});
function focusOut(e) {
var $this = $(this),
$selectOptionsContainer = $this.find('#child-container');
$selectOptionsContainer.stop().hide();
}

If you don't mind having the fade not working in some old browsers, you could do it with CSS quickly:
#parent-container { }
#child-container {
opacity:0;
-webkit-transition:opacity 1s ease-in;
-moz-transition:opacity 1s ease-in;
}
#parent-container:hover #child-container {{
opacity:1;
-webkit-transition:opacity 1s ease-out;
-moz-transition:opacity 1s ease-out;
}

Those guys give you a working alternative, but it also has some bugs. For example, if you quit the outer box while the combobox is still opened, it won't fade out. I recommend you a much easier alternative that will also fix that bug.
Instead of thinking in the mouseleave event of the inner box, why don't you swap your mind to think in the other way around? I mean, leaving the inner box, also means entering in another container. So you can do outerContainer.mouseenter(function(){ hideInnerBox() }); :-)
Obviously for that purpose innerbox should not be a child of outerbox, even if visually it seems so (css positioning can be used to achieve it)

So I just ran into a similar issue with a <select> nested in a container and came across this question. Here's what I ended up doing.
$("#container").mouseover(function(e){
var t = $(this);
t.addClass('active');
var offset = t.offset();
var xMin = offset.left;
var yMin = offset.top;
var xMax = xMin + t.innerWidth();
var yMax = yMin + t.innerHeight();
t.parent().mousemove(function(e){
if(e.pageX < xMin || e.pageX > xMax-2 || e.pageY < yMin || e.pageY > yMax ){
t.removeClass('active');
// unbind this event
$(this).unbind('mousemove');
}
});
});
Basically, when you mouseover the container, we collect its bounds and start checking whether or not the mouse is over the element. When we know the mouse is gone, we unbind the mousemove listener.
I'd make a jsfiddle for you but its running so slow today!
Hope that helps.

You should only check if the current Element is a descendant of your container.
If so abort the handler.
See: jquery descendant
Example:
ContainerElement.mouseleave(function (e) {
if (ContainerElement.has(e.fromElement).length > 0) return;
// Do your Stuff
});

Related

Use function as an "on" event?

I currently have this function:
function highlightBoxes() {
var windowStart = $(window).scrollTop();
var windowEnd = windowStart + $(window).height();
$('.box').each(function() {
var box = $(this);
var start = box.offset().top;
var end = start + box.height();
if (windowStart <= start && windowEnd >= end) {
box.addClass('active');
} else {
box.removeClass('active');
}
});
}
highlightBoxes();
$(document).scroll(highlightBoxes);
$(window).resize(highlightBoxes);
Which checks if an entire element (in this case .box) is in view (jsfiddle). However, I want to be able to use the function as an on event, so I can use it for many different elements. Something like:
$('.box').on('inview', function () {
if (elementIsInView) {
// make the box red
} else {
// make the box the original color
}
});
How can I do this?
using on means you will need to trigger an event with the same name, a super simple version of this is using document as the message bus like:
$(document).trigger('inview');
Therefore at the point in your code where you have decided that inview should be true, fire an event like the above, at which point the on event will run the function.
Base on the code above, you probably want to move the if statement out of the on event, and in fact run that as a separate function. When elementIsInView returns true, you could fire the inview event.
You could use the hover event.
$(document).on('hover','.box', function () {
if (elementIsInView) {
// make the box red
} else {
// make the box the original color
}
});
If am not clear with your answer let me know.
click ,hover ,drag all are events. Event is a action, apply from user. Function is a declare with javascript.Is not directly running.Its only run after event trigger.Event are declared by w3c
I think you need something like that:
Assign function with button click.Its works from button click event.
$('button').on('click',hello)
function hello(){
console.log('button Clicked')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button >hi</button>
or
$('button').on('click',function hello(){
console.log('button Clicked')
})
For your code do like this
$('.box').on('click', function inview() {
if (elementIsInView) {
// make the box red
} else {
// make the box the original color
}
});
try this:
function checkElementToBeInView(elem, callback) {
$(elem).each(function() {
var element = $(this);
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = element.offset().top;
var elemBottom = elemTop + element.height();
var isInView = ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
callback(element, isInView);
});
}
$(window).on("load resize scroll", function(e) {
checkElementToBeInView(".box", function(elem, isInView) {
if (isInView)
elem.addClass('active');
else
elem.removeClass('active');
});

How can I use variables only once with 'on mouseenter' and 'on mouseleave'?

I have multiple objects with different sizes that I want each to display additional box on mouseenter and hide on mouseleave. I have a jquery script that does it perfectly, my only concern is that I am repeating variables twice and something tells me that this can be done without repeating myself.
Problem is they both are strongly based on $(this) core element, so I can't make variables global. My guess was that I should put them withing the element container function, right before on mouseenter and on mouseleave are called, but syntax wise I have no idea how to do it. But again, I might be terribly wrong on that.
Here's the code:
$(document).ready(function() {
$('.box-options').hide();
var $boxModule = $('div.box');
$boxModule.on({
mouseenter: function() {
var $this = $(this), // repeat
$options = $this.find('div.options'), // repeat
$optionsBox = $this.find('div.options-box'); // repeat
var boxHeight = $this.height(), // repeat
boxWidth = $this.width(), // repeat
optionsBoxHeight = $optionsBox.outerHeight(); // repeat
if ( // statement referring to variables above }
else { // statement referring to variables above };
$options.fadeIn(200).addClass('shadow').css({"height" : boxHeight + optionsBoxHeight});
$optionsBox.delay(100).fadeIn(200).css({"top" : boxHeight}, 200);
},
mouseleave: function() {
var $this = $(this), // repeat
$options = $this.find('div.options'), // repeat
$optionsBox = $this.find('div.options-box'); // repeat
var boxHeight = $this.height(), // repeat
boxWidth = $this.width(), // repeat
optionsBoxHeight = $optionsBox.outerHeight(); // repeat
$optionsBox.hide().css({"top" : boxHeight});
$options.hide().removeClass('shadow').css({"height" : boxHeight}, 200);
}
});
});
Obviously the code contains more lines, but the important part is variables marked as // repeat. Does anyone know how I can re-structure the code to make variables be written only once?
UPDATE: I updated the code to describe logic better. Just to make it clear, on each page there are also multiple objects with identical classes, structure and size, only difference is content (text) within and id number.
Use hover function and for variables declare them before hovering event like you have done for $boxModule.
Calling
$( selector ).hover( handlerIn, handlerOut )
is shorthand for:
$( selector ).mouseenter( handlerIn ).mouseleave( handlerOut );
I think the solution for repetition in that code would be to create an external function to get some of the information from the element passed as an argument.
For example:
function options($element) {
return $element.find('div.options');
}
The same goes for every other property based on $(this).
Then you can just use your options inside your event handler as such: options($this).fadeIn(200)
Hope this helps to clean your code.
You can declare var outside on event like :
$('div.box').each(function(){
var $this = $(this),
$options = $this.find('div.options'),
$optionsBox = $this.find('div.options-box'),
boxHeight = $this.height();
$this.on({
mouseenter: function() {...}
mouseleave: function() {...}
});
});
How about making a function that return an object that you can use in every handler?
var calcVars = function(){
var $this = $(this),
$options = $this.find('div.options'),
$optionsBox = $this.find('div.options-box');
var boxHeight = $this.height(),
boxWidth = $this.width(),
optionsBoxHeight = $optionsBox.outerHeight();
return {
boxHeight: boxHeight,
//every other variable you need outside
}
$boxModule.on({
firstEvent: function() {
var object = calcVars.call(this);
object.calculatedProperty.doSomething();
//other code
},
secondEvent: function() {
var object = calcVars.call(this);
object.anotherCalculatedProperty.doSomething();
//other code
}
})
or you can do:
$boxModule.on("anEvent anotherEvent", function(event) {
/*
var declarations
*/
var $this = $(this),
//etc..
if(event.type == "anEvent"){
doStuff();
else if(event.type == "anotherEvent"){
doOtherStuff();
}
})

Stop the touchstart performing too quick when scrolling

I'm trying to figure out how to solve the tapped class being assigned to the elements when scrolling, but it's taking effect too quick which I need to delay it a bit when it's actually touched instead of touched while scrolling, this is my code of how it works:
$('div, a, span').filter('[tappable][data-tappable-role]').bind('touchstart', function()
{
var self = $(this);
self.addClass(self.data('tappable-role'));
}).bind('touchend', function()
{
var self = $(this);
self.removeClass(self.data('tappable-role'));
}).bind('click', function()
{
var self = $(this),
goTo = self.data('goto');
if(typeof goTo !== 'undefined')
{
window.location = goTo;
}
});
When scrolling, it will assign the class to the element when I've barely touched it, I want to prevent this from happening unless it's properly touched (not clicked). Although I tried experimenting with the setTimeout, but that doesn't work well as it delays but it will still assign the class later on.
This is how I did it with the setTimeout:
var currentTapped;
$('div, a, span').filter('[tappable][data-tappable-role]').bind('touchstart', function()
{
clearTimeout(currentTapped);
var self = $(this);
var currentTapped = setTimeout(function()
{
self.addClass(self.data('tappable-role'));
}, 60);
}).bind('touchend', function()
{
clearTimeout(currentTapped);
var self = $(this);
self.removeClass(self.data('tappable-role'));
}).bind('click', function()
{
clearTimeout(currentTapped);
var self = $(this),
goTo = self.data('goto');
if(typeof goTo !== 'undefined')
{
window.location = goTo;
}
});
How can I do this the effective way?
Demo #1 (with setTimeout).
Demo #2 (with no setTimeout)
You need to view it on your iPhone/iPod/iPad or an emulator to test the fiddle.
UPDATE:
function nextEvent()
{
$(this).on('touchend', function(e)
{
var self = $(this);
self.addClass(self.data('tappable-role')).off('touchend');
})
.on('touchmove', function(e)
{
var self = $(this);
self.removeClass(self.data('tappable-role')).off('touchend');
})
.click(function()
{
var self = $(this),
goTo = self.data('goto');
if(typeof goTo !== 'undefined')
{
window.location = goTo;
}
});
}
$('div, a, span').filter('[tappable][data-tappable-role]').on('touchstart', this, nextEvent);
Here's how I did it:
Essentially, when you navigate a page you're going to tap or scroll. (Well there are other things like pinch and slide put you can figure them out later)...
So on a tap your 'touchstart' will be followed by a 'touchend'
On a scroll your 'touchstart' will be followed by a 'touchmove'
Using Jq 1.7... on other versions you can use .bind()
function nextEvent() {
//behaviour for end
$(this).on('touchend', function(e){
/* DO STUFF */
$(this).off('touchend');
});
//behaviour for move
$(this).on('touchmove', function(e){
$(this).off('touchend');
});
}
$('div, a, span').filter('[tappable][data-tappable-role]').on('touchstart', this, nextEvent);
Basically, when a 'touchstart' happens, I bind actions to 'touchend' and 'touchmove'.
'Touchend' does whatever I would want a tap to do and then unbinds itself
'Touchmove' basically does nothing except unbind 'touchend'
This way if you tap you get action, if you scroll nothing happens but scrolling..
RESPONSE TO COMMENT: If I understand your comment properly, try this:
function nextEvent() {
var self = $(this);
self.addClass(self.data('tappable-role'))
//behaviour for move
$(this).on('touchmove', function(e){
self.removeClass(self.data('tappable-role'));
});
}
$('div, a, span').filter('[tappable][data-tappable-role]').on('touchstart', this, nextEvent);
Despite this is a relatively old question with a best answer already selected, I want to share my solution.
I achieved this by triggering the events just on click.
$("div, a, span").on("click", function() {
// Your code here
}
Maybe is not the best way to do it, but this worked for me.

JavaScript setTimeout scope issue

var toogleDelay = 500;
var closeTimeout = null;
$(">ul>li", $nav).hover(function () {
var $this = $(this);
if(closeTimeout) {
clearTimeout(closeTimeout);
}
var openMenuCallback = function() {
$this.addClass("hover");
};
window.setTimeout(openMenuCallback, toogleDelay);
}, function () {
var $this = $(this);
var closeMenuCallback = function() {
$this.removeClass("hover");
};
closeTimeout = window.setTimeout(closeMenuCallback, toogleDelay);
});
I use this snippet to open and close a multidropdown-menu and I want the menu to fade in and out with a 0.5s delay. I also added a cleartimeout to the mouseover part of the jquery hover function, so that the menu does not close if somebody (accidently) leaves the menuarea and enters it again within the 0.5s. This all works fine, but I now have the problem, because there is more than just one dropdown, that the closeTimeout of lets say the first dropdown gets cleared, if I move the mouse from the first directly to the second dropdown and I now have both dropdown-elements open. How must I rewrite the code, so that every dropdown has its own closeTimeout and at the same time I am still able to clear the timeout in the mouseover part of the hover function.
thx
sub
You could store the timer's id in the element's data. Something like
var $this = $(this);
var closeMenuCallback = function() {
$this.removeClass("hover");
$this.removeData("timerid");
};
var closeTimeout = window.setTimeout(closeMenuCallback, toogleDelay);
$this.data("timerid", closeTimeout);
and then check it with
var $this = $(this);
var closeTimeout = $this.data("timerid");
if(closeTimeout) {
clearTimeout(closeTimeout);
$this.removeData("timerid");
}
I know this isn't part of the question but I like the CSS approach to this.
http://webdesignerwall.com/tutorials/css3-dropdown-menu
there are a number of examples for this. some multilevel some not.

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.
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();
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);
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.
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');
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.
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
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).
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.
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();
}
The mousedown event is raise before the click event :
first mousedown raise -> set the width to 'auto' (if the state of the dropdown is 'close')
click raise -> store in a var the state of the dropdown : 'open'
We select a value, the second mousedown is raised : nothing to do
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>
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);
});
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
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.

Categories

Resources