Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: 'type' attribute cannot be dynamic if input uses two-way binding

Tags:

svelte

I was trying to create an Input component for my project. I want to set type attribute dyamically on input element

But when i set type attribute dynamically on input i get error saying 'type' attribute cannot be dynamic if input uses two-way binding

So is there any workaround for this such that i can set type attribute dynamically without loosing two way binding

Input.svelte

<script>
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";
</script>

<div class="container">
    <label>{label}</label>
    <input {type} bind:value {placeholder} />
    <p>{description}</p>
</div>
like image 463
GAGANDEEP SINGH Avatar asked Aug 07 '19 10:08

GAGANDEEP SINGH


2 Answers

The reason type must be static with two-way binding is that the code Svelte generates is different for different kinds of input. For example, number and range inputs must have their values coerced to a number, some inputs need change event listeners instead of input events or vice versa, and so on.

But you can manually do the same thing the generated code would have been doing — adding an event listener that reflects state:

<script>
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";

  const handleInput = e => {
    // in here, you can switch on type and implement
    // whatever behaviour you need
    value = type.match(/^(number|range)$/)
      ? +e.target.value
      : e.target.value;
  };
</script>

<div class="container">
    <label>{label}</label>
    <input {type} {value} {placeholder} on:input={handleInput} />
    <p>{description}</p>
</div>
like image 150
Rich Harris Avatar answered Oct 12 '22 23:10

Rich Harris


use a function in your component to set the node type:

Input.svelte:

<script>
    export let type = 'text'
    export let label
    export let value

    function typeAction(node) {
        node.type = type;
    }
</script>

<div class="space-y-1">
    <label>{label}</label>

    <input use:typeAction bind:value class="rounded-md w-full">

    <p class="text-sm text-red-600">errors</p>
</div>

Form.svelte:

    <form on:submit|preventDefault={login}>
        <Input type="email" label="Email" bind:value={values.email}/>
        <Input type="password" label="Password" bind:value={values.password}/>

        <Button type="submit" label="Login"/>
    </form>
like image 30
kjdion84 Avatar answered Oct 12 '22 22:10

kjdion84