Dylaan Alith
Dylaan Alith

Reputation: 13

Can't set element ID in JavaScript, it's always undefined

I want to have a function that generates ID's on the fly for a given jquery object, if it doesn't have one already. These ID's should then be used in future requests.

I came up with the code below, but it doesn't work. The ID's are never set. The commented out alert statement below always return undefined.

I always pass code like $(this) or $(options.el) as a parameter to substitute 'el'. Initially, the elements do not have explicitly ID set in HTML.

Any help would be appreciated, here's the code:

getElementId: function(el) 
{
   if(undefined == el.attr('id'))
   {
      el.attr('id',"anim-"+Math.random().toString().substr(2));
   }
   // alert(el.attr('id'));
   return el.attr('id');
},

Upvotes: 1

Views: 2607

Answers (5)

Matt Ball
Matt Ball

Reputation: 360056

Test the truthiness of the valued returned by .attr(), and make sure that el is actually a jQuery object.

getElementId: function(el) 
{
   if (!el.jquery)
   {
       el = $(el);
   }
   
   if(!el.attr('id'))
   {
      el.attr('id',"anim-"+Math.random().toString().substr(2));
   }
   // alert(el.attr('id'));
   return el.attr('id');
},

Depending on the attribute you're trying to retrieve, .attr() may return undefined or "".


Other recommended cleanup:

getElementId: function(el) 
{
   if (!el.jquery)
   {
       el = $(el);
   }
   
   var id = el.attr('id');
   
   if(!id)
   {
      // make sure this ID hasn't actually been used before!
      do
      {
          id = "anim-"+Math.random().toString().substr(2);
      } while (!$('#' + id).length);
      el.attr('id', id);
   }
   
   return id;
},

You really need to make sure that you're not assigning an ID to that element which has already been used before. The above function does this. A simpler way to accomplish the same thing is to use an incrementing counter stored somewhere outside of the scope of the function:

__idCounter__: 1,
getElementId: function(el) 
{
   if (!el.jquery)
   {
       el = $(el);
   }
   
   var id = el.attr('id');
   
   if(!id)
   {
      id = "anim-" + (this.__idCounter__++);
      el.attr('id', id);
   }
   
   return id;
},

Last edit (I promise)

There seems to be confusion about what .attr() returns when an element does not have the attribute requested. After running some tests, it looks like .attr() returns:

  • the empty string for at least id and class (perhaps other HTML4-spec attributes as well; didn't test)
  • undefined for other attributes not defined by the spec

Output from my tests:

<div id="myID"/> id: myID
<div id="myID"/> class: 
<div id="myID"/> data-attr: undefined
<div id="myID"/> asdf: undefined

<div class="myClass"/> id: 
<div class="myClass"/> class: myClass
<div class="myClass"/> data-attr: undefined
<div class="myClass"/> asdf: undefined

<div data-attr="myAttr"/> id: 
<div data-attr="myAttr"/> class: 
<div data-attr="myAttr"/> data-attr: myAttr
<div data-attr="myAttr"/> asdf: undefined

<div asdf="myNonSpecAttr"/> id: 
<div asdf="myNonSpecAttr"/> class: 
<div asdf="myNonSpecAttr"/> data-attr: undefined
<div asdf="myNonSpecAttr"/> asdf: myNonSpecAttr

tl;dr

Just test the truthiness of the value returned by .attr(), since that treats undefined and "" (the empty string) the same:

if (somejQueryElt.attr('someAttr'))
{
    // it definitely has the attribute
}
else
{
    // it definitely does not have the attribute
}

Upvotes: 4

Imrul
Imrul

Reputation: 3516

To find any element/attribute exists in DOM you need to use length property : Proper condition is :

if (el.attr('id').length > 0 )

Full function:

getElementId: function (el) {
    return el.attr('id').length > 0 ? el.attr('id') : el.attr('id', "anim-" + Math.random().toString().substr(2));
}

Upvotes: 1

epascarello
epascarello

Reputation: 207557

Adding a simple debugging statement in your code would show you why no id is being set.

getElementId: function(el) 
{
   alert(el.attr('id'));
   if(console)console.log(el.attr('id'));
   if(undefined == el.attr('id'))
   {
      el.attr('id',"anim-"+Math.random().toString().substr(2));
   }
   // alert(el.attr('id'));
   return el.attr('id');
},

You will see the alert does not return undefined. It returns an empty string

getElementId: function(el) 
{
   var id = el.attr('id');
   if(id.length===0)
   {
      id="anim-"+Math.random().toString().substr(2);               
      el.attr('id',id);
   }
   return id;
},

I also hope you know that math.random is really not random. You should have some sort of counter.

Upvotes: 0

pimvdb
pimvdb

Reputation: 154968

Try changing:

if(undefined == el.attr('id'))

to:

if("" == el.attr('id'))

Upvotes: 2

Rendicahya
Rendicahya

Reputation: 4285

Maybe your condition should be like this:

if (typeof el.attr('id') === 'undefined')

Upvotes: -1

Related Questions