Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ <h4>Behavioural</h4>
<h4>Navigation</h4>
<a class="navigation tree" href="/src/pat/expandable-tree/index.html" title="">Expandable tree<sup>unknown</sup></a>
<a class="navigation navigation-marker" href="/src/pat/navigation/index.html" title="Navigation markers">Navigation<sup>unknown</sup></a>
<a class="navigation menu" href="/src/pat/menu/index.html" title="Menu">Menu<sup>unknown</sup></a>
</div>

<div class="layout">
Expand All @@ -47,9 +48,9 @@ <h4>Forms</h4>
<a class="navigation datetime-picker" href="/src/pat/datetime-picker/index.html" title="">Date/Time picker<sup>β</sup></a>
<a class="navigation checked-flag" href="/src/pat/checked-flag/index.html" title="checkedflag">Checked flag<sup>unknown</sup></a>
<a class="navigation checkboxes" href="/src/pat/checklist/index.html" title="checklist">Checkboxes<sup>unknown</sup></a>
<a class="navigation validate" href="/src/pat/validation/index.html">Validation<sup>β</sup></a>
<a class="navigation subform" href="/src/pat/subform/index.html">Subform<sup>unknown</sup></a>
<a class="navigation colour-picker" href="/src/pat/colour-picker/index.html">Colour-Picker<sup>unknow</sup></a>
<a class="navigation validate" href="/src/pat/validation/index.html">Validation<sup>β</sup></a>
<a class="navigation subform" href="/src/pat/subform/index.html">Subform<sup>unknown</sup></a>
<a class="navigation colour-picker" href="/src/pat/colour-picker/index.html">Colour-Picker<sup>unknown</sup></a>
</div>

<div class="fancy-stuff">
Expand Down
40 changes: 40 additions & 0 deletions src/pat/menu/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Description

This is a simple pattern which makes sure that only one menu item ( <li> ) has
the class `open`, with the rest having the class `closed`. This helps designers
can focus on setting the styles for the classes `open`, and `closed`, and
and can rely on the classes being set consistently.

### Examples

####This is a very simple list, in which the <li> elements change color and
####font upon focus.

<ul class="pat-menu">
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
<li>Fourth item</li>
<li>Fifth item</li>
<li>Sixth item</li>
</ul>

On loading,
<ul class="pat-menu">
<li class = 'closed'>First item</li>
<li class = 'closed'>Second item</li>
<li class = 'closed'>Third item</li>
<li class = 'closed'>Fourth item</li>
<li class = 'closed'>Fifth item</li>
<li class = 'closed'>Sixth item</li>
</ul>

If the focus is on the second element,
<ul class="pat-menu">
<li class = 'closed'>First item</li>
<li class = 'open'>Second item</li>
<li class = 'closed'>Third item</li>
<li class = 'closed'>Fourth item</li>
<li class = 'closed'>Fifth item</li>
<li class = 'closed'>Sixth item</li>
</ul>
22 changes: 17 additions & 5 deletions src/pat/menu/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,32 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>pat-colour-picker demo page</title>
<link rel="stylesheet" href="/style/common.css" type="text/css">
<link rel="stylesheet" type="text/css" href="/src/pat/menu/menu.css">
<script src="/bundle.js" type="text/javascript" charset="utf-8"></script>

<link rel="stylesheet" type="text/css" href="menu.css">
<script src="/bundle.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
ul {
width: 40em;
}
</style>
</head>
<body>
<h3> Example Menu </h3>
<ul class="pat-menu">
<li>First item</li>
<li>First item
<ul>
<li>Sub First item</li>
<li>Sub Second item</li>
<li>Sub Third item</li>
<li>Sub Fourth item</li>
<li>Sub Fifth item</li>
<li>Sub Sixth item</li>
</ul>
</li>
<li>Second item</li>
<li>Third item</li>
<li>Fourth item</li>
<li>Fifth item</li>
<li>Sixth item</li>
</ul>

</body>
</html>
4 changes: 2 additions & 2 deletions src/pat/menu/menu.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.open {
li.open {
background-color: grey;
color: white;
font-size: 20px;
}

.closed {
li.closed {
background-color: beige;
color: black;
}
101 changes: 50 additions & 51 deletions src/pat/menu/menu.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,60 @@
define([
"pat-base",
"pat-parser",
"jquery",
"pat-registry"
], function($, patterns) {
var menu = {
name: "menu",
trigger: "ul.pat-menu",

init: function($root) {
return $root.each(function() {
var $menu = $(this),
timer,
closeMenu, openMenu,
mouseOverHandler, mouseOutHandler;

openMenu = function($li) {
if (timer) {
clearTimeout(timer);
timer = null;
}

if (!$li.hasClass("open")) {
$li.siblings("li.open").each(function() { closeMenu($menu);});
$li.addClass("open").removeClass("closed");
}
};
], function(Base, Parser, $) {

closeMenu = function($li) {
$li.find("li.open").addBack().removeClass("open").addClass("closed");
};

mouseOverHandler = function() {
var $li = $(this);
openMenu($li);
};
var parser = new Parser('menu');

mouseOutHandler = function() {
var $li = $(this);
parser.addArgument('nav-item-selector', 'li'); // CSS Selector for navigation items.

if (timer) {
clearTimeout(timer);
timer=null;
}

timer = setTimeout(function() { closeMenu($li); }, 1000);
return Base.extend({
name: "menu",
trigger: ".pat-menu",

timer: null,

init: function($el, opts) {
this.options = parser.parse(this.$el, opts);
var self = this;
$el.find(this.options.navItemSelector).each(function() {
var $it = $(this);
$it.addClass("closed")
.on("mouseover", self.mouseOverHandler.bind(self))
.on("mouseout", self.mouseOutHandler.bind(self));
if($it.children(self.options.navItemSelector).length > 0) {
$it.addClass("hasChildren");
};

$root.find("li")
.addClass("closed")
.filter(":has(ul)").addClass("hasChildren").end()
.on("mouseover.pat-menu", mouseOverHandler)
.on("mouseout.pat-menu", mouseOutHandler);
});
},

openMenu: function(it) {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
it = $(it);
if (!it.hasClass("open")) {
it.siblings(".open").each(function() { this.closeMenu(this.$el);}.bind(this));
it.addClass("open").removeClass("closed");
}
},

closeMenu: function(it) {
$(it).find(".open").addBack().removeClass("open").addClass("closed");
},

mouseOverHandler: function(ev) {
this.openMenu(ev.target);
},

mouseOutHandler: function(ev) {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.timer = setTimeout(function() { this.closeMenu(ev.target); }.bind(this), 1000);
}
};

patterns.register(menu);
});
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
33 changes: 33 additions & 0 deletions src/pat/menu/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
define(["pat-menu"], function(Pattern) {

describe("pat-menu", function() {

beforeEach(function() {
$("<div/>", {id: "lab"}).appendTo(document.body);
});

afterEach(function() {
$("#lab").remove();
});


describe("init tests", function() {
it("adds class closed on init", function() {
var $lab = $("#lab");
$lab.html([
"<ul class=\"pat-menu\">",
"<li>First Item</li>",
"<li>Second Item</li>",
"<li>Third Item</li>",
"</ul>"
].join("\n"));
var $list = $("ul.pat-menu");

Pattern.init($list);

expect($($list).children().not(".closed").length).toBe(0);
});
});
});

});