6

I have a doubt about good practices writing HTML with Javascript.

I've came up with an idea (probably not the first, but couldn't find a clear reference about that) to mark some elements as candidates to load some data when it's available (after some user interaction). Let me exemplify:

Suppose I have a request that returns the following:

GET    /animals/dog

{
  name: "Gutemberg",
  race: "doberman",
  age: "2y"
}

The code I wrote binds fields in the response to elements that are candidates to load such value. For example: With the request above, I could use the following tags:

<input name="dog-name-field" data-load-dog-name type="text"/>
<input name="dog-age-hid" data-load-dog-age type="hidden"/>

Each tag would receive the property value because it's marked as a candidate to do so - dog-name-field will have a value of "Gutemberg" when everything executes . That will happen everytime the request is reloaded. For now, I just get the data type I've searched ("dog"), concat it with the property "name/age" to form the attribute data-load-type-property and set a value to everyone that has such attribute.

I have a feeling that attributes are not meant to be used just like that, but I'm not aware of any real downsides to that. As I could not find it for the lack of a clear name to this approach, I'd like some guidance.

Is there a name for such technique? Is it a bad practice? If so, why?

PS: To comply with SO good practices, I'd like the answers to be reference-guided and not based solely on opinion whenever possible. If no reference is provided, please, let us have a solid, well described example.

Andrea Casaccia
  • 4,802
  • 4
  • 29
  • 54
D. Melo
  • 2,139
  • 2
  • 14
  • 19
  • Generally the way to do this is to use the `id` attribute if it is for a single element and `class` for multiple elements. – Tonlage Nov 09 '15 at 11:44
  • Related: http://stackoverflow.com/questions/17184918/best-practice-class-or-data-attribute-as-identifier – Andrea Casaccia Nov 09 '15 at 11:44
  • I see nothing wrong with your approach, assuming you need to keep the identifcation method dynamic. – Rory McCrossan Nov 09 '15 at 11:44
  • Use ids or classes. Attributes are the slowest of them all. Ids are much faster than the 3. If you want to keep it this way , set an attribute like myval="xxx" – cpugourou Nov 09 '15 at 11:57

2 Answers2

1

This is called binding. Sometimes data binding and sometimes template binding.

Various frameworks provide mechanisms for this, though the syntax varies.

AngularJS example:

<input ng-model="dog.name" />

Knockout example:

<input data-bind="textInput: dog.name" />

React example:

<input value={this.state.dog.name} />

These are all quite popular frameworks/libraries, so I think it's safe to say it is not considered bad practice. The main difference from your approach is that they use the value of the attribute to specify the reference into the model (i.e. the "dog.name" part of your attributes), while you are putting the reference in the attribute name. In practice this is mostly a matter of style. Separating the reference from the "marker" (i.e. "data-load") is perhaps a bit more readable.

Supr
  • 18,572
  • 3
  • 31
  • 36
  • Using an attribute in html does not create any binding by itself so saying `this is called binding` is incorrect – charlietfl Nov 09 '15 at 12:19
  • @charlietfl It does if you use the frameworks I mentioned or if you wrote code to find and process the attributes like D. Melo did. – Supr Nov 09 '15 at 12:29
1

I have a feeling that attributes are not meant to be used just like that

Let's see what custom data attributes are meant to be used for:

Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements. These attributes are not intended for use by software that is independent of the site that uses the attributes.

(from w3.org)

So whether using data-attributes is "appropriate" in your case depends on your needs: if the DOM API doesn't provide better attributes to do that then it's appropriate.

If your need is just to select some element to change the textContent then you have two more appropriate/simpler options:

1) Using the id attribute if your elements are going to be unique in the document

The id global attribute defines a unique identifier (ID) which must be unique in the whole document. Its purpose is to identify the element when linking (using a fragment identifier), scripting, or styling (with CSS).

(from id on MDN)

2) Using the class attribute if your elements are going to be used in multiple instances in the document

The class global attribute is a space-separated list of the classes of the element. Classes allows CSS and Javascript to select and access specific elements via the class selectors or functions like the DOM method document.getElementsByClassName.

(from class on MDN)

As @Supr says in his answer, what you are doing is a very simple implementation of data-binding. data-binding can involve a lot more complexity than what you are doing at the moment; for example you may want to:

  • keep in sync your UI with a Javascript object which represent your business model instead of directly injecting data coming from an Ajax call,

  • update other attributes (value, style) and not only innerHTML or textContent,

  • have your business model updated in reaction to changes on the UI (two way data binding)

To implement all these features, simple id and class selectors are not sufficient, and this is why frameworks which implement data-binding, like KnockoutJS or AngularJS, use the more flexible data-* attributes instead (AngularJS is actually using its own ng-* attributes, but allows to use the alternative data-ng-* syntax for using HTML validation tools).

Data attributes allow to describe much more complex bindings:

<input data-bind="visible: editing, value: name, hasFocus: editing" />

Check KnockoutJS documentation for the meaning of the above code, it is not relevant to this example but just imagine describing that with classes or ids, it wouldn't be very convenient.

TL;DR

If you don't plan to implement more complex features you might want to use class and id instead.

Community
  • 1
  • 1
Andrea Casaccia
  • 4,802
  • 4
  • 29
  • 54