From 59566e93021eb8ebd3520d6106fcb1aa0e0dcd46 Mon Sep 17 00:00:00 2001 From: Carlos Silva Date: Mon, 19 Mar 2012 15:38:55 -0100 Subject: [PATCH] Initial import --- combobox.css | 76 ++++++++++ combobox.js | 369 ++++++++++++++++++++++++++++++++++++++++++++++ testComboBox.html | 22 +++ 3 files changed, 467 insertions(+) create mode 100644 combobox.css create mode 100644 combobox.js create mode 100644 testComboBox.html diff --git a/combobox.css b/combobox.css new file mode 100644 index 0000000..3d4f69d --- /dev/null +++ b/combobox.css @@ -0,0 +1,76 @@ +.toggle-menu { + font-size: 12px; + border:#989898 1px solid; + display: inline-block; + padding: 5px; + margin: 5px; + border-top-left-radius: 4px 4px; + border-top-right-radius: 4px 4px; + border-bottom-left-radius: 4px 4px; + border-bottom-right-radius: 4px 4px; + cursor: default; + user-select: none; + -khtml-user-select: none; + -o-user-select: none; + -moz-user-select: -moz-none; + -webkit-user-select: none; +} +.toggle-menu-selected { + background: #d8d8d8; /* Old browsers */ + background: -moz-linear-gradient(top, #d8d8d8 0%, #8e8e8e 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#d8d8d8), color-stop(100%,#8e8e8e)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #d8d8d8 0%,#8e8e8e 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #d8d8d8 0%,#8e8e8e 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #d8d8d8 0%,#8e8e8e 100%); /* IE10+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d8d8d8', endColorstr='#8e8e8e',GradientType=0 ); /* IE6-9 */ + background: linear-gradient(top, #d8d8d8 0%,#8e8e8e 100%); /* W3C */ +} +.toggle-menu-collate-right { + border-top-right-radius: 0px 0px; + border-bottom-right-radius: 0px 0px; + margin-right: 0px; +} +.toggle-menu-collate-left { + border-top-left-radius: 0px 0px; + border-bottom-left-radius: 0px 0px; + margin-left: 0px; +} +.toggle-menu .title { + text-align: center; + display: inline-block; +} +.toggle-menu .arrow { + background: url("http://www.freepbx.org/trac/browser/freepbx/trunk/amp_conf/htdocs/recordings/theme/images/arrow-desc.gif?rev=10449&format=raw") no-repeat 50% 50%; + padding: 6px; + margin-left: 5px; + display: none; +} +.toggle-menu div.dropdown { + position: absolute; + border:#999999 1px solid; + background-color:#FFFFFF; + display: none; + box-shadow: 0 0 5px gray; + overflow: auto; + max-height: 100px; +} +.toggle-menu div.dropdown p { + position: relative; + padding: 3px; + margin: 0px; + text-align: left; + -khtml-user-select: none; + -o-user-select: none; + -moz-user-select: -moz-none; + -webkit-user-select: none; +} +.toggle-menu div.dropdown p:hover { + background-color: #D3D3D3; +} +.toggle-menu div.dropdown p.disabled { + color: #B8B8B8 +} +.toggle-menu div.dropdown p.disabled:hover { + background-color: inherit; +} +​ \ No newline at end of file diff --git a/combobox.js b/combobox.js new file mode 100644 index 0000000..c2837c2 --- /dev/null +++ b/combobox.js @@ -0,0 +1,369 @@ +(function($) { + $.fn.getHiddenDimensions = function(includeMargin) { + var $item = this, + props = { position: 'absolute', visibility: 'hidden', display: 'block' }, + dim = { width:0, height:0, innerWidth: 0, innerHeight: 0,outerWidth: 0,outerHeight: 0 }, + $hiddenParents = $item.parents().andSelf().not(':visible'), + includeMargin = includeMargin || false; + + var oldProps = []; + $hiddenParents.each(function() { + var old = {}; + + for ( var name in props ) { + old[ name ] = this.style[ name ]; + this.style[ name ] = props[ name ]; + } + + oldProps.push(old); + }); + + dim.width = $item.width(); + dim.outerWidth = $item.outerWidth(includeMargin); + dim.innerWidth = $item.innerWidth(); + dim.height = $item.height(); + dim.innerHeight = $item.innerHeight(); + dim.outerHeight = $item.outerHeight(includeMargin); + + $hiddenParents.each(function(i) { + var old = oldProps[i]; + for ( var name in props ) { + this.style[ name ] = old[ name ]; + } + }); + + return dim; + }; + + var buttonClickWithItems = function(e) { + var parent = $(this).closest('.toggle-menu'); + var p = parent.position(); + var isVisible = parent.find('.dropdown').is(':visible'); + var dropdown = $(parent).find('.dropdown'); + + $('.toggle-menu .dropdown').hide(); + $('.toggle-menu-selected').removeClass('toggle-menu-selected'); + if (!isVisible) { + parent.addClass('toggle-menu-selected'); + dropdown.show().offset({ + top: p.top + 31, + left: p.left + parseInt(parent.css('margin-left')) + }); + } + + if (!e) var e = window.event; + e.cancelBubble = true; + e.stopPropagation(); + }; + + var buttonMouseDown = function(e) { + $(this).closest('.toggle-menu').addClass('toggle-menu-selected'); + }; + + var buttonMouseUp = function(e) { + $(this).closest('.toggle-menu').removeClass('toggle-menu-selected'); + + // Call the "data-onclick" function + var clickFunction = $(this).data('onclick'); + if (clickFunction) + clickFunction(); + } + + var buttonDragStart = function(e) { + $(this).closest('.toggle-menu').removeClass('toggle-menu-selected'); + } + + var buttonMethods = { + construct: function(options) { + var name = options.Name; + var title = options.Title; + var collateLeft = options.CollateLeft; + var collateRight = options.CollateRight; + var onClick = options.onClick; + var firstTimeOpened = true; + + // Mouse events + $(this).mousedown(buttonMouseDown); + $(this).mouseup(buttonMouseUp); + $(this).bind('dragstart', buttonDragStart); + + // Save the OnClick function + if (onClick) + $(this).data('onclick', onClick); + + // Input that will hold the value + var input = $(''); + + // Create the Button + var button = $('
'); + button.append('
' + title + '
', + '
'); + + // This is the DropDown Box + var dropdown = $(''); + + // Run this code to hide the dropdown box when clicked anywhere on the screen + var oldOnClick = $(document).onclick; + $(document).click(function() { + $('.toggle-menu .dropdown').hide(); + $('.toggle-menu-selected').removeClass('toggle-menu-selected'); + if (oldOnClick != null) + oldOnClick(); + }); + + // Setup the border fade on hover (we need jQuery UI for this) + $(this).mouseenter(function() { + $(this).animate({borderTopColor: '#505050', + borderLeftColor: '#505050', + borderRightColor: '#505050', + borderBottomColor: '#505050' }, + 'fast'); + }); + $(this).mouseleave(function() { + $(this).animate({borderTopColor: '#989898', + borderLeftColor: '#989898', + borderRightColor: '#989898', + borderBottomColor: '#989898' }, + 'fast'); + }); + + // Add everything and call ourselfs as a 'toggle-menu' :) + $(this).append(input, button, dropdown); + $(this).addClass('toggle-menu'); + if (collateLeft == 'yes') + $(this).addClass('toggle-menu-collate-left'); + if (collateRight == 'yes') + $(this).addClass('toggle-menu-collate-right'); + + return this; + }, + + // Add a new item to the dropdown menu + add: function(options) { + var dropdown = $(this).find('.dropdown'); + var items = dropdown.children('p'); + // ComboBoxItem class + function ComboBoxItem(itemOptions) { + var text = itemOptions.Text; + var onClick = itemOptions.onClick; + var selectOnClick = itemOptions.selectOnClick; + + var item = $('

' + text + '

'); + item.click(function(e) { + if ($(this).hasClass('disabled')) return false; + + // Call the "data-onclick" function if we have one + var clickFunction = $(this).data('onClick'); + if (clickFunction) { + var parent = $(this).closest('.toggle-menu'); + parent.children('.dropdown').hide(); + parent.removeClass('toggle-menu-selected'); + + if ($(this).data('selectOnClick')) { + var parent = $(this).closest('.toggle-menu'); + parent.find('input').attr('value', $(this).text()); + parent.find('.title').html($(this).text()); + } + + clickFunction($(this).closest('p').html()); + + return false; + } else { + var parent = $(this).closest('.toggle-menu'); + parent.find('input').attr('value', $(this).text()); + parent.find('.title').html($(this).text()); + } + }); + + // Save the OnClick function + if (onClick) + item.data('onClick', onClick); + + // Store the selectOnClick option + if (selectOnClick) + item.data('selectOnClick', selectOnClick); + + return item; + } + // Add the arrow back if this is the first item + if (items.length == 0) { + $(this).find('.title').css('text-align', 'left'); + $(this).find('.arrow').css('display', 'inline-block'); + + // And add the onclick event + $(this).click(buttonClickWithItems); + $(this).unbind('mousedown'); + $(this).unbind('mouseup'); + $(this).unbind('dragstart'); + } + + var item = new ComboBoxItem(options); + dropdown.append(item); + + var minWidth = $(this).find('.title').width(); + dropdown.children('p').each(function() { + if ($(this).getHiddenDimensions().width > minWidth) + minWidth = $(this).getHiddenDimensions().width; + }); + $(this).find('.title').css('min-width', minWidth + 'px'); + dropdown.css('min-width', ($(this).width() + 20) + 'px'); + }, + + // Deletes a option from the dropdown menu + del: function(index) { + var items = $(this).find('.dropdown p'); + var toDel = items.eq(index); + var title = $(this).find('.title'); + + if (title.html() == toDel.text()) { + title.html(''); + $(this).find('input').attr('value', ''); + } + + // Remove the arrow and make this a simple button if no more items are available + if (items.length == 1) { + $(this).find('.title').css('text-align', 'center'); + $(this).find('.arrow').css('display', 'none'); + + $(this).mousedown(buttonMouseDown); + $(this).mouseup(buttonMouseUp); + $(this).bind('dragstart', buttonDragStart); + $(this).unbind('click'); + } + + toDel.remove(); + }, + + // Clears any entries on the ComboBox + clear: function() { + var nItems = $(this).find('.dropdown').children('p').size(); + var i = 0; + + for (i = 0; i < nItems; i++) { + $(this).ComboBox('del', 0); + } + }, + + // Disables a menu item + disable: function(index) { + var toDis = $(this).find('.dropdown p').eq(index); + var title = $(this).find('.title'); + + if (title.html() == toDis.text()) { + title.html(''); + $(this).find('input').attr('value', ''); + } + + toDis.addClass('disabled'); + }, + + // Enables a menu item + enable: function(index) { + var toEn = $(this).find('.dropdown p').eq(index); + + toEn.removeClass('disabled'); + }, + }; + + $.fn.ComboBox = function(method) { + if (buttonMethods[method]) { + return buttonMethods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return buttonMethods['construct'].apply(this, arguments); + } else { + $.error('Method ' + method + ' doesn\'t exist in jQuery.ComboBox'); + } + }; + + + $('#cb1').ComboBox({ + Name: 'cbo1', + Title: 'Test 1', + CollateLeft: 'no', + CollateRight: 'yes' + }); + $('#cb1').ComboBox('add', { + Text: 'Item 1' + }); + $('#cb1').ComboBox('add', { + Text: 'Item 2' + }); + $('#cb1').ComboBox('add', { + Text: 'Item 3' + }); + $('#cb2').ComboBox({ + Name: 'cbo2', + Title: 'Test 2', + CollateLeft: 'yes', + CollateRight: 'no' + }); + $('#cb2').ComboBox('add', { + Text: 'Item 4' + }); + $('#cb2').ComboBox('add', { + Text: 'Item 5', + onClick: test, + selectOnClick: false + }); + $('#cb2').ComboBox('add', { + Text: 'Item 6', + onClick: test, + selectOnClick: true + }); + $('#cb3').ComboBox({ + Name: 'cbo3', + Title: '', + CollateLeft: 'no', + CollateRight: 'no', + onClick: test + }); + $('#cb3').ComboBox('add', { + Text: 'Item 7' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 8' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); + $('#cb3').ComboBox('add', { + Text: 'Item 9' + }); +})(jQuery); + +function test() { + alert('clicked'); +}; \ No newline at end of file diff --git a/testComboBox.html b/testComboBox.html new file mode 100644 index 0000000..0b1af81 --- /dev/null +++ b/testComboBox.html @@ -0,0 +1,22 @@ + + + + + + + testComboBox + + + + + + +


+ + + + ​ + + +