Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery create a new element with `data` HTML attribute

Tags:

jquery

Preamble

The question is about HTML element creation with an HTML data attribute, like <object data="foo"></object>.

The Question

Quick question as I stumbled across this a few minutes ago; If I write

$('<div>', { id:"foo", 'class':"bar" });
// <div id="foo" class="bar"></div>

However

$('<object>', { id:"foo", data:"some+data+string" });
// [ <object id="foo"></object> ]

where I expected the output to be

// [ <object id="foo" data="some+data+string"></object> ]

I know about .data. My problem is that

$('<object>', { id:"foo", data:"some+data+string" }).data();
// Object {}
$('<object>', { id:"foo", 'data-foo':"some+data+string" }).data();
// Object {foo:"some+data+string"}

So... why does it not create the HTML attribute data since it is not a data-xxxx attribute name, and therefore does not create any actual data?

Update

I'll reiterate what's written in this question once more.

[...] If I write

$('<div>', { id:"foo", 'class':"bar" });
// <div id="foo" class="bar"></div>

However

$('<object>', { id:"foo", data:"some+data+string" });
// [ <object id="foo"></object> ]

where I expected the output to be

// [ <object id="foo" data="some+data+string"></object> ]

... and once again, I know about .data.

Why doesn't $('<div>', { data: 'foo' }) create <div data="foo"></div>, or in other word, why does it ignore the attribute altogether when creating the element?

Edit

For all those arguing that data is not a valid HTML attribute, well, it is.

Update

As of today, the solution I am using for this use case is

$('<div>', {
  attr: {
    data: 'foo'
  }
});
like image 777
Yanick Rochon Avatar asked Apr 05 '14 20:04

Yanick Rochon


1 Answers

When creating an element and passing an object with attributes and methods, any jQuery method is valid, so you can do

$('<div />', { 
    id      : "foo",  
    'class' : "bar",
    text    : "test",          // jQuery text() is called,
    html    : '<span></span>', // jQuery html() is called,
    css     : {                // jQuery css() is called,
        color: 'red'
    },
    on : {                     // calls jQuery's .on('click' ...
        click: function() {
             alert
        }
    }
});

In the same way, data="" is not a common attribute, it's only valid on a few elements, like <object>, and jQuery doesn't seem to account for this, so you can't set a data="" attribute as jQuery will catch the data() method first.

In other words, this doesn't work, instead it sets the internal data object using data()

$('<object />', {data : 'somedata'});

A rather strange workaround is that this seems to be case sensitive, so jQuery will only look for the methods if the key is all lowercase, and on the other hand, jQuery attr() will always lowercase attributes, so doing any of these

$('<object>', { id:"foo", 'Data' : "some+data+string" });
$('<object>', { id:"foo", 'daTa' : "some+data+string" });

will actually work, and the attribute will be lower cased when set, so you end up with

<object id="foo" data="some+data+string"></object>

FIDDLE

like image 147
adeneo Avatar answered Jan 01 '23 09:01

adeneo