r862 - in branches/experimental: tests/visual/menu ui
Author: paul.bakaus
Date: Tue Nov 4 08:29:57 2008
New Revision: 862
Added:
branches/experimental/ui/ui.core.position.js
Modified:
branches/experimental/tests/visual/menu/menu.html
branches/experimental/ui/ui.menu.js
Log:
menu: implemented context mode, hide all other menus when clicking around,
etc
core(experimental): implemented new fn.position plugin to position any DOM
element
Modified: branches/experimental/tests/visual/menu/menu.html
==============================================================================
--- branches/experimental/tests/visual/menu/menu.html (original)
+++ branches/experimental/tests/visual/menu/menu.html Tue Nov 4 08:29:57
2008
@@ -9,14 +9,28 @@
<script type="text/javascript" src="../../../jquery-1.2.6.js"></script>
<script type="text/javascript" src="../../../ui/ui.core.js"></script>
<script type="text/javascript" src="../../../ui/ui.menu.js"></script>
+ <script src="../../../ui/ui.core.position.js" type="text/javascript"
charset="utf-8"></script>
+
+ <style type="text/css" media="screen">
+
+ body,html {
+ margin: 0;
+ padding: 0;
+ }
+
+ #menu2 {
+ border: 5px solid black;
+ }
+
+ </style>
<script type="text/javascript">
$(document).ready(function() {
- $('#menu1').menu({
- mode: 'static'
- });
+ //$('#menu1').menu({
+ // mode: 'static'
+ //});
$('button').menu({
items: '#items2'
Added: branches/experimental/ui/ui.core.position.js
==============================================================================
--- (empty file)
+++ branches/experimental/ui/ui.core.position.js Tue Nov 4 08:29:57 2008
@@ -0,0 +1,68 @@
+$.fn.position = function(e, o) {
+
+ var parentOffset = this.parent().offset();
+ parentOffset = {
+ top: this.parent()[0] == document.body ? 0 : parentOffset.top,
+ left: this.parent()[0] == document.body ? 0 : parentOffset.left
+ };
+
+ var options = $.extend({
+ relativeTo: 'mouse',
+ direction: 'default'
+ }, o);
+
+ if($(options.relativeTo).length && $(options.relativeTo)[0].nodeName) {
+
+ var element = $(options.relativeTo),offset = element.offset();
+ var relHeight = element[0].offsetHeight, relWidth =
element[0].offsetWidth, height = this[0].offsetHeight, width =
this[0].offsetWidth;
+ var leftOffset = 0, topOffset = 0;
+
+
+ if((/(left|right)/).test(options.direction)) {
+ leftOffset = options.direction == 'left' ? -(width) : relWidth;
+ topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+ } else {
+
+ if(options.direction == 'above') {
+ topOffset = -(height);
+ } else if(options.direction == 'below') {
+ topOffset = relHeight;
+ } else {
+ topOffset = $(window).height()-offset.top < height ? -(height) :
relHeight;
+ }
+
+ }
+
+
+ switch(options.direction) {
+ case 'right':
+ leftOffset = relWidth;
+ topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+ break;
+ case 'left':
+ leftOffset = -(width);
+ topOffset = e ? ( $(window).height()-offset.top < height ?
-(height-relHeight) : 0 ) : 0;
+ break;
+ case 'above':
+ topOffset = -(height);
+ break;
+ case 'below':
+ topOffset = relHeight;
+ break;
+ }
+
+ this.css({
+ left: offset.left - parentOffset.left + leftOffset,
+ top: offset.top - parentOffset.top + topOffset
+ });
+
+ } else {
+
+ this.css({
+ left: e.pageX - parentOffset.left,
+ top: e.pageY - parentOffset.top
+ });
+
+ }
+
+};
\ No newline at end of file
Modified: branches/experimental/ui/ui.menu.js
==============================================================================
--- branches/experimental/ui/ui.menu.js (original)
+++ branches/experimental/ui/ui.menu.js Tue Nov 4 08:29:57 2008
@@ -12,6 +12,14 @@
*/
(function($) {
+$(document).ready(function() {
+ $(window).bind('click', function(e) {
+
+ $.ui.menu.prototype.closeAll(e);
+
+ });
+});
+
$.widget("ui.menu", {
_init: function() {
@@ -71,14 +79,14 @@
if(o.mode != 'static') {
if(o.mode == 'dropdown') {
- this.element.bind('click', function() {
- self.toggle();
+ this.element.bind('click', function(e) {
+ self.toggle(e);
});
}
if(o.mode == 'context') {
this.element.bind('contextmenu', function(e) {
- self.open();
+ self.open(e);
e.preventDefault();
});
}
@@ -118,13 +126,17 @@
$('> a', this)
.addClass('ui-menu-indicator') //Add a class that shows the little
arrow to indicate a sub list
.html('<span class="'+self.options.nextMenuClass+'">'+$('> a',
this).text()+'</span>') //Insert a new span
- .hover(function() {
+ .hover(function(e) {
if(hideTimer) clearTimeout(hideTimer);
var subList = $(this).next();
showTimer = setTimeout(function(){
- subList.addClass('ui-component-content').show();
+ subList.addClass('ui-component-content').show();
+ subList.position(e, {
+ relativeTo: subList.parent(),
+ direction: 'right'
+ });
}, 300);
}, function() {
@@ -160,27 +172,48 @@
},
- toggle: function() {
- return this[this.visible ? 'close' : 'open']();
+ toggle: function(e) {
+ return this[this.visible ? 'close' : 'open'](e);
},
- open: function() {
-
+ open: function(e) {
+
+ if(this.options.exclusive) {
+ this.closeAll();
+ }
+
this.menu.show();
- var offset = this.element.offset();
-
- this.menu.css({
- left: offset.left,
- top: offset.top + this.element.height()
+ this.menu.position(e, {
+ relativeTo: this.options.mode == 'context' ? 'mouse' : this.element,
+ direction: this.options.direction
});
+ $.ui.menu.manager.push(this);
this.visible = true;
},
+ closeAll: function(excludeEvent) {
+
+ var exclusion = null;
+ if(excludeEvent) {
+ var q = $(excludeEvent.target).parents().andSelf().each(function() {
+ if($.data(this, 'menu') && ($.data(this, 'menu').options.mode
== 'context' ? excludeEvent.which == 3 : true)) exclusion =
$.data(this, 'menu');
+ });
+ }
+
+ for (var i=0; i < $.ui.menu.manager.length; i++) {
+ if(exclusion != $.ui.menu.manager[i]) $.ui.menu.manager[i].close();
+ };
+
+ },
+
close: function() {
this.menu.hide();
+ for (var i=0; i < $.ui.menu.manager.length; i++) {
+ if($.ui.menu.manager[i] == this) $.ui.menu.manager.splice(i,1);
+ };
this.visible = false;
}
@@ -188,11 +221,13 @@
});
$.extend($.ui.menu, {
+ manager: [],
defaults: {
type: 'normal', //Can be set to either normal, ipod style or toolbar
mode: 'dropdown', //Can be set to context (open on click) or static
(render into the selected element)
items: '> ul', //Can be either a jQuery selector, therefore using markup
in the selected node, or a JSON list of menu entries
- appendTo: 'body', //Only in case of context/dropdown - where the actual
menu is being appended to
+ appendTo: 'body', //Only in case of context/dropdown - where the actual
menu is being appended to,
+ exclusive: true, //Defines wether only this menu can be shown at the
same time
width: 180,
height: null, //If height specified and surpassed, up and down arrows at
both ends are shown to navigate up and down,