I have following html:
<div class="copy_me_text">
<div>
<input type="text" name="name" />
<input type="hidden" name="id" />
</div>
</div>
<div class="copy_me_hidden">
<div>
<input type="hidden" name="name" />
<input type="hidden" name="id" />
</div>
</div>
And following js code:
var $cloned_text = $('.copy_me_text').clone();
$cloned_text.find('input[name="name"]').val("SOMETHING");
$cloned_text.find('input[name="id"]').val("SOMETHING");
console.log($cloned_text.html());
var $cloned_hidden = $('.copy_me_hidden').clone();
$cloned_hidden.find('input[name="name"]').val("SOMETHING");
$cloned_hidden.find('input[name="id"]').val("SOMETHING");
console.log($cloned_hidden.html());
And output is strange for me:
<div>
<input name="name" type="text">
<input value="SOMETHING" name="id" type="hidden">
</div>
<div>
<input value="SOMETHING" name="name" type="hidden">
<input value="SOMETHING" name="id" type="hidden">
</div>
I create also jsFiddle example.
Is it correct behavior? I don’t understand, why in .html() function, value of input type="text" is not returned.
This is not a strange jQuery behavior, its a strange DOM effect.
jQuery.val()does nothing else than setting thevalueproperty of<input>element. By “property”, I mean the DOM property and not the node attribute – see .prop() vs .attr() for the difference.The
.html()method, which returns theinnerHTMLserialisation of the DOM, is expected to show only attributes of the elements – their properties are irrelevant. This is the default behaviour, and when you want input values serialized you need to explicitly set them as attributes –$input.attr("value", $input.prop("value")).So why did simple
val()work on the hidden input elements? The reason is the HTML specification. There are reflecting IDL attributes, where the DOM property is coupled with the node attribute, but thevalueattribute is none of those. Yet, the value IDL attribute has special modes, in which it reacts differently. To cite the spec:Spot the difference? And now, let’s have a look at the states of the type attribute. And really, if we check the Bookkeeping details sections, we can notice that in the
hiddenstate,‐ while in all other (textual) states the mode is “value”.
TL;DR:
(Only) On
<input type="hidden">elements, setting thevalueDOM property (input.value = …,$input.val(…),$input.prop("value", …)) also sets thevalueattribute and makes it serializable forinnerHTML/.html().