r2703 - New plugin: selectmenu
Author: scottjehl
Date: Thu Jun 11 10:39:13 2009
New Revision: 2703
Added:
branches/labs/ui-selectmenu/
branches/labs/ui-selectmenu/index.html (contents, props changed)
branches/labs/ui-selectmenu/ui.selectmenu.css (contents, props changed)
branches/labs/ui-selectmenu/ui.selectmenu.js (contents, props changed)
Log:
New plugin: selectmenu
For custom select elements
Added: branches/labs/ui-selectmenu/index.html
==============================================================================
--- (empty file)
+++ branches/labs/ui-selectmenu/index.html Thu Jun 11 10:39:13 2009
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>Demo Page for jQuery UI selectmenu</title>
+ <link rel="Stylesheet"
href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-darkness/jquery-ui.css"
type="text/css" />
+ <link rel="Stylesheet" href="ui.selectmenu.css" type="text/css" />
+ <script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
+ <script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
+ <script type="text/javascript" src="ui.selectmenu.js"></script>
+ <style type="text/css">
+ /*demo styles*/
+ body {font-size: 62.5%; font-family:"Verdana",sans-serif; margin: 100px;}
+ fieldset { border:0; display: block; margin-bottom: 40px;}
+ label,select,.ui-select-menu { float: left; margin-right: 10px; }
+ select { width: 200px; }
+ </style>
+ <script type="text/javascript">
+
+
+ $(function(){
+
+ $('select#speedA').selectmenu();
+
+ $('select#speedB').selectmenu({
+ width: 300,
+ format: addressFormatting
+ });
+
+ $('select#speedC').selectmenu({style:'dropdown'});
+
+ $('select#speedD').selectmenu({
+ style:'dropdown',
+ menuWidth: 400,
+ format: addressFormatting
+ });
+
+ $('<a href="#">Destroy Menus</a>
')
+ .appendTo('body')
+ .click(function(){
+ $('select').selectmenu('destroy');
+ });
+
+
+ });
+ //format options
+ var addressFormatting = [
+ {find:/^([^\-]+) \- /g, rep: '<span
class="ui-selectmenu-item-header">$1</span>'},
+ {find:/([^\|><]+) \| /g, rep: '<span
class="ui-selectmenu-item-content">$1</span>'},
+ {find:/([^\|><\(\)]+) (\()/g, rep: '<span
class="ui-selectmenu-item-content">$1</span>$2'},
+ {find:/([^\|><\(\)]+)$/g, rep: '<span
class="ui-selectmenu-item-content">$1</span>'},
+ {find:/(\([^\|><]+\))$/g, rep: '<span
class="ui-selectmenu-item-footer">$1</span>'}
+ ];
+
+
+ </script>
+ <script type="text/javascript"
src="http://ui.jquery.com/applications/themeroller/themeswitchertool/"></script>
+<script type="text/javascript"> $(function(){ $('<div style="position:
absolute; top: 20px; left: 20px;" />').appendTo('body').themeswitcher();
}); </script>
+</head>
+<body>
+ <form action="#">
+ <h2>Default: "popup" Style
(<code>$('select#speedA').selectmenu();</code>)</h2>
+ <fieldset>
+ <label for="speedA">Select a Speed:</label>
+ <select name="speedA" id="speedA">
+ <option value="Slower" class="whoo">Slower</option>
+ <option value="Slow">Slow</option>
+ <option value="Medium" selected="selected">Medium</option>
+ <option value="Fast">Fast</option>
+ <option value="Faster">Faster</option>
+ </select>
+ </fieldset>
+
+ <h2>Same with option text formatting</h2>
+ <fieldset>
+ <label for="speedB">Select an Address:</label>
+ <select name="speedB" id="speedB">
+ <option>John Doe - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ <option selected="selected">Jane Doe - 78 West Main St Apt 3A |
Bloomsburg, PA 12345 (footer text)</option>
+ <option>Joseph Doe - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ <option>Mad Doe Kiiid - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ </select>
+ </fieldset>
+
+ <h2>"dropdown" Style</h2>
+ <fieldset>
+ <label for="speedC">Select a Speed:</label>
+ <select name="speedC" id="speedC">
+ <option value="Slower" class="whoo">Slower</option>
+ <option value="Slow">Slow</option>
+ <option value="Medium" selected="selected">Medium</option>
+ <option value="Fast">Fast</option>
+ <option value="Faster">Faster</option>
+ </select>
+ </fieldset>
+
+
+ <h2>"dropdown" Style with menuWidth wider than menu and text
formatting</h2>
+ <fieldset>
+ <label for="speedD">Select an Address:</label>
+ <select name="speedD" id="speedD">
+ <option>John Doe - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ <option>Jane Doe - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ <option selected="selected">Joseph Doe - 78 West Main St Apt 3A |
Bloomsburg, PA 12345 (footer text)</option>
+ <option>Mad Doe Kiiid - 78 West Main St Apt 3A | Bloomsburg, PA 12345
(footer text)</option>
+ </select>
+ </fieldset>
+
+ </form>
+</body>
+</html>
\ No newline at end of file
Added: branches/labs/ui-selectmenu/ui.selectmenu.css
==============================================================================
--- (empty file)
+++ branches/labs/ui-selectmenu/ui.selectmenu.css Thu Jun 11 10:39:13 2009
@@ -0,0 +1,25 @@
+ /*
+ * jQuery UI selectmenu
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+
+.ui-selectmenu { display: block; position:relative; height:2em;
text-decoration: none; overflow:hidden;}
+.ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top:
50%; }
+.ui-selectmenu-menu { padding:0; margin:0; list-style:none;
position:absolute; visibility: hidden; }
+.ui-selectmenu-open { visibility: visible; }
+.ui-selectmenu-menu-popup { margin-top: -1px; }
+.ui-selectmenu-menu-dropdown { }
+.ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top:
1px dotted transparent; border-bottom: 1px dotted transparent;
border-right-width: 0 !important; border-left-width: 0 !important;
font-weight: normal !important; }
+.ui-selectmenu-menu li a,.ui-selectmenu-status {line-height: 1.4em;
display:block; padding:.3em 1em; outline:none; text-decoration:none; }
+.ui-selectmenu-status { line-height: 1.4em; }
+.ui-selectmenu-open li.ui-selectmenu-item-focus a { }
+.ui-selectmenu-open li.ui-selectmenu-item-selected { }
+.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block;
margin-bottom: .2em; }
+.ui-selectmenu-menu li .ui-selectmenu-item-header { font-weight: bold; }
+.ui-selectmenu-menu li .ui-selectmenu-item-content { }
+.ui-selectmenu-menu li .ui-selectmenu-item-footer { opacity: .8; }
\ No newline at end of file
Added: branches/labs/ui-selectmenu/ui.selectmenu.js
==============================================================================
--- (empty file)
+++ branches/labs/ui-selectmenu/ui.selectmenu.js Thu Jun 11 10:39:13 2009
@@ -0,0 +1,371 @@
+ /*
+ * jQuery UI selectmenu
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+
+(function($) {
+
+$.widget("ui.selectmenu", $.extend({}, $.ui.mouse, {
+ _init: function() {
+ var self = this, o = this.options;
+ var that = this;
+ this._mouseInit();
+
+ //quick array of button and menu id's
+ this.ids = this._genId();
+
+ //create menu button wrapper
+ this.newelement = $('<a class="ui-selectmenu ui-widget ui-state-default
ui-corner-all" id="'+this.ids[0]+'" href="#" aria-haspopup="true"
aria-owns="'+this.ids[1]+'"></a>')
+ .insertAfter(this.element);
+
+ //transfer classes to selectmenu
+ if(o.transferClasses){
+ var transferClasses = this.element.attr('class') || '';
+ this.newelement.addClass(transferClasses);
+ }
+
+ //transfer tabindex
+ var tabindex = this.element.attr('tabindex') || '0';
+ this.newelement.attr('tabindex', tabindex);
+
+
+ //menu icon
+ this.selectmenuIcon = $('<span class="ui-selectmenu-icon
ui-icon"></span>')
+ .prependTo(this.newelement)
+ .addClass( (o.style
== "popup")? 'ui-icon-triangle-2-n-s' : 'ui-icon-triangle-1-s' );
+
+
+ //make associated form label trigger focus
+ $('label[for='+this.element.attr('id')+']')
+ .click(function(){
+ that.newelement.focus();
+ return false;
+ });
+
+ //click toggle for menu visibility
+ this.newelement
+ .bind('click', function(){
+ that._closeOthers();
+ that._toggle();
+ return false;
+ })
+ .keydown(function(event){
+ var ret = true;
+ switch (event.keyCode) {
+ case $.ui.keyCode.ENTER:
+ case $.ui.keyCode.SPACE:
+ ret = false;
+ that._closeOthers();
+ that._toggle();
+ break;
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.LEFT:
+ //trigger click event on previous (should be abstracted out)
+
that.list.find('li.ui-selectmenu-item-selected').prev().trigger('mouseup');
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.RIGHT:
+ //trigger click event on next (should be abstracted out)
+
that.list.find('li.ui-selectmenu-item-selected').next().trigger('mouseup');
+ break;
+ }
+ return ret;
+ })
+ .bind('mouseover focus', function(){
$(this).addClass('ui-selectmenu-focus ui-state-hover'); })
+ .bind('mouseout blur', function(){
+ $(this).removeClass('ui-selectmenu-focus ui-state-hover');
+ });
+
+ //document click closes menu
+ $(document).click(function(){
+ that.close();
+ });
+
+ //change event on original selectmenu
+ this.element
+ .click(function(){ this._refreshValue(); })
+ .focus(function(){ this.newelement.focus(); });
+
+
+ //create menu portion, append to body
+ var cornerClass = (o.style == "dropdown")? " ui-corner-bottom" : "
ui-corner-all"
+ this.list = $('<ul class="ui-selectmenu-menu ui-widget
ui-widget-content'+cornerClass+'" role="menu"
aria-labelledby="'+this.ids[0]+'"
id="'+this.ids[1]+'"></ul>').appendTo('body');
+
+ //get selectmenu element option data
+ var s_options = this._selectOptions();
+ var activeClass = (that.options.style == "popup") ? "
ui-state-active" : "";
+ //write li's
+ for(var i in s_options){
+ var thisLi = $('<li><a href="#" tabindex="-1" role="option"
aria-selected="false">'+ s_options[i].text +'</a></li>')
+ .data('index',i)
+ .addClass(s_options[i].classes)
+ .mouseup(function(){
+ that.value($(this).data('index'));
+ })
+ .bind('mouseover focus', function(){
+
$(this).parent().find('.ui-selectmenu-item-selected').addClass(activeClass);
+
$(this).parent().find('.ui-selectmenu-item-focus').removeClass('ui-selectmenu-item-focus
ui-state-hover');
+
$(this).removeClass('ui-state-active').addClass('ui-selectmenu-item-focus
ui-state-hover');
+ })
+ .bind('mouseout blur', function(){
+ if($(this).is('.ui-selectmenu-item-selected')){
$(this).addClass(activeClass); }
+ $(this).removeClass('ui-selectmenu-item-focus ui-state-hover');
+ })
+ .appendTo(this.list);
+ }
+
+ //add corners to top and bottom menu items
+ this.list.find('li:last').addClass("ui-corner-bottom");
+ if(o.style == 'popup'){
+ this.list.find('li:first').addClass("ui-corner-top");
+ }
+
+ //original selectmenu width
+ var selectWidth = this.element.width();
+ //set menu button width
+ this.newelement.width( (o.width) ? o.width : selectWidth);
+ //set menu width to either menuWidth option value, width option value,
or select width
+ if(o.style == 'dropdown'){ this.list.width( (o.menuWidth) ?
o.menuWidth : ((o.width) ? o.width : selectWidth)); }
+ else { this.list.width( (o.menuWidth) ? o.menuWidth : ((o.width) ?
o.width - o.handleWidth : selectWidth - o.handleWidth)); }
+
+ if(this.list.width() > this.newelement.width()){ }
+
+ //transfer menu click to menu button
+ this.list
+ .click(function(){
+ that.newelement.trigger('click'); // (should be abstracted out)
+ return false;
+ })
+ .keydown(function(event){
+ var ret = true;
+
+ switch (event.keyCode) {
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.LEFT:
+ ret = false;
+ if($(event.target).parents('li:eq(0)').prev().size()>0){
+
$(event.target).blur().parents('li:eq(0)').prev().find('a:eq(0)').focus();
+ }
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.RIGHT:
+ ret = false;
+ if($(event.target).parents('li:eq(0)').next().size()>0){
+
$(event.target).blur().parents('li:eq(0)').next().find('a:eq(0)').focus();
+ }
+ break;
+ case $.ui.keyCode.ENTER:
+ case $.ui.keyCode.SPACE:
+ ret = false;
+ that.close();
+ $(event.target).parents('li:eq(0)').trigger('mouseup');
+ break;
+ case $.ui.keyCode.TAB:
+ ret = true;
+ that.close();
+ break;
+ }
+ return ret;
+ });
+
+ //selectmenu style
+ if(o.style == 'dropdown'){
+ this.newelement
+ .addClass("ui-selectmenu-dropdown");
+ this.list
+ .addClass("ui-selectmenu-menu-dropdown");
+ }
+ else {
+ this.newelement
+ .addClass("ui-selectmenu-popup");
+ this.list
+ .addClass("ui-selectmenu-menu-popup");
+ }
+
+ this.newelement.prepend('<span class="ui-selectmenu-status">'+
s_options[this._selectedIndex()].text +'</span>');
+
+ //hide original selectmenu element
+ if(o.hideElement){
+ this.element.hide();
+ }
+
+ //update value
+ if(o.value){ this.value(o.value); }
+ else { this._refreshValue(); }
+ this._setData("value", this._selectedIndex());
+ },
+
+ destroy: function() {
+ this.newelement.remove();
+ this.element.show();
+ this._mouseDestroy();
+ //unbind click on label
+ $('label[for='+this.element.attr('id')+']').unbind('click');
+ },
+
+ _closeOthers: function(){
+ //this needs to be handled better
+
$('.ui-selectmenu-open').not(this.list).removeClass('ui-selectmenu-open');
+ $('.ui-select').not(this.newelement).trigger('blur');
+ },
+
+ _genId: function(type){
+ var num = Math.round(Math.random() * 1000);
+ return [this.element.attr('id') + '_' + 'button' + '_' + num,
this.element.attr('id') + '_' + 'menu' + '_' + num];
+ },
+
+ open: function(){
+ this._refreshPosition();
+ this.newelement.addClass('ui-state-active');
+ this.list
+ .appendTo('body')
+ .addClass('ui-selectmenu-open')
+ .find('li:eq('+ this._selectedIndex() +') a').focus();
+
+ if(this.options.style == "dropdown"){
this.newelement.removeClass('ui-corner-all').addClass('ui-corner-top'); }
+ return this.element;
+ },
+
+ close: function(){
+ &