I am trying to use document.cloneNode(true) to clone/make a copy of an existing html page containing forms but that doesn’t capture user inputs.
I have a js script embedded in a html page with form and am trying to use document.cloneNode(true) to clone that page and save it in a s3 bucket. When user clicks on submit button the js function runs to clone the html page.
Issue is that the cloneNode() doesn’t include the user inputs while cloning the HTML page. I checked the docs – https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode but didn’t find the handling of this use case.
Is this behaviour of cloneNode() expected? If so how can I achieve my requirement of having the user inputs like this –
<input type='text' value='John Doe'>
instead of
<input type='text'>
Do I have to manually set the value in every input field? There can be different types of inputs like checkbox, dates, etc so I think there should be a better way to achieve this.
>Solution :
The value of an input element is not reflected in its value attribute (or any other), despite the name. The value attribute provides the default value of an input, not its current value, even though the value property of an HTMLInputElement instance does give you the current value. This is one of the confusing things about the DOM. Here’s the breakdown:
| Item | Attribute | Property |
|---|---|---|
| Default value | value |
defaultValue |
| Current value | none | value |
If you want an HTML string that captures the user’s current input text on input elements (and their currently-selected items on select elements), you’ll have to implement that functionality yourself, perhaps with data-* attributes.
Here’s a quick-and-dirty example for input elements:
// Respond to the `input` event by updating an attribute on the
// input element
document.addEventListener("input", ({target}) => {
if (target instanceof HTMLInputElement) {
target.setAttribute("data-current-value", target.value);
}
});
// Hook up the button to show the HTML:
document.querySelector("[value='Show HTML']").addEventListener("click", () => {
for (const input of document.querySelectorAll("input[type=text]")) {
console.log(input.outerHTML);
}
});
A: <input type="text" name="a">
<br>
B: <input type="text" name="b">
<br>
<div><input type="button" value="Show HTML"></div>
In that example, I grab the values as they change, but you could do it just before cloning the document as well.