3

I want to copy some DOM nodes by html() method. I use val() to modify the input value, then use html() to copy the input node, but the value of the copied input is old!! When I use attr() to modify the input value, then copy it by html(), it looks like RIGHT!

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>

<p id="con1"><input type="text" value="1"></p>
<p id="con2"></p>

<button onclick="doTest1()">test1</button>
<button onclick="doTest2()">test2</button>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
var doTest1 = function() {
  $("#con1 > input").val("2");
  $("#con2").html( $("#con1").html() );
};

var doTest2 = function() {
  $("#con1 > input").attr("value","2");
  $("#con2").html( $("#con1").html() );
};
</script>
</body>
</html>

3 Answers3

3

jQuery implements .html(), .attr() and .val() like,

.html() - element.innerHTML();

.attr(x, y) - element.setAttribute(x, y);

.val(x) - element.value = x;

When you run .html() after you set the value with .val(), you basically just copy the entire element's inner HTML with its not-updated value attribute like (in your sample),

<input type="text" value="1">

And that's why the value would still be 1.

By changing the value with .val() after page load, does not update the attribute value in your input. Even for the element above, if you run,

$('input').val('2'); // <input type="text" value="1">

But if you run with .attr(),

$('input').attr('2'); // <input type="text" value="2">

Note that .html() gets the exact HTML contents of the element.

Community
  • 1
  • 1
choz
  • 17,242
  • 4
  • 53
  • 73
  • 1
    I think this is the correct answer, but it seems like it should be deemed a jQuery bug. – StackSlave Jun 24 '16 at 03:00
  • 1
    Perfect answer! I fully understand it. – lee shinwell Jun 24 '16 at 03:02
  • 1
    @PHPglue Nah, I don't think it should be a bug. Setting an `element.value` in js does not update the HTML contents in the document. While `element.setAttribute` does. – choz Jun 24 '16 at 03:05
  • 1
    That is the same as saying that using the `.html(contentHere)` method should not change the `.html()` method's output. It's just changing the `Element.innerHTML`. – StackSlave Jun 24 '16 at 03:07
1

Use $.clone() instead. Here is an example:

<button type="button" id="btnClone">Clone Input</button>
    <div id="inputContainer">
        <input id="myInput" type="text"/>
    </div>


$('#btnClone').click(function (e) {
    $('#myInput').clone().attr('id', 'myInput2').appendTo('#inputContainer');
})

NOTE When cloning, be cautious of the element you're cloning. For example, if it's got an id attribute, that will be cloned too. This would result in 2 separate elements with the same id.

https://api.jquery.com/clone/

mwilson
  • 12,295
  • 7
  • 55
  • 95
0

var doTest1 = function() {
  $("#con1 > input").val("2");

  $("#con2").html($("#con1").html());
  console.log("con 1 val " + $("#con1 > input").val());
  console.log("con 1 attr " + $("#con1 > input").attr('value'));

  console.log("con 2 val " + $("#con2 > input").val());
  console.log("con 2 attr " + $("#con2 > input").attr('value'));
};

var doTest2 = function() {
  $("#con1 > input").attr("value", "2");
  $("#con2").html($("#con1").html());

  console.log("con 1 val " + $("#con1 > input").val());
  console.log("con 1 attr " + $("#con1 > input").attr('value'));

  console.log("con 2 val " + $("#con2 > input").val());
  console.log("con 2 attr " + $("#con2 > input").attr('value'));
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="con1">
  <input type="text" value="1">
</p>
<p id="con2"></p>

<button onclick="doTest1()">test1</button>
<button onclick="doTest2()">test2</button>

When you look the at console you can see that even if the displayed value change using the method .val() in the html the attr value is still 1 in the first example. So when you copy the html using .html() what it copied is value='1'

While in example 2 when you change the value using .attr() the attr value changed to 2 that is why when you copied it using .html() you get the value='2'

I hope the demo made sense

guradio
  • 15,524
  • 4
  • 36
  • 57