Search code examples
jqueryhtmlcontenteditablecustom-data-attribute

contenteditable - updating data-* attributes using jquery


I'm buliding some basic rich text editing functionality for a client using contenteditable. One of the features requires changing the value of data-* attributes of a button, e.g. <button data-type="telephone">Text</button>

I've created a minimal example below - this creates a contenteditable area, then jquery attempts to update the <button>, before printing the updated HTML to the #output div.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>contenteditable data-* test</title>
</head>
<body>

<div id="input" contenteditable>
  <p>Some text!</p>
  <button data-url="/go-somewhere">Button text!</button>
  <p>More text!</p>
</div>

<hr>

<div id="output" style="font-family: monospace;">
</div>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

<script>
$(document).ready( function(){

  // --- Update the button --- //

  // 1. Add new data attribute: data-new="test!"
  $( '#input button' ).data( 'new', 'test!' );

  // 2. Update existing data attribute: data-url="/somewhere-else"
  $( '#input button' ).data( 'url', '/somewhere-else' );

  // 3. Add a class
  $( '#input button' ).addClass( 'new-class' );

  // --- Display the updated content --- //

  $( '#output' ).html( 
    $( '#input' ).html().replace( /</g, '&lt;' ).replace( />/g, '&gt;' ) 
  );
});
</script>

</body>
</html>

The results are:

  • jquery fails to add the new data-new="test!" attribute
  • jquery fails to update the existing data-url attribute
  • jquery does manage to add class="new-class" using addClass()

How can I add/update the data-* attributes?


Solution

  • Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr.

    So, to add/update, you use .attr(attribute, value):

    $( '#input button' ).attr( 'data-new', 'test!' );
    $( '#input button' ).attr( 'data-url', '/somewhere-else' );
    

    Since jQuery 1.4.3, data-* attributes are used to initialize jQuery data. An element's data-* attributes are retrieved the first time the data() method is invoked upon it, and then are no longer accessed or mutated (all values are stored internally by jQuery).

    Referece