0

Introduction

For my new job I have to write a classical dropdown menu example that is highly accessible (by mouse and keyboard) and that is compatible to screen readers (by managing WAI-ARIA attributes and states properly). My team consists of "normal" people and people with bodily disabilities, and they say they weren't able to find a fully accessible dropdown menu until this point, so we are trying to create our own to give to clients.

Well, I'm coming from a Ruby on Rails background and didn't write complex JavaScript code until now, so I'm trying to apply my OOP knowledge from Ruby to the JS world. Since I know CoffeeScript quite well, and it's offering quite some magic in the background which makes working with classes and inheritance easy (although JS is an object driven language and there's no such thing as classes), I'm sticking to CoffeeScript instead of plain JS.

I'm trying to set up some proper object tree that resembles a dropdown menu:

  • There's an Item class.
  • There's a ParentItem class which inherits from Item.
  • There's a RootParentItem class which inherits from ParentItem.

This way, all root items are of type RootParentItem, all other parent items (items that hold their own sub menus) are of type ParentItem, and all the "real" menu items (links pointing to some place in the website) are of type Item.

By setting up this proper object tree, I think it's very simple and reasonable to handle different key actions, mouse actions, etc., depending on the type of item. This helps to prevent long procedural spaghetti code, that I have seen on many other JS libraries which are providing similar functionality.

Here's an example of my current work: http://codepen.io/jmuheim/pen/fAjcx

Now after some thinking I asked me the question: is it reasonable to create my own object tree, while having a lot of jQuery arrays in the background and keeping them in my objects' variables? It somehow feels odd to have a nice tree structure, but always working with a "shadow" of quite the same structure, say: jQuery arrays.

As mentioned, I'm coming from a Ruby world, which is highly object oriented. I don't have any experience in clean coding practices/patterns in JavaScript world, so:

  • Do you think my attempt is reasonable?
  • Is there a cleaner (publicly more accepted) way of doing this? Maybe working directly on the prototypes of the jQuery arrays would be more reasonable? How could this be done though?
  • Any other comment about my JS coding style?
Joshua Muheim
  • 12,617
  • 9
  • 76
  • 152
  • Before I get too deep into your question, did you research jQuery UI select menu or any of its relatives? http://jqueryui.com/selectmenu/. jQuery takes accessibility pretty seriously. I'd be curious what your team found it missing. – joeltine Aug 09 '14 at 07:02
  • I forgot to add the link to my codepen example. There you see that I mean a multi-level dropdown-menu, not an alternative to the `select` tag. – Joshua Muheim Aug 09 '14 at 07:09
  • Similar to http://jqueryui.com/menu/? – joeltine Aug 09 '14 at 07:20
  • I will talk back to my team about the jQuery UI menu. Meanwhile, I would still be highly interested in your opinion about my question. – Joshua Muheim Aug 09 '14 at 07:36
  • might checkout MVC principles; it's inevitable that you'll need to sync data and a view, and whatever easy way you can accomplish that is reasonable. – dandavis Aug 09 '14 at 07:52

2 Answers2

0

I think your inheritance model is backwards. It sounds like you want "Item" to be the "leaf" subclass, but you say "ParentItem inherits from Item". Item should actually inherit from ParentItem and so on.

In terms of OO design, it really depends how the arrays "in the background" will be used. Are these unique lists for each class instance? Are they static lists who are actually shared amongst all your class instances or among just one type of class instances? If it's the former, having an internal member variable to store these arrays for each instance makes sense. If it's the latter, you're really talking about, in classical OO terms, static member variables. That can be achieved by attaching the static member to the Constructor object as a normal attribute (and accessed as such), instead of on the prototype or assigned to "this" in the constructor. An example:

function A(name) {
this.name = name;
}

A.prototype.doStuff = function() {
 A.staticList.push(this.name);
};

A.staticList = [];

var x = new A('foo');
var y = new A('bar');

x.doStuff();
y.doStuff();

A.staticList; // contains ['foo', 'bar']
joeltine
  • 1,610
  • 17
  • 23
0

and all the "real" menu items (links pointing to some place in the website) are of type Item.

I would consider using a RealItem or LinkItem class for them that inherits from Item as well.

Is it reasonable to create my own object tree, while having a lot of jQuery arrays in the background and keeping them in my objects' variables?

Yes. That what most apps with MVC model do - the view component controls the DOM, and keeps references to it (or jQuery wrappers) as properties/variables in the class.

Is there a cleaner (publicly more accepted) way of doing this? Maybe working directly on the prototypes of the jQuery arrays would be more reasonable?

I don't think that would be much cleaner.

How could this be done though?

Yes, you can inherit from jQuery collections, but I wouldn't recommend it.

Any other comment about my JS coding style?

The code could get a bit more DRY if you'd use some functional programming practises, but I think it is fine.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375