Gordon Guthrie
Gordon Guthrie

Reputation: 6264

Unique html item ID in Javascript

I am building a drag'n'drop gui builder in Javascript. So far so good.

As I add items to the GUI and configure them; I have two mechanisms for addressing them:

My problem is this: the 'id' must be unique across all html items on the page (by definition) so how do I ensure this? I need to get all the id's of all the items and then maintain some sort of state table.

Starting from a blank bit of html this is pretty reasonable - but I need to start from a partly created bit of html with a mixture of existing 'id's - some of which will be in my unique scheme and some of which wont be...

The way to do this best ought to be a solved problem.

Suggestions, tips, examples?

Upvotes: 1

Views: 4524

Answers (4)

diachedelic
diachedelic

Reputation: 2359

function generateId() {
    var chars = "0123456789abcdefghiklmnopqrstuvwxyz",
        string_length = 8,
        id = '';
    for (var i = 0; i < string_length; i++) {
        var rnum = Math.floor(Math.random() * chars.length);
        id += chars.substring(rnum, rnum + 1);
    }

    return id;
}

Close enough to unique is good enough. Don't use the Date() solution unless you're only generating a single ID at any given time...

Upvotes: 0

Prestaul
Prestaul

Reputation: 85145

The best way to do this will depend entirely upon the structure and organization of your javascript. Assuming that you are using objects to represent each of your GUI elements you could use a static counter to increment your ids:

// Your element constructor
function GuiElement() {
    this.id = GuiElement.getID();
}
GuiElement.counter = 0;
GuiElement.getID = function() { return 'element_' + GuiElement.counter++; };

Of course you probably have more than one type of element, so you could either set each of them up so that they have their own counter (e.g. form_1, form_2, label_1, label_2) or so that they all share a counter (e.g. element_1, element_2, element_3), but either way you will probably want them to inherit from some base object:

// Your base element constructor
function GuiElement(tagName, className) {
    this.tagName = tagName;
    this.className = className;
}
GuiElement.counter = 0;
GuiElement.getID = function() { return 'element_' + GuiElement.counter++; };
GuiElement.prototype.init = function() {
    this.node = document.createElement(this.tagName);
    this.node.id = this.id = GuiElement.getID();
    this.node.className = this.className;
}

// An element constructor
function Form() {
    this.init();
}
Form.prototype = new GuiElement('form', 'form gui-element');

// Another element constructor
function Paragraph() {
    this.init();
}
Paragraph.prototype = new GuiElement('p', 'paragraph gui-element');

You could also go this route if you would rather keep some variables "private":

// Your element constructor constructor
var GuiElement = (function() {
    var counter = 0;
    function getID() {
        return 'element_' + counter++;
    }
    return function GuiElement(tagName, className) {
        return function() {
            this.node = document.createElement(tagName);
            this.node.id = this.id = getID();
            this.node.className = className + ' gui-element';
            this.className = className;
        };
    }
})();

// Create your element constructors
var Form = GuiElement('form', 'form'),
    Paragraph = GuiElement('p', 'paragraph');

// Instantiate elements
var f1 = new Form(),
    f2 = new Form(),
    p1 = new Paragraph();

Update: If you need to verify that an id is not already in use then you could add the check you and of the getID methods:

var counter = 0;
function getID() {
    var id = 'element_' + counter++;
    while(document.getElementById(id)) id = 'element_' + counter++;
    return id;
}

Upvotes: 2

Jason
Jason

Reputation: 1183

If you happen to be using the Prototype library (or want to check it out), you can use the Element.identify() method.

Otherwise, Darin's response is a good idea as well.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038820

function uniqueId() {
    return 'id_' + new Date().getTime();
}

Upvotes: 2

Related Questions