Search code examples
htmlformsinputresetsvelte

How to force inline html attribute in Svelte


I want to use the browsers native support for resetting all fields' values of a form to their default or initial state using an <input type"reset"> element.

In HTML

In native HTML, clicking the reset input will remove any user input and reset the field to whatever is set in as the value inline parameter: value='default value', and if it's empty or missing, it will reset to an empty field.

input{
  display:block;
  margin:10px;
}
<form>
  <input type="text" value="default value">
  <input type="text" value="">
  <input type="text">
  <input type="reset">
  
</form>

In Svelte

In Svelte, the value attribute seems to never be printed in the html. As a results, clicking the reset input will empty every fields instead of reseting them to their initial values. Here's an example in Svelte REPL

So is there a way to force the native behaviour without handling it with javascript? is there a way to force svelte to print an inline attribute and never update it?


Solution

  • To my knowledge, Svelte doesn't have a built-in way to force setting the attribute instead of a property. If you look at the generated code in the REPL, it always sets the value property when value="something" is used.

    You can force setting the attribute using a custom action.

    function valueAttr(node, val) {
        node.setAttribute('value', val);
    
        return {
            update: function(val) {
                node.setAttribute('value', val);
            }
        }
    }
    

    See below for how the action can be applied to the input element. You will use this action instead of setting value="something" in the template. When the element is mounted, the function will run and set the value attribute on the element. The update function is optional, but will re-set the value attribute when the value passed to it changes.

    <script>
        let dvalue = 'default value';
        
        function valueAttr(node, val) {
            // see definition above
        }
    </script>
    <form>
        <input type="text" use:valueAttr={dvalue}>
        <input type="text" use:valueAttr={"default value"}>
        <input type="text">
        <input type="reset">    
    </form>
    

    Updating your REPL code to use this action makes the reset input function correctly.