patternjavascriptMinor
A generic context menu with generically bound events
Viewed 0 times
genericboundeventswithmenucontextgenerically
Problem
I've taken a stab at making a context menu using BackboneJS.
Here's the overall structure:
Collections:
Models:
Views:
To start off, lets take a look at my template:
My template is created such that each
Here's my view:
```
define(['contextMenu'], function (ContextMenu) {
'use strict';
var ContextMenuView = Backbone.View.extend({
className: 'contextMenu',
template: _.template($('#contextMenuTemplate').html()),
parentSelector: 'body',
render: function () {
this.$el.html(this.template(this.model.toJSON()));
// Prevent display outside viewport.
var offsetTop = this.top;
var needsVerticalFlip = offsetTop + this.$el.height() > $(this.parentSelector).height();
if (needsVerticalFlip) {
offsetTop = offsetTop - this.$el.height();
}
var offsetLeft = this.left;
var needsHorizontalFlip = offsetLeft + this.$el.width() > $(this.parentSelector).width();
if (needsHorizontalFlip) {
offsetLeft = offsetLeft - this.$el.width();
}
// Show the element before setting offset to ensure correct positioning.
this.$el.show().offset({
top: offsetTop,
left: offsetLeft
});
return this;
},
initialize: function () {
// TODO: If I implement Backbone View's more properly, then 'body' should b
Here's the overall structure:
Collections:
- /collection/contextMenuGroups
- /collection/contextMenuItems
Models:
- /model/contextMenu
- /model/contextMenuGroup
- /model/contextMenuItem
Views:
- /view/contextMenuView
To start off, lets take a look at my template:
">
" href="#">
My template is created such that each
contextMenuGroup provided to it creates a new unordered list. Each item in each group creates a link inside of a listItem for the given unordered list.Here's my view:
```
define(['contextMenu'], function (ContextMenu) {
'use strict';
var ContextMenuView = Backbone.View.extend({
className: 'contextMenu',
template: _.template($('#contextMenuTemplate').html()),
parentSelector: 'body',
render: function () {
this.$el.html(this.template(this.model.toJSON()));
// Prevent display outside viewport.
var offsetTop = this.top;
var needsVerticalFlip = offsetTop + this.$el.height() > $(this.parentSelector).height();
if (needsVerticalFlip) {
offsetTop = offsetTop - this.$el.height();
}
var offsetLeft = this.left;
var needsHorizontalFlip = offsetLeft + this.$el.width() > $(this.parentSelector).width();
if (needsHorizontalFlip) {
offsetLeft = offsetLeft - this.$el.width();
}
// Show the element before setting offset to ensure correct positioning.
this.$el.show().offset({
top: offsetTop,
left: offsetLeft
});
return this;
},
initialize: function () {
// TODO: If I implement Backbone View's more properly, then 'body' should b
Solution
I like the code as is,
As for events, I would
- Use of
'use strict'
- JsHint cannot find anything
- Readable, well named variables
- No obvious copy pasting or repeated code
As for events, I would
- Wait until everything is rendered
- Add a
$.click()to each menu item, item by selecting on a classname used only by those menu items, or you could re-build the id's of each menu item and attach to each one individually ( first approach would be much better ).
- Then I would use
$.trigger()to send out an event with the text of the button
- Register whoever needs to know that a menu item was clicked for that event
Context
StackExchange Code Review Q#28606, answer score: 3
Revisions (0)
No revisions yet.