kjo
kjo

Reputation: 35311

Automatically generating unique DOM ids?

When coding with JS and the DOM I find myself constantly needing to generate ids (or names) that have no purpose other than to group DOM elements together (or relate them to each other)1.

These ids (or names) will not be mentioned explicitly anywhere else in the code, and therefore they could be any random strings, and, for the case of ids, they must be unique.

Is there a standard way in JavaScript to automatically generate unique ids?


1A situation that illustrates such use of identifiers arises at the time of grouping (say) radio buttons and linking them to their associated labels...

My (naive noob's) alternative to the brain-numbing task of writing HTML like this

<input type="radio" name="sys" id="sys-0" value="lnx"> <label for="sys-0"> Linux   </label> <br>
<input type="radio" name="sys" id="sys-1" value="osx"> <label for="sys-1"> OS X    </label> <br>
<input type="radio" name="sys" id="sys-2" value="win"> <label for="sys-2"> Windows </label>

(which requires repeating each sys-based identifier three times per button-label pair) is to just write

<div class="button-group" name="sys">
  <input type="radio" value="lnx"> <label> Linux   </label> <br>
  <input type="radio" value="osx"> <label> OS X    </label> <br>
  <input type="radio" value="win"> <label> Windows </label>
</div>

and then use some JS to group the buttons under one name attribute, and link the labels to their respective buttons:

$('.button-group').each(function (i, e) {
  var name = $(e).attr('name');
  $(e).find(':radio').each(function (j, f) {
    var id = name + '-' + j;
    $(f).attr('name', name)
        .attr('id', id)
      .next()
        .attr('for', id);
  })
});

This works fine, but it still requires me to come up with names for these button groups and unique ids for the buttons, names and ids that are otherwise useless to me. I'd just as soon avoid all this gratuitous naming business with something like

<div class="button-group">
  <input type="radio" value="lnx"> <label> Linux   </label> <br>
  <input type="radio" value="osx"> <label> OS X    </label> <br>
  <input type="radio" value="win"> <label> Windows </label>
</div>

$('.button-group').each(function (i, e) {
  var name = unique_id();
  $(e).find(':radio').each(function (j, f) {
    var id = unique_id();
    $(f).attr('name', name)
        .attr('id', id)
      .next()
        .attr('for', id);
  })
});

Of course I could roll my own implementation of unique_id, but I thought I'd ask before I reinvent this very obvious-looking wheel.

Upvotes: 18

Views: 22865

Answers (4)

Christophe
Christophe

Reputation: 28124

A common approach - for example in ajax calls - is to use new Date().getTime().

If you are worried that you might output the same id twice, you can always add a validation step:

do {uniqueID=new Date().getTime();} while (document.getElementById(uniqueID));

Upvotes: 5

charlietfl
charlietfl

Reputation: 171669

Example of working with radio labels without ID:

<div class="button-group" name="sys">
  <input type="radio" value="lnx" name="radio1"> <label> Linux   </label> <br>
  <input type="radio" value="osx"  name="radio1"> <label> OS X    </label> <br>
  <input type="radio" value="win"  name="radio1"> <label> Windows </label>
</div>


   <div class="content">
       <div>Show me when 1st radio checked</div> 
       <div>Show me when 2nd radio checked</div> 
       <div>Show me when 3rdd radio checked</div>
   </div>

JS

$('.button-group[name=sys] :radio').change(function(){
    $(this).parent().find('label').removeClass('active');
     $(this).next().addClass('active');

      /* index radios vs content*/

      var radioIndex=$('.button-group[name=sys] :radio').index(this);
       /* hide all the content div, show one that matches radio index*/
       $('.content div').hide().eq(radioIndex).show();
})

Upvotes: -1

Arun P Johny
Arun P Johny

Reputation: 388316

One approach which I've used is

(function(){
    var counter = 0;
    window.uniqueId = function(){
        return 'myid-' + counter++
    }
});

then

$('.button-group').each(function (i, e) {
  var name = uniqueId();
  $(e).find(':radio').each(function (j, f) {
    var id = uniqueId();
    $(f).attr('name', name)
        .attr('id', id)
      .next()
        .attr('for', id);
  })
});

Upvotes: 16

mjswensen
mjswensen

Reputation: 3124

I agree with some of the commenters that there are probably better ways to do this, but a simple implementation of unique_id() you could use would be:

return Math.random().toString(36);

Upvotes: 7

Related Questions