145

Can I set data-* attribute with Thymeleaf?

As I understood from Thymeleaf documentation I tried:

<div th:data-el_id="${element.getId()}"> <!-- doesn't work -->

<div data-th-el_id="${element.getId()}"> <!-- doesn't work -->
Lii
  • 11,553
  • 8
  • 64
  • 88
Alexandru Severin
  • 6,021
  • 11
  • 48
  • 71
  • 8
    This was a bug, [fixed for Thymeleaf 3.0](https://github.com/thymeleaf/thymeleaf/issues/489). This question is relevant only for pre 3.0 version. For newer ones `th:data-el_id` will work. – wi2ard Mar 12 '18 at 15:07

3 Answers3

259

Yes, th:attr to the rescue Thymeleaf documentation - Setting attribute values.

For your scenario, this should do the job:

<div th:attr="data-el_id=${element.getId()}">

XML rules do not allow you to set an attribute twice in a tag, so you can't have more than one th:attr in the same element.

Note: If you want more that one attribute, separate the different attributes by comma:

<div th:attr="data-id=${element.getId()},data-name=${element.getN‌​ame()}"> 
Alexandru Severin
  • 6,021
  • 11
  • 48
  • 71
Aldrian
  • 2,919
  • 1
  • 17
  • 11
  • 61
    Just a note for future readers, you can't have more than one th:attr in the same element so just use one and separate the different attributes by comma: `th:attr="data-id=${element.getId()},data-name=${element.getName()}"` – AntonioOtero Aug 14 '14 at 18:12
  • 6
    If you need to include a variable as part of a string you need to do this: `th:attr="data-id='some-text'+${element.getId()}+'some-other-text',data-name=${element.getName()}"` – kabadisha May 31 '16 at 09:46
  • 1
    @AntonioOtero 's comment should be part of the answer. – Don Cheadle Aug 02 '16 at 20:56
  • I wish attribute processing would not be restricted to certain attributes but rather be generally handled. Has anyone heard that it will be feature? (Well blame on me, I did not check the version 3 yet ;-) – Dirk Schumacher Dec 01 '17 at 12:14
18

With Thymeleaf 3.0 there is the Default Attribute Processor which can be used for any kind of custom attributes, e.g. th:data-el_id="" becomes data-el_id="", th:ng-app="" becomes ng-app="" and so on. There is no need for the beloved data attribute dialect anymore.

This solution I prefer, if I want to use json as the value, instead of:

<div th:attr="data-foobar='{&quot;foo&quot:'+${bar}+'}'">

You can use (in combination with literal substitution):

<div th:data-foobar='|{"foo":${bar}}|'>

Update: If you don't like the th namespace, you can also use HTML5 friendly attribute and element names like data-th-data-foobar="".

If someone is interested, related template engine tests can be found here: Tests for Default Attribute Processor

RiZKiT
  • 2,107
  • 28
  • 23
14

Or you can use this Thymeleaf dialect https://github.com/mxab/thymeleaf-extras-data-attribute and you'll be able do

<div data:el_id="${element.getId()}">
Alexandru Severin
  • 6,021
  • 11
  • 48
  • 71
Adrian Ber
  • 20,474
  • 12
  • 67
  • 117