3

On a HTML page i have an input with a value attribute which is changed by some library i use. After the user changes the value of the input the value property is changed.

After some action i want to remove the user provided value property and let the input show the value provided by the attribute again, and from that point on, do that automatically (like it did before the user ever entered a value).

I looked at some other questions like What is the difference between properties and attributes in HTML? . They all give a descent explanation ofthe difference between property and attribute however nothing to remove the user filled property.

Things i have tried (with jQuery in FF):

$("#my-input").removeProp('value'); // This has no effect
$("#my-input").prop('value', null); // Makes the input empty
$("#my-input").prop('value', false); // Sets value to the string "false"
$("#my-input").prop('value', undefined); // Makes the input empty
$("#my-input").prop('value', $("#my-input").attr('value')); // Sets the correct value however if the external library changes the attribute it doesn't change the prop with it

Edit 1

As requested i made a small minimal snippet showing the question better: https://jsfiddle.net/codx3vmg/

Edit 2

I managed to find a snippet which does exactly what i desire with a form: https://jsfiddle.net/9h6py8oc/

However, in my case i do not have my inputs in a form. Can i reset a specific input (without a form)?

connexo
  • 53,704
  • 14
  • 91
  • 128
eKKiM
  • 421
  • 5
  • 18
  • `$("#my-input").val('')` ? Not sure if you are saying you want to remove the `value` attribute entirely or just empty it. Can you show what this input looks like with both the property and attribute you mention in your question? – Kinglish Mar 25 '22 at 20:12
  • `$("#my-input").val('')` will set the content of the input to nothing. Not the value of the value attribute.. – eKKiM Mar 25 '22 at 21:20
  • What kind of input is it? Please add to your question with the element's HTML - or even set a snippet – Kinglish Mar 25 '22 at 21:25
  • It is hard to understand what you are asking without seeing your HTML/code. [Use `.val()` to get/set the value of an input](https://api.jquery.com/val/), there's nothing more to it. If you want to track other stuff, use other attributes, [eg `data-` attributes](https://stackoverflow.com/questions/5309926/how-can-i-get-the-data-id-attribute) are commonly used for this. I'm guessing that doesn't help, if so, please edit your question and try to create a [minimal, complete, and verifiable example](https://stackoverflow.com/help/mcve) showing what you're having trouble with. – Don't Panic Mar 26 '22 at 02:45
  • Have you tried dynamically creating a `form` element, appending the input, calling `reset()` on the form, then appending the input back to its original location and discarding the form element? – connexo Mar 26 '22 at 10:32

3 Answers3

1

After a long chat discussion with OP, in an attempt to clarify their problem, this is what it boiled down to:

  1. An input element that has never been touched by the user syncs the value attribute with the displayed value, and keeps doing so whenever the attribute changes.
  2. This syncing behaviour is lost as soon as the input receives its very first input event.
  3. In a form, the behaviour can be restored using a form reset.
  4. If there is no form, there's currently no way to achieve that.

Your only options to get the behaviour you want are:

  1. Use a mutation observer that watches value attribute changes, and sets the value property accordingly.
  2. Use a custom input (web component) and implement an attributeChangedCallback for the value attribute.
  3. Prevent user input by setting the input to readOnly: input.readOnly = true;
  4. Wrap the input in a dynamically created form element, call reset() on the form, and re-insert the input at its original location. This is a bit ugly because it requires the form to actually be added to the DOM, otherwise calling reset() throws an error.

let c = 1;
btn.addEventListener('click',
  () => {
    const form = document.createElement('form');
    const parent = foo.parentNode;
    const { nextSibling } = foo;
    form.style.display = 'inline';
    form.appendChild(foo);
    parent.prepend(form);
    form.reset();
    if (nextSibling)
      parent.insertBefore(foo, nextSibling)
    else
      parent.prepend(foo);
    form.remove();
  });

setInterval(() => foo.setAttribute('value', c++), 1000);
<input id="foo" value="0">
<button id="btn">Restore untouched behaviour after editing the input</button>
connexo
  • 53,704
  • 14
  • 91
  • 128
0

I do not know jquery but here's the code in javascript

  const input = document.querySelector("#my-input");
  const defaultValue = "default";

     input.addEventListener("keyup", (e) => {
      const userValue = input.value;
      input.setAttribute("value", userValue);
     });
     input.addEventListener("blur", (e) => {
      setTimeout(SetVal, 10000);
     });

     function SetVal() {
      input.setAttribute("value", defaultValue);
     }
Nikhil
  • 60
  • 8
0

You might want to try something like this. This automatically updates the input value back to default in the case where a value is not provided manually by the user. I find this cleaner and more convenient.

var input = $("#input1");

input.on("keyup", (event)=>{
  input.attr("data-user-value",event.target.value);
});

let ctr = 0;
setInterval(() => {
    ctr++;
  input.val(input.attr("data-user-value") || ctr);
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<label>Input</label>
<input 
    data-user-value="" 
    id="input1" 
    value="" />
Mosia Thabo
  • 4,009
  • 1
  • 14
  • 24
  • Have you read https://chat.stackoverflow.com/rooms/243342/discussion-between-connexo-and-ekkim? – connexo Mar 26 '22 at 10:46
  • @connexo if that's the case then I think the above should do the Job as well.. this is just another approach. Your approach is great as well. data-attrs are also very versatile when used correctly. – Mosia Thabo Mar 26 '22 at 11:20