]> source.dussan.org Git - jquery-ui.git/commitdiff
improved: full disable / enable functionality for select, option, optgroup; see:...
authorFelix Nagel <info@felixnagel.com>
Sun, 20 Mar 2011 18:37:26 +0000 (19:37 +0100)
committerFelix Nagel <info@felixnagel.com>
Sun, 20 Mar 2011 22:40:17 +0000 (23:40 +0100)
demos/selectmenu/disable_enable.html
themes/base/jquery.ui.selectmenu.css
ui/jquery.ui.selectmenu.js

index 0c0704bc550f092f156c5c6bccd05d6a3ea50db5..ac49e9e3b8425f30b8fb5b96f763fa3f3a1369db 100644 (file)
@@ -16,7 +16,7 @@
        <style type="text/css">
                /*demo styles*/
                body {font-size: 62.5%; font-family:"Verdana",sans-serif; }
-               fieldset { border:0; margin: 50px 0 0 0;}       
+               fieldset { border:0; margin: 30px 0 0 0;}       
                label,select,.ui-select-menu { float: left; margin-right: 10px; }
                select { width: 200px; }
                
@@ -32,7 +32,7 @@
        </style>
        <script type="text/javascript"> 
                $(function(){           
-                       
+               
                        // please note that option.event is always passed as a string, so do not test for true or 1 with if (options.value)
                        // see this issue for more information http://github.com/fnagel/jquery-ui/issues#issue/12
                        var speedA_depends = $('select#speedA_depends').selectmenu();           
                                speedB.selectmenu("disable");
                        });                     
                        
+                       var speedB2 = $('select#speedB2').selectmenu();                 
+                       $("#optionSwitch").toggle(
+                               function(){
+                                       speedB2.selectmenu("disable", 2);
+                               }, 
+                               function(){
+                                       speedB2.selectmenu("enable", 2);
+                               }
+                       );                      
+                       
                        var speedC = $('select#speedC').selectmenu();
                        
-                       var speedD = $('select#speedD').selectmenu();                   
+                       var speedD = $('select#speedD').selectmenu();           
+
+                       var speedD2 = $('select#speedD2').selectmenu();                         
+                       $("#optgroupSwitch").toggle(
+                               function(){
+                                       speedD2.selectmenu("disable", 1, "optgroup");
+                               }, 
+                               function(){
+                                       speedD2.selectmenu("enable", 1, "optgroup");
+                               }
+                       );                      
+
+                       var speedD3 = $('select#speedD3').selectmenu();         
+                       
+                       $('select').show();
                });             
                
        </script>
@@ -64,6 +88,8 @@
 <body>
        <h2>Disable / Enable Testing</h2>
        <form action="#">
+               <h3>API</h3>
+               <h4>selectmenu</h4>
                <label for="speedA">Disabled by select callback (does not change original select)</label>
                <fieldset>
                        <select name="speedA" id="speedA">
                                <option value="Medium">Medium</option>
                                <option value="Fast">Fast</option>
                        </select>
-               </fieldset>
-               
-               
+               </fieldset>             
                <fieldset>
-                       <label for="speedB">Disble by links</label>
+                       <label for="speedB">Disble whole select</label>
                        <select name="speedB" id="speedB">
                                <option value="Slower" selected="selected">Slower</option>
                                <option value="Slow">Slow</option>
                        <a href="#nogo" id="on">on</a> | <a href="#nogo" id="off">off</a><br />
                </fieldset>
                
+               <h4>option</h4>
+               <fieldset>
+                       <label for="speedD2">Disabled option by HTML</label>
+                       <select name="speedB2" id="speedB2">
+                               <option value="Slower" selected="selected">Slower</option>
+                               <option value="Slow">Slow</option>
+                               <option value="Medium">Medium</option>
+                               <option value="Fast">Fast</option>
+                               <option value="Faster">Faster</option>
+                       </select>
+                       Disable option 'Medium' <a href="#nogo" id="optionSwitch">on / off</a><br />
+               </fieldset>
+               
+               <h4>optgroup</h4>                               
+               <fieldset>
+                       <label for="speedD2">Disabled optgroup by HTML</label>
+                       <select name="speedD2" id="speedD2">
+                               <optgroup label="scripts">
+                                       <option value="jquery">jQuery.js</option>
+                                       <option value="jqueryui">ui.jQuery.js</option>
+                               </optgroup>
+                               <optgroup label="Label with space">
+                                       <option value="somefile">Some unknown file</option>
+                                       <option value="someotherfile">Some other file</option>
+                               </optgroup>
+                       </select>
+                       Disable option 'Label with space' <a href="#nogo" id="optgroupSwitch">on / off</a><br />
+               </fieldset>
+               
+               
+               <h3>HTML</h3>
                <fieldset>
                        <label for="speedC">Disabled by HTML (initial)</label>
                        <select disabled="disabled" name="speedC" id="speedC">
                </fieldset>
                                
                <fieldset>
-                       <label for="speedD">Disabled option by HTML (initial, does not work)</label>
+                       <label for="speedD">Disabled option by HTML</label>
                        <select name="speedD" id="speedD">
                                <option value="Slower" selected="selected">Slower</option>
                                <option value="Slow">Slow</option>
                                <option value="Faster">Faster</option>
                        </select>
                </fieldset>
+                               
+               <fieldset>
+                       <label for="speedD3">Disabled optgroup by HTML</label>
+                       <select name="speedD3" id="speedD3">
+                               <optgroup label="scripts">
+                                       <option value="jquery">jQuery.js</option>
+                                       <option value="jqueryui">ui.jQuery.js</option>
+                               </optgroup>
+                               <optgroup disabled="disabled" label="Label with space">
+                                       <option value="somefile">Some unknown file</option>
+                                       <option value="someotherfile">Some other file</option>
+                               </optgroup>
+                       </select>
+               </fieldset>
        </form>
 </body>
 </html>
\ No newline at end of file
index 318941d6ee666cde500c85fe9e802bc7d0bfa950..8a54f0a1b88254a92ce4b644f87ca35b94aa4d4e 100644 (file)
@@ -8,6 +8,7 @@
 .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: .405em 1em; outline:none; text-decoration:none; }
+.ui-selectmenu-menu li.ui-state-disabled a { cursor: default; }
 .ui-selectmenu-menu li.ui-selectmenu-hasIcon a,
 .ui-selectmenu-hasIcon .ui-selectmenu-status { padding-left: 20px; position: relative; margin-left: 5px; }
 .ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; }
index a1ad54b4c3d8439dc3e56d309234d992d0598a16..e06570c0af42e83418eab10e0f0f141a34c7629f 100644 (file)
@@ -245,6 +245,7 @@ $.widget("ui.selectmenu", {
                                        value: $(this).attr('value'),
                                        text: self._formatText($(this).text()),
                                        selected: $(this).attr('selected'),
+                                       disabled: $(this).attr('disabled'),
                                        classes: $(this).attr('class'),
                                        typeahead: $(this).attr('typeahead'),
                                        parentOptGroup: $(this).parent('optgroup'),
@@ -260,20 +261,20 @@ $.widget("ui.selectmenu", {
 
                // write li's
                for (var i = 0; i < selectOptionData.length; i++) {
-                                       var thisLi = $('<li role="presentation"><a href="#" tabindex="-1" role="option" aria-selected="false"'+ (selectOptionData[i].typeahead ? ' typeahead="' + selectOptionData[i].typeahead + '"' : '' ) + '>'+ selectOptionData[i].text +'</a></li>')
+                               var thisLi = $('<li role="presentation"' + (selectOptionData[i].disabled ? ' class="' + this.namespace + '-state-disabled' + '"' : '' ) + '><a href="#" tabindex="-1" role="option"' + (selectOptionData[i].disabled ? ' aria-disabled="true"' : '' ) + ' aria-selected="false"' + (selectOptionData[i].typeahead ? ' typeahead="' + selectOptionData[i].typeahead + '"' : '' ) + '>'+ selectOptionData[i].text +'</a></li>')
                                .data('index', i)
                                .addClass(selectOptionData[i].classes)
                                .data('optionClasses', selectOptionData[i].classes || '')
                                .bind("mouseup.selectmenu", function(event) {
-                                               if (self._safemouseup) {
-                                                       var changed = $(this).data('index') != self._selectedIndex();
-                                                       self.index($(this).data('index'));
-                                                       self.select(event);
-                                                       if (changed) {
-                                                               self.change(event);
-                                                       }
-                                                       self.close(event, true);
+                                       if (self._safemouseup && !self._disabled(event.currentTarget) && !self._disabled($( event.currentTarget ).parents( "ul>li." + self.widgetBaseClass + "-group " )) ) {
+                                               var changed = $(this).data('index') != self._selectedIndex();
+                                               self.index($(this).data('index'));
+                                               self.select(event);
+                                               if (changed) {
+                                                       self.change(event);
                                                }
+                                               self.close(event, true);
+                                       }
                                        return false;
                                })
                                .bind("click.selectmenu", function() {
@@ -297,7 +298,7 @@ $.widget("ui.selectmenu", {
                                if (this.list.find( 'li.' + optGroupName ).length ) {
                                        this.list.find( 'li.' + optGroupName + ':last ul' ).append( thisLi );
                                } else {
-                                       $(' <li role="presentation" class="' + self.widgetBaseClass + '-group ' + optGroupName + '"><span class="' + self.widgetBaseClass + '-group-label">' + selectOptionData[i].parentOptGroup.attr('label') + '</span><ul></ul></li> ')
+                                       $(' <li role="presentation" class="' + self.widgetBaseClass + '-group ' + optGroupName + (selectOptionData[i].parentOptGroup.attr("disabled") ? ' ' + this.namespace + '-state-disabled" aria-disabled="true"' : '"' ) + '><span class="' + self.widgetBaseClass + '-group-label">' + selectOptionData[i].parentOptGroup.attr('label') + '</span><ul></ul></li> ')
                                                .appendTo( this.list )
                                                .find( 'ul' )
                                                .append( thisLi );
@@ -594,10 +595,24 @@ $.widget("ui.selectmenu", {
                if (newIndex > this._optionLis.size() - 1) {
                        newIndex = this._optionLis.size() - 1;
                }
+               
+               //Occurs when a full loop has been made
+               if (newIndex === recIndex) { 
+                       return false; 
+               }
+               
                var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
 
                this._focusedOptionLi().find('a:eq(0)').attr('id', '');
-               this._optionLis.eq(newIndex).find('a:eq(0)').attr('id', activeID).focus();
+               
+               if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) {
+                       // if option at newIndex is disabled, call _moveFocus, incrementing amt by one
+                       (amt > 0) ? amt++ : amt--;
+                       this._moveFocus(amt, newIndex);
+               } else {
+                       this._optionLis.eq(newIndex).find('a:eq(0)').attr('id',activeID).focus();
+               }
+               
                this.list.attr('aria-activedescendant', activeID);
        },
 
@@ -609,6 +624,7 @@ $.widget("ui.selectmenu", {
 
        _setOption: function(key, value) {
                this.options[key] = value;
+               // set 
                if (key == 'disabled') {
                        this.close();
                        this.element
@@ -620,10 +636,81 @@ $.widget("ui.selectmenu", {
                }
        },
 
+       disable: function(index, type){
+                       //if options is not provided, call the parents disable function
+                       if ( !index ) { 
+                               this._setOption( 'disabled', true );
+                       } else {
+                               if ( type == "optgroup" ) {
+                                       this._disableOptgroup(index);
+                               } else {
+                                       this._disableOption(index);
+                               }
+                       }
+       },
+
+       enable: function(index, type) {
+                       //if options is not provided, call the parents enable function
+                       if ( !index ) {
+                               this._setOption('disabled', false);
+                       } else {
+                               if ( type == "optgroup" ) {
+                                       this._enableOptgroup(index);
+                               } else {
+                                       this._enableOption(index);
+                               }
+                       }
+       },
+
+       _disabled: function(elem) {
+                       return $(elem).hasClass( this.namespace + '-state-disabled' );
+       },
+       
+
+       _disableOption: function(index) {
+                       var optionElem = this._optionLis.eq(index);
+                       if (optionElem) {
+                               optionElem.addClass(this.namespace + '-state-disabled')
+                                       .find("a").attr("aria-disabled", true);
+                               this.element.find("option").eq(index).attr("disabled", "disabled");
+                       }
+       },
+
+       _enableOption: function(index) {
+                       var optionElem = this._optionLis.eq(index);
+                       if (optionElem) {
+                               optionElem.removeClass( this.namespace + '-state-disabled' )
+                                       .find("a").attr("aria-disabled", false);
+                               this.element.find("option").eq(index).removeAttr("disabled");
+                       }
+       },
+
+       _disableOptgroup: function(index) {             
+                       var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
+                       if (optGroupElem) {
+                               optGroupElem.addClass(this.namespace + '-state-disabled')
+                                       .attr("aria-disabled", true);
+                               this.element.find("optgroup").eq(index).attr("disabled", "disabled");
+                       }
+       },
+
+       _enableOptgroup: function(index) {              
+                       var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
+                       if (optGroupElem) {
+                               optGroupElem.removeClass(this.namespace + '-state-disabled')
+                                       .attr("aria-disabled", false);
+                               this.element.find("optgroup").eq(index).removeAttr("disabled");
+                       }
+       },
+       
        index: function(newValue) {
                if (arguments.length) {
-                       this.element[0].selectedIndex = newValue;
-                       this._refreshValue();
+                       if (!this._disabled($(this._optionLis[newValue]))) {
+                               this.element[0].selectedIndex = newValue;
+                               this._refreshValue();
+                       } else {
+                               return false;
+                       }
                } else {
                        return this._selectedIndex();
                }