10

Must Support IE6 and must Validate vs XHTML Strict 1.0!

This is tricky to explain...

I'm using a generic class name to initiate a plugin feature on an associated element. I also want to have options associated with the element stored in an attribute as well.

<a href="url.com" class="popup" rel="900x900" >My Link</a>

With this, jQuery will look for all elements that have 'popup' and parse the rel value for the dimensions of the popup and initiate the popup() function whenever this link is clicked with a window the size w=900 h=900

but I need to take this a step further because I want to have more options...

<a href="url.com" class="popup" rel="900x900_scroll_tool_menu" >My Link</a>

I'm not sure if using the rel attribute is the place for this because I also want to use this on other elements that dont have a rel= attribute.

So I was thinking using classes for this too... I came up with this:

 <a href="url.com" class="popup opt_dim-900x900_scroll_tool_menu" >My Link</a>
 <img src="pic.gif" class="popup opt_dim-150x200_location" >My Link</a>

From the looks of this the options can get VERY long, using class seems ok, but maybe there's something better..

Which way do you think is better? Do you have another idea for this? I want to store the options in some html attribute.

Thanks!

UPDATE

I am continually reminded that there are a dozen ways to do anything in Javascript, in terms of the solutions here I later changed the correct answer to the html5 data attribute, which now that ie6 isnt an issue, seems like the best method.

Best, because it uses standard features and avoids any of the hackery I was trying to do with class names. Sure classnames are extremely flexible still, but that solution isn't semantic, nor does it follow best practice of separating views from behavior.

qodeninja
  • 10,946
  • 30
  • 98
  • 152

8 Answers8

18

If you can use HTML5, then use data-* attributes -- they were designed for exactly this problem.

<div data-tool-menu="900x900">

http://ejohn.org/blog/html-5-data-attributes/

Ian Clelland
  • 43,011
  • 8
  • 86
  • 87
  • cant use html5, have to support ie6 – qodeninja Mar 09 '10 at 21:25
  • 1
    HTML 5 is still just a draft. – Gumbo Mar 09 '10 at 21:32
  • This will still work in IE6, as long as you don't use the javascript function to access it, which isn't implemented anywhere yet AFAIK. – Rich Bradshaw Mar 09 '10 at 21:51
  • 13
    “HTML 5 is still just a draft.” For crying out loud. I’m pretty sure `XMLHttpRequest` wasn’t in any spec 5 years ago, but we seem to have got along just fine in the interim regardless. – Paul D. Waite Mar 09 '10 at 22:10
  • 3
    @Rich: you actually can access these kind of attributes, using `getAttribute` http://stackoverflow.com/questions/2412947/do-html5-custom-data-attributes-work-in-ie-6/2413263#2413263 – Marcel Korpel Mar 10 '10 at 00:15
  • 2
    this answer is not helpful. I need to support ie6 and the markup should validate against xhtml strict. – qodeninja Mar 10 '10 at 01:23
  • @Marcel — that’s exactly why I asked that question, excellent! – Paul D. Waite Mar 10 '10 at 10:56
  • @codeninja — ah yes, it doesn’t validate as XHMTL Strict (or Transitional). But aside from `class`, XHTML doesn’t have any IE-supported way to add arbitrary data to HTML tags. If you could switch to valid HTML5 instead of valid XHTML Strict, this would be a viable option. – Paul D. Waite Mar 10 '10 at 10:58
  • @codeninja: Or, if you want to stick with XHTML, you could switch to XHTML 5. Just don't use the new elements like `
    ` and `
    – Marcel Korpel Mar 10 '10 at 16:56
  • @Paul D. Waite: Frankly, *XMLHTTP*, the predecessor of *XMLHTTPRequest*, was already in Internet Explorer 6. (That’s also where it got its horrible name from.) – Gumbo Mar 10 '10 at 21:24
  • @PaulD.Waite Looking back on this issue and ie6 not being supported much anymore, using the html5 data attributes seems like the way to go now! Funny how things change over time. – qodeninja Sep 21 '12 at 16:24
  • @qodeninja: indeed, time deprecates all browsers eventually. Although it’s worth remembering that `data-*` attributes themselves have always worked alright in IE6, so IE6 support wasn’t much of a reason to avoid them. – Paul D. Waite Sep 23 '12 at 10:43
8

Why not just embed json in the rel attribute:

<a href="url.com" class="popup" rel="{w:900,h:900}" >My Link</a>

That way you can have as many properties as you want and the format is standardized and easy to access.

if validation is a concern; you could always use xhtml, define your own custom namespace, and then add a custom attribute.

<a href="url.com" class="popup" custom:options="{w:900,h:900}" >My Link</a>

Edit: Thanks to @andras in the comments, here's a great example of this technique:
http://www.bennadel.com/blog/1453-Using-jQuery-With-Custom-XHTML-Attributes-And-Namespaces-To-Store-Data.htm

Joel Martinez
  • 46,929
  • 26
  • 130
  • 185
  • I thought about this too, but I want the HTML to look like HTML with no Javascripty stuff in it. You get me? – qodeninja Mar 09 '10 at 21:25
  • As pointed out in the other answer even using rel="" for this will not validate. So now the problem becomes if i use JSON what HTML attribute do i put it in? – qodeninja Mar 09 '10 at 21:28
  • 7
    `rel` describes the current document and the document that is referenced. You should not abuse it for this purpose. – Gumbo Mar 09 '10 at 21:30
  • 2
    if validation is a concern; you could always use xhtml, define your own custom namespace, and then add a custom attribute. My Link – Joel Martinez Mar 09 '10 at 22:15
  • 2
    @Joel: That seems to be nice (http://www.bennadel.com/blog/1453-Using-jQuery-With-Custom-XHTML-Attributes-And-Namespaces-To-Store-Data.htm). – Andras Vass Mar 09 '10 at 22:35
  • @Joel: have you considered updating your answer? – Andras Vass Mar 09 '10 at 22:37
  • Can you use custom namespaces with XHTML served as `text/html`? I thought that was an XML-only thing. – Paul D. Waite Mar 10 '10 at 11:03
  • @Joel: cheers, the comment on XHTML custom attributes was really nice. (...but @Gumbo is right: you are a sinner for using `rel` in your answer...:-) http://codeoffsets.com/ ? xD – Andras Vass Mar 10 '10 at 21:00
  • lol, to be fair, explicit validation is not always a requirement. In those cases, rel (or any other attribute value) works just fine ;-) – Joel Martinez Mar 10 '10 at 21:12
5

Extract metadata from a DOM Element and return it as an Object.

You could support / use the jQuery metadata plugin. There are a few options to choose from, and it's a good way to embed metadata in the html.

e.g. the following are all supported by the plugin.

<li class="someclass {some: 'data'} anotherclass">...</li>
<li data="{some:'random', json: 'data'}">...</li>
<li class="someclass">
   <script type="application/json">{some:"json",data:true}</script>...
</li>

See also: A Plugin Development Pattern over at learningjquery.com

Robert Paulson
  • 17,603
  • 5
  • 34
  • 53
  • this is actually what im leaning towards. – qodeninja Mar 14 '10 at 16:59
  • With HTML5, there are also data-* specific attributes (and valid!) that are geared toward just this sort of thing. Replace * with anything that fits your need. You can then access the attribute and load it's contents in javascript, in any needed format, json being the most amenable. – arxpoetica Jun 26 '10 at 21:49
  • 1
    @American Yak - Yes I use data- attributes all the time. [HTML 5 data- Attributes - John Resig](http://ejohn.org/blog/html-5-data-attributes/) – Robert Paulson Jun 26 '10 at 22:39
4

Technically, rel has a limited list of possible values, so you could create a page that won't validate.

I use extra classes for this type of thing all the time. I've never had one longer than about 20 characters, so I've never pushed against any length limit. The good thing about using classes this way is that you can validate the page, which is always a Good Thing(tm).

Update for comment:

I tend to not overload a single class name, but to generate multiple classes that each Do One Thing. This not only makes things simpler to parse, but it also makes it easy to separate behavior from identity from attribute.

For example: the Django Book platform code has not been made available (at least not that I can find anywhere, and I've looked hard), so I'm reimplementing it for a customer (and, yes, it will be released OS). A lightly modified version of docutils automatically adds behavior and identity to the tags of "commentable items" as it converts from reStructuredText to HTML. The specifics aren't pertinent, but there are lots of cg-13-134 and cg-15-u-142 type classes floating around, which are easy on the eyes and the parser.

Peter Rowell
  • 17,605
  • 2
  • 49
  • 65
  • Can you give some detail on how you use classes for your options? do you do someting like class="opt_location-1 opt_menu-0" ? – qodeninja Mar 09 '10 at 21:25
  • It’s up to you. The `class` attribute just gives you a place where you can store as much arbitrary string content as you want (subject to them being valid HTML class names, I suppose?) – Paul D. Waite Mar 09 '10 at 22:12
  • yeah, something about this (using class) I dont like though =/ – qodeninja Mar 10 '10 at 01:24
  • @codeninja: OK, so where do *you* put this kind of information and still get a pre-HTML5 document that will validate? To my knowledge the *only* safe place to put it is in the `class`. As long as you generate conformant class names I don't see the problem. Any name that is not defined in a stylesheet is just a NOP. (http://en.wikipedia.org/wiki/NOP) – Peter Rowell Mar 10 '10 at 01:37
  • Very interesting, that example. Do you already have a link to this project, or isn't it published yet? – Marcel Korpel Mar 10 '10 at 23:36
  • @Marcel: It's not open for the public at the moment. The book it's being used for may be truly groundbreaking in its field and so I'm mostly making sure that all of the necessary features are there for a select group of expert reviewers. Once the feature set has settled down I'll do a beta release, probably in about 1 to 2 months. Send me email if you would like to get the announcement. peter@techbuddy.us. – Peter Rowell Mar 11 '10 at 01:11
  • @PeterRowell do you still use this method now that the data attribute in html does a lot of this out of the box and semantically? – qodeninja Sep 21 '12 at 16:22
  • @qodeninja: yes and yes :-) I use `data-whatever` for actual data, but still use classes to identify items that need JS behaviors attached to them. I haven't tested it, but my sense is that the "selector engines" of most JS frameworks are optimized to search on `class` more than they are for arbitrary attribute names/values. – Peter Rowell Sep 21 '12 at 21:26
4

You can include a element within an element

If you give the element an id, you could use something like:

<a href="/url" id="unique_id" class="popup">My Link
    <script type="text/javascript">
        popup['unique_id'] = { \\JSON object describing options
                             };
    </script>
</a>

Granted, you still have Javascript entwined with your HTML, but it will, at least, validate.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
  • hmm or maybe a hidden options span? a nested elm is a good idea but a script.. no.. lol – qodeninja Mar 09 '10 at 21:41
  • SCRIPT has the advantage that it doesn't display anything, so you don't need to explicitly hide it. I'd argue that it's more appropriate, semantically too. – Dancrumb Mar 10 '10 at 15:07
  • I try to avoid inline scripts per my brainwashing. I understand there may be situations where inline scripting makes sense but this isnt one of them. – qodeninja Sep 21 '12 at 16:23
  • 1
    Two years on, I'd recommend using the HTML 5 data-* attributes for this kind of thing. – Dancrumb Sep 21 '12 at 16:48
3

I think you're looking for jQuery.data().

The jQuery.data() method allows us to attach data of any type to DOM elements ...

From the example in the link above:

var div = $("div")[0];
jQuery.data(div, "test", { first: 16, last: "pizza!" });
$("span:first").text(jQuery.data(div, "test").first);
$("span:last").text(jQuery.data(div, "test").last);
jrummell
  • 42,637
  • 17
  • 112
  • 171
1

Since you're going to be using javascript, I'll suggest adding the extra options/information you need as parameters to your url. I've been looking for a similar solution to your question and I've finally decided to take this route. It's also the way ThickBox (http://jquery.com/demo/thickbox/) does it, and I've used it successfully on a couple of projects.

<a href="url.com?width=900&height=900&randomKey=randomValue" class="popup">My Link</a>

Then in your js

$(".popup").click(function(){
  var url = $(this).attr("href");
  var width = fancyFunctionToParseParameters(url, "width");
  ...
});
sjobe
  • 2,817
  • 3
  • 24
  • 32
  • 1
    This is really a clever use of the URL! and actually I did something very similar to this to autoload modals and popups when certain parameters were in the URL string – qodeninja Sep 21 '12 at 16:12
1

Why not this instead:

<a href="url.com" class="popup">
<input type="hidden" value="900x900_scroll_tool_menu">My Link</a>

Then just use the proper jQuery selector on your click event. Simple and it keeps the javascript out of this part of your HTML.

WVDominick
  • 2,074
  • 15
  • 17
  • thats ok excpet for the fact that input has to be proceded by form in order to validate. – qodeninja Mar 09 '10 at 22:52
  • @codeninja: Pardon? What validator are you using? input is just an inline-level element -- you should be able to put it in a p tag if you want. (And, technically, you can't put it directly in a form tag: they enclose block-level content; that's what fieldsets are for) – Ian Clelland Mar 10 '10 at 17:42
  • @IanClelland if I recall, in order for the markup to validate against the XHTML doctype an input element has to follow a form element. It gave me a validation errors when I tried to use input without a form tag. Though it may be inline, it isn't semantically correct. – qodeninja Sep 21 '12 at 16:18