r803 - in branches/1.7: . tests/visual

r803 - in branches/1.7: . tests/visual


Author: paul.bakaus
Date: Thu Oct 16 08:45:00 2008
New Revision: 803
Added:
branches/1.7/tests/visual/keyboard_selection.html
branches/1.7/ui.keyboardSelectable.js
Log:
1.7: experimental version of keyboard selectables, with multiple
selections, focus, quite sophisticated. Should probably later be merged
with mouse selectables.
Added: branches/1.7/tests/visual/keyboard_selection.html
==============================================================================
--- (empty file)
+++ branches/1.7/tests/visual/keyboard_selection.html    Thu Oct 16 08:45:00
2008
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+    <head>
+        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+        <title>keyboard_selection</title>
+        <script type="text/javascript"
src="../../../../trunk/jquery-1.2.6.js"></script>
+        <script type="text/javascript" src="../../ui.core.js"></script>
+        <script type="text/javascript"
src="../../ui.keyboardSelectable.js"></script>
+
+        <style type="text/css" media="screen">
+            
+            .selected {
+                background: green;
+                font-weight: bold;
+            }
+            
+            .focussed {
+                border: 2px solid red;
+            }
+        
+        </style>
+
+        <script type="text/javascript">
+            
+            $(document).ready(function() {
+
+                $("ul").keyboardSelectable({
+                    
+                    select: function(e, ui) {
+                        console.log(ui.selection);
+                    }
+                    
+                });
+
+            });
+        
+
+        
+        </script>
+
+    </head>
+    <body>
+        
+        <ul tabindex="1">
+            <li>Item 1</li>
+            <li>Item 2</li>    
+            <li>Item 3</li>    
+            <li>Item 4</li>    
+            <li>Item 5</li>
+            <li>Item 6</li>
+            <li>Item 7</li>    
+            <li>Item 8</li>    
+            <li>Item 9</li>    
+            <li>Item 10</li>    
+        </ul>
+        
+    </body>
+</html>
\ No newline at end of file
Added: branches/1.7/ui.keyboardSelectable.js
==============================================================================
--- (empty file)
+++ branches/1.7/ui.keyboardSelectable.js    Thu Oct 16 08:45:00 2008
@@ -0,0 +1,175 @@
+/*
+ * jQuery UI Resizable @VERSION
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ *    ui.core.js
+ */
+(function($) {
+    
+    $.widget('ui.keyboardSelectable', {
+        
+        _init: function() {
+            
+            var self = this;
+            
+            //Set the currentFocus to the first item
+            this.currentFocus = $($('> *', this.element)[0]);
+            
+            this.element
+                .bind('focus.keyboardSelectable', function() {
+                    self.currentFocus.addClass(self.options.focusClass);    
+                })
+                .bind('blur.keyboardSelectable', function() {
+                    self.currentFocus.removeClass(self.options.focusClass);
+                })
+                .bind('keydown.keyboardSelectable', function(e) {
+
+                    if(e.keyCode == $.keyCode.DOWN || e.keyCode == $.keyCode.RIGHT) {
+                        self.selectNext(e);
+                        e.preventDefault();
+                    }
+                        
+                    if(e.keyCode == $.keyCode.UP || e.keyCode == $.keyCode.LEFT) {
+                        self.selectPrevious(e);
+                        e.preventDefault();
+                    }
+
+                });
+            
+        },
+
+        _selection: [],
+        
+        _clearSelection: function() {
+            
+            for (var i = this._selection.length - 1; i >= 0; i--){
+                this._selection[i]
+                    .removeClass(this.options.selectClass)
+                    .data('keyboardSelected', false);
+            };
+            
+            this._selection = [];
+                
+        },
+
+        _addToSelection: function(item) {
+            
+            this._selection.push(item);
+            this.latestSelection = item;
+            item
+                .addClass(this.options.selectClass)
+                .data('keyboardSelected', true);
+            
+        },
+        
+        _removeFromSelection: function(item) {
+
+            for (var i=0; i < this._selection.length; i++) {
+                if(this._selection[i][0] == item[0]) {
+                    this._selection[i]
+                        .removeClass(this.options.selectClass)
+                        .data('keyboardSelected', false);
+                    this._selection.splice(i,1);
+                    break;
+                }
+            };
+
+        },
+        
+        _updateSelection: function(e, dir) {
+
+            if(e.shiftKey && this.options.multiple) {
+
+                if(this.currentFocus.data('keyboardSelected')) {
+                    this._removeFromSelection(this.previousFocus);
+                } else {
+                    
+                    if($('> *', this.element).index(this.latestSelection[0]) > $('> *',
this.element).index(this.currentFocus[0])) {
+                        if(!this.previousFocus.data('keyboardSelected')) {
+                            var i = dir == 'next' ? this.previousFocus.next() :
this.previousFocus;
+                            while(i.length && !i.data('keyboardSelected')) {
+                                this._addToSelection(i);
+                                i = i.next();
+                            }
+                        }
+                    } else {
+                        if(!this.previousFocus.data('keyboardSelected')) {
+                            var i = dir == 'prev' ? this.previousFocus.prev() :
this.previousFocus;
+                            while(i.length && !i.data('keyboardSelected')) {
+                                this._addToSelection(i);
+                                i = i.prev();
+                            }
+                        }
+                    }
+
+                    this._addToSelection(this.currentFocus);
+                    
+                }
+                
+            } else {
+                
+                //If the CTRL or Apple/Win key is pressed, only set focus
+                if(e.ctrlKey || e.metaKey)
+                    return;
+                
+                this._clearSelection();
+                this._addToSelection(this.currentFocus);
+                
+            }
+            
+        },
+        
+        _select: function(e, dir) {
+
+            //Bail if there's no previous/next item
+            if(!this.currentFocus[dir]().length)
+                return;
+            
+            //Set the current selection to the previous/next item
+            this.previousFocus = this.currentFocus;
+            this.currentFocus = this.currentFocus[dir]();
+            
+            this.previousFocus.removeClass(this.options.focusClass);
+            this.currentFocus.addClass(this.options.focusClass);
+
+            //Set and update the selection
+            this._updateSelection(e, dir);
+            
+            //Trigger select event
+            this._trigger('select', e, this._uiHash(e));
+
+        },
+        
+        selectPrevious: function(e) {
+            this._select(e, 'prev');
+        },
+        
+        selectNext: function(e) {
+            this._select(e, 'next');
+        },
+        
+        _uiHash: function(e) {
+            return {
+                previousFocus: this.previousFocus,
+                currentFocus: this.currentFocus,
+                selection: $($.map(this._selection, function(i) { return i[0]; }))
+            };
+        }
+        
+    });
+    
+    $.extend($.ui.keyboardSelectable, {
+        defaults: {
+            multiple: true,
+            selectClass: 'selected',
+            focusClass: 'focussed'
+        }
+    });
+    
+})(jQuery);
\ No newline at end of file