New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

pretty-dropdowns

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pretty-dropdowns - npm Package Compare versions

Comparing version 3.1.3 to 3.3.3

232

dist/js/jquery.prettydropdowns.js
/*!
* jQuery Pretty Dropdowns Plugin v3.1.3 by T. H. Doan (http://thdoan.github.io/pretty-dropdowns/)
* jQuery Pretty Dropdowns Plugin v3.3.3 by T. H. Doan (http://thdoan.github.io/pretty-dropdowns/)
*

@@ -17,5 +17,3 @@ * jQuery Pretty Dropdowns by T. H. Doan is licensed under the MIT License.

}, oOptions);
var nHoverIndex,
nLastIndex,
nTimer,
var $current,
aKeys = [

@@ -25,55 +23,83 @@ '0','1','2','3','4','5','6','7','8','9',,,,,,,,

],
$current,
nHoverIndex,
nLastIndex,
nTimer,
handleKeypress = function(e) {
var $dropdown = $('.prettydropdown > ul.active'),
var $dropdown = $('.prettydropdown > ul.active, .prettydropdown > ul:focus');
if (!$dropdown.length) return;
if (e.which===9) { // Tab
resetDropdown($dropdown[0]);
return;
} else {
// Intercept non-Tab keys only
e.preventDefault();
e.stopPropagation();
}
var $items = $dropdown.children(),
bOpen = $dropdown.hasClass('active'),
nItemsHeight = $dropdown.height()/(oOptions.height-2),
nItemsPerPage = nItemsHeight%1<0.5 ? Math.floor(nItemsHeight) : Math.ceil(nItemsHeight),
sKey;
if (!$dropdown.length) return;
e.preventDefault();
e.stopPropagation();
nHoverIndex = $dropdown.children('li.hover').index();
nLastIndex = $dropdown.children().length-1;
$current = $dropdown.children().eq(nHoverIndex);
nHoverIndex = Math.max(0, $dropdown.children('li.hover').index());
nLastIndex = $items.length-1;
$current = $items.eq(nHoverIndex);
$dropdown.data('lastKeypress', +new Date());
switch (e.which) {
case 13: // Enter
if (!bOpen) toggleHover($current, 1);
$current.click();
return;
break;
case 27: // Esc
resetDropdown($dropdown[0]);
return;
if (bOpen) resetDropdown($dropdown[0]);
break;
case 32: // Space
sKey = ' ';
if (bOpen) {
sKey = ' ';
} else {
toggleHover($current, 1);
$current.click();
}
break;
case 33: // Page Up
toggleHover($current, 0);
toggleHover($dropdown.children().eq(Math.max(nHoverIndex-nItemsPerPage-1, 0)), 1);
return;
if (bOpen) {
toggleHover($current, 0);
toggleHover($items.eq(Math.max(nHoverIndex-nItemsPerPage-1, 0)), 1);
}
break;
case 34: // Page Down
toggleHover($current, 0);
toggleHover($dropdown.children().eq(Math.min(nHoverIndex+nItemsPerPage-1, nLastIndex)), 1);
return;
if (bOpen) {
toggleHover($current, 0);
toggleHover($items.eq(Math.min(nHoverIndex+nItemsPerPage-1, nLastIndex)), 1);
}
break;
case 35: // End
toggleHover($current, 0);
toggleHover($dropdown.children().eq(nLastIndex), 1);
return;
if (bOpen) {
toggleHover($current, 0);
toggleHover($items.eq(nLastIndex), 1);
}
break;
case 36: // Home
toggleHover($current, 0);
toggleHover($dropdown.children().eq(0), 1);
return;
if (bOpen) {
toggleHover($current, 0);
toggleHover($items.eq(0), 1);
}
break;
case 38: // Up
toggleHover($current, 0);
// If not already key-navigated or first item is selected, cycle to the last item;
// else select the previous item
toggleHover(nHoverIndex ? $dropdown.children().eq(nHoverIndex-1) : $dropdown.children().eq(nLastIndex), 1);
return;
if (bOpen) {
toggleHover($current, 0);
// If not already key-navigated or first item is selected, cycle to
// the last item; or else select the previous item
toggleHover(nHoverIndex ? $items.eq(nHoverIndex-1) : $items.eq(nLastIndex), 1);
}
break;
case 40: // Down
toggleHover($current, 0);
// If last item is selected, cycle to the first item;
// else select the next item
toggleHover(nHoverIndex===nLastIndex ? $dropdown.children().eq(0) : $dropdown.children().eq(nHoverIndex+1), 1);
return;
if (bOpen) {
toggleHover($current, 0);
// If last item is selected, cycle to the first item; or else select
// the next item
toggleHover(nHoverIndex===nLastIndex ? $items.eq(0) : $items.eq(nHoverIndex+1), 1);
}
break;
default:
sKey = aKeys[e.which-48];
if (bOpen) sKey = aKeys[e.which-48];
}

@@ -85,7 +111,8 @@ if (sKey) { // Alphanumeric key pressed

$dropdown.removeData('keysPressed');
// NOTE: Windows keyboard repeat delay is 250-1000 ms. See
// https://technet.microsoft.com/en-us/library/cc978658.aspx
}, 300);
// Build index of matches
var aMatches = [],
nCurrentIndex = $current.index(),
$items = $dropdown.children();
nCurrentIndex = $current.index();
$items.each(function(nIndex) {

@@ -110,33 +137,44 @@ if ($(this).text().toLowerCase().indexOf($dropdown.data('keysPressed'))===0) aMatches.push(nIndex);

},
hoverDropdownItem = function(e) {
var $dropdown = $(e.currentTarget);
if ($dropdown[0]===e.target || !$dropdown.hasClass('active') || new Date()-$dropdown.data('lastKeypress')<200) return;
toggleHover($dropdown.children(), 0, 1);
toggleHover($(e.target), 1, 1);
},
resetDropdown = function(o) {
var $dropdown = $(o.currentTarget||o);
// NOTE: Sometimes it's possible for $dropdown to point to the wrong
// element when you quickly hover over another menu. To prevent this, we
// need to check for .active as a backup.
if (!$dropdown.hasClass('active')) $dropdown = $('.prettydropdown > ul.active');
$dropdown.data('hover', false);
clearTimeout(nTimer);
nTimer = setTimeout(function() {
if (!$dropdown.data('hover')) {
if ($dropdown.hasClass('reverse')) $dropdown.prepend($dropdown.children('li:last-child'));
$dropdown.removeClass('active changing reverse').css('height', '');
$dropdown.children().removeClass('hover nohover');
$dropdown.removeData('clicked');
$(window).off('keydown', handleKeypress);
}
if ($dropdown.data('hover')) return;
if ($dropdown.hasClass('reverse')) $dropdown.prepend($dropdown.children('li:last-child'));
$dropdown.removeClass('active reverse').css('height', '');
$dropdown.children().removeClass('hover nohover');
$dropdown.removeData('clicked').attr('aria-expanded', 'false');
}, (o.type==='mouseleave' && !$dropdown.data('clicked')) ? oOptions.hoverIntent : 0);
},
hoverDropdownItem = function(e) {
var $dropdown = $(e.currentTarget);
if (!$dropdown.hasClass('active') || new Date()-$dropdown.data('lastKeypress')<200) return;
toggleHover($dropdown.children(), 0, 1);
toggleHover($(e.target), 1, 1);
selectDropdownItem = function($li) {
var $dropdown = $li.parent(),
$select = $dropdown.parent().find('select');
$dropdown.children('li.selected').removeClass('selected');
$dropdown.prepend($li.addClass('selected')).removeClass('reverse').attr('aria-activedescendant', $li.attr('id'));
// Sync <select> element
$select.children('option[value="' + $li.data('value') +'"]').prop('selected', true);
$select.trigger('change');
},
toggleHover = function($el, bOn, bNoScroll) {
toggleHover = function($li, bOn, bNoScroll) {
if (bOn) {
$el.removeClass('nohover').addClass('hover');
if ($el.length===1 && $current && !bNoScroll) {
$li.removeClass('nohover').addClass('hover');
if ($li.length===1 && $current && !bNoScroll) {
// Ensure items are always in view
var $dropdown = $el.parent(),
var $dropdown = $li.parent(),
nDropdownHeight = $dropdown.outerHeight(),
nItemOffset = $el.offset().top-$dropdown.offset().top-1; // -1px for top border
if ($el.index()===0) {
nItemOffset = $li.offset().top-$dropdown.offset().top-1; // -1px for top border
if ($li.index()===0) {
$dropdown.scrollTop(0);
} else if ($el.index()===nLastIndex) {
} else if ($li.index()===nLastIndex) {
$dropdown.scrollTop($dropdown.children().length*oOptions.height);

@@ -149,3 +187,3 @@ } else {

} else {
$el.removeClass('hover').addClass('nohover');
$li.removeClass('hover').addClass('nohover');
}

@@ -157,30 +195,39 @@ };

return this.each(function() {
var $this = $(this);
if ($this.data('loaded')) return true; // Continue
$this.outerHeight(oOptions.height);
// NOTE: $this.css('margin') returns empty string in Firefox.
// See https://github.com/jquery/jquery/issues/3383
var nWidth = $this.outerWidth(),
var $select = $(this);
if ($select.data('loaded')) return true; // Continue
$select.outerHeight(oOptions.height);
var nCount = 0,
nTimestamp = +new Date(),
nWidth = $select.outerWidth(),
// Height - 2px for borders
sHtml = '<ul' + ($this.attr('title')?' title="'+$this.attr('title')+'"':'') + ' style="max-height:' + (oOptions.height-2) + 'px;margin:'
+ $this.css('margin-top') + ' '
+ $this.css('margin-right') + ' '
+ $this.css('margin-bottom') + ' '
+ $this.css('margin-left') + ';">',
sHtml = '<ul' + ($select.attr('title')?' title="'+$select.attr('title')+'"':'')
+ ' tabindex="0" role="listbox" aria-activedescendant="item' + nTimestamp
+ '-1" aria-expanded="false" style="max-height:' + (oOptions.height-2) + 'px;margin:'
// NOTE: $select.css('margin') returns empty string in Firefox. See
// https://github.com/jquery/jquery/issues/3383
+ $select.css('margin-top') + ' '
+ $select.css('margin-right') + ' '
+ $select.css('margin-bottom') + ' '
+ $select.css('margin-left') + ';">',
renderItem = function(el, sClass) {
return '<li data-value="' + el.value + '"'
return '<li id="item' + nTimestamp + '-' + nCount
+ '" data-value="' + el.value + '"'
+ (el.title ? ' title="' + el.title + '"' : '')
+ ' role="option"'
+ (sClass ? ' class="' + sClass + '"' : '')
+ ((oOptions.height!==50) ? ' style="height:' + (oOptions.height-2) + 'px;line-height:' + (oOptions.height-2) + 'px"' : '')
+ ((oOptions.height!==50) ? ' style="height:' + (oOptions.height-2)
+ 'px;line-height:' + (oOptions.height-2) + 'px"' : '')
+ '>' + el.text + '</li>';
};
$this.children('option:selected').each(function() {
$select.children('option:selected').each(function() {
++nCount;
sHtml += renderItem(this, 'selected');
});
$this.children('option:not(:selected)').each(function() {
$select.children('option:not(:selected)').each(function() {
++nCount;
sHtml += renderItem(this);
});
sHtml += '</ul>';
$this.css('visibility', 'hidden').wrap('<div class="prettydropdown ' + oOptions.customClass + ' loading"></div>').before(sHtml).data('loaded', true);
var $dropdown = $this.parent().children('ul'),
$select.css('visibility', 'hidden').wrap('<div class="prettydropdown ' + oOptions.customClass + ' loading"></div>').before(sHtml).data('loaded', true);
var $dropdown = $select.parent().children('ul'),
nWidth = $dropdown.outerWidth(true),

@@ -204,12 +251,6 @@ nOuterWidth;

// is a scrollbar.
$dropdown.children('li').width(nWidth);
$dropdown.children('li').css('width', $dropdown.children('li').css('width')).click(function() {
var $li = $(this);
$dropdown.children().width(nWidth).css('width', $dropdown.children().css('width')).click(function() {
// Only update if different value selected
if ($dropdown.hasClass('active') && $li.data('value')!==$dropdown.children('li.selected').data('value')) {
$dropdown.children('li.selected').removeClass('selected');
$dropdown.prepend($li.addClass('selected')).removeClass('reverse');
// Sync <select> element
$this.children('option[value="' + $li.data('value') +'"]').prop('selected', true);
$this.trigger('change');
if ($dropdown.hasClass('active') && $(this).data('value')!==$dropdown.children('li.selected').data('value')) {
selectDropdownItem($(this));
}

@@ -219,2 +260,8 @@ $dropdown.toggleClass('active');

if ($dropdown.hasClass('active')) {
// Ensure the selected item is in view
$dropdown.scrollTop(0);
// Close any other open menus
if ($('.prettydropdown > ul.active').length>1) {
resetDropdown($('.prettydropdown > ul.active').not($dropdown)[0]);
}
var nWinHeight = window.innerHeight,

@@ -237,5 +284,5 @@ nOffsetTop = $dropdown.offset().top,

}
$(window).on('keydown', handleKeypress);
$dropdown.attr('aria-expanded', 'true');
} else {
$dropdown.addClass('changing').data('clicked', true); // Prevent FOUC
$dropdown.data('clicked', true);
resetDropdown($dropdown[0]);

@@ -245,2 +292,9 @@ }

$dropdown.on({
focusin: function() {
// Unregister any existing handlers first to prevent duplicate firings
$(window).off('keydown', handleKeypress).on('keydown', handleKeypress);
},
focusout: function() {
$(window).off('keydown', handleKeypress);
},
mouseenter: function() {

@@ -247,0 +301,0 @@ $dropdown.data('hover', true);

{
"name": "pretty-dropdowns",
"version": "3.1.3",
"version": "3.3.3",
"description": "A simple, lightweight jQuery plugin to create stylized drop-down menus.",

@@ -5,0 +5,0 @@ "keywords": [

# jQuery Pretty Dropdowns
Pretty Dropdowns is a simple, lightweight jQuery plugin that converts `<select>` drop-down menus into "pretty" menus that you can style using CSS. Full keyboard navigation is supported (you can go directly to a menu option by typing its text). As an extra bonus, it does its best to keep the menu options within the viewport.
Pretty Dropdowns is a simple, lightweight jQuery plugin that converts `<select>` drop-down menus into "pretty" menus that you can style using CSS.
### Features:
- Two arrow styles and sizes to choose from (or add your own style)
- Full keyboard navigation support (you can even go directly to a menu item by typing its text)
- Accessible (it plays nicely with screen readers)
- Sensible (when you open the menu it does its best to keep the menu items within the viewport)
**[See a demo &raquo;](https://thdoan.github.io/pretty-dropdowns/demo.html)**

@@ -51,2 +58,18 @@

## Keyboard Navigation
Key | Description
------- | -----------
`Tab` | Put focus on the next drop-down menu. If a menu is open, it will automatically close.
`Shift`+`Tab` | Put focus on the previous drop-down menu. If a menu is open, it will automatically close.
`Enter` | Open the drop-down menu that is in focus. If it is already open, then select the highlighted item.
`Esc` | Close the drop-down menu.
`Home` | Jump to the first item in the drop-down menu.
`End` | Jump to the last item in the drop-down menu.
`PgUp` | Go to the previous page of items. If there is no scrollbar, then this is the same as `Home`.
`PgDn` | Go to the next page of items. If there is no scrollbar, then this is the same as `End`.
`Up` | Highlight the previous item in the drop-down menu.
`Down` | Highlight the next item in the drop-down menu.
`A`-`Z`<br>`0`-`9`<br>`Space` | If the drop-down menu is open, jump to the first item matching the key(s) pressed. Every time you press a key it will cycle through the matching items. **Hint:** if you type fast enough, it will try to find a match for everything you typed instead of just the first character. If the menu is closed and in focus, `Space` opens the menu (same as `Enter`).
## Installation

@@ -53,0 +76,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc