question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide a way to dynamically set input type (with or without two way binding)

See original GitHub issue

Is your feature request related to a problem? Please describe.

I am currently making a Input.svelte component to manage common logic:

<script>
  export let id;
  export let label;
  export let type = 'text';
  export let value = '';
  export let revealed = false;

  const revealToggle = (event) => {
    const input = event.currentTarget.previousElementSibling;

    if (!input) {
      return;
    }

    input.type = input.type === 'password' ? 'text' : 'password';
    revealed = !revealed;
  }
</script>

<style>
  button:focus {
    outline: 0 !important;
  }
</style>

<label class="block mb-2" for="{id}">{label}</label>
<div class="flex mb-4">
  {#if type === 'password'}
    <input
      {id}
      type="password"
      placeholder="{label}"
      bind:value
      class="rounded-r-none border-r-0"
    >
    <button
      title="Afficher le mot de passe"
      type="button"
      class="border border-gray-400 rounded rounded-l-none px-3 text-gray-500"
      on:click={revealToggle}
    >
      <i class="fa fa-fw {revealed ? 'fa-eye' : 'fa-eye-slash'}"></i>
    </button>
  {:else}
    <input {id} type="text" placeholder="{label}" bind:value>
  {/if}
</div>

It is currently not possible to assign a prop to the type html attribute as you well answered here: https://stackoverflow.com/a/57393751/1731473

Otherwise, it will produce this error:

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

But it is still possible to do “dynamic” type attribute with a basic if/else logic as you can see in my example.

So I don’t understand why things are not simpler. Nowadays, with html5, we have a ton of “text similar input” like date, email, or tel: https://www.w3schools.com/html/html_form_input_types.asp

I would like to avoid to make a if forest if I only need to change the type attribute.

Also, maybe a good place for an another issue, but I can’t find an easier way to pass input related directly to the right DOM element in my component without declaring each of them manually (min, max, required etc…), but I don’t know if this is doable.

Describe the solution you’d like

Allow to do something like this:

<input {id} {type} placeholder="{label}" bind:value>

With or without two-way binding. The goal is to quickly define what type I want from my input component:

<script>
  import Input from './Input.svelte';
</script>

<Input type="text" ... />

Describe alternatives you’ve considered

The only alternative I found is what you have on my example.

Maybe it’s a design issue from my own. In that case, some good advices on this issue and the documentation would be very welcome. 👍

How important is this feature to you?

It is not very urgent, but I think this is quite useful in order to avoid code repetition on big projects.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:8
  • Comments:15 (1 by maintainers)

github_iconTop GitHub Comments

12reactions
TIOvOITcommented, Apr 2, 2020

I also encountered this problem, so I solved it:

Input component:

<script>
  import { onMount } from "svelte";
	
  export let inputType= "text";
  export let value = "";
	
  let inputElement;
  onMount(() => {
    inputElement.type = inputType;
  });
</script>

<input
  on:keyup
  on:change
  bind:value 
  bind:this={inputElement}/>

External call:

<script>
	import Input from "./Input.svelte";
	let value = "";
	let text = "";
	function foo(){
		if(value.length < 4){
			text="Passwod too short";
		}else{
			text="";
		}
	}
</script>

<Input bind:value inputType='password' on:change={foo}/>
<p>{text}</p>

I don’t know if this is really correct,superficially works.

10reactions
vince83110commented, Jul 15, 2021

Solution found on youtube for this problem, and works correctly in 2021 :

export let type = 'text';

const setType = (node) => {
  node.type = type;
};

<input
  bind:value
  use:setType
/>
Read more comments on GitHub >

github_iconTop Results From Across the Web

error: 'type' attribute cannot be dynamic if input uses two- ...
The reason type must be static with two-way binding is that the code Svelte generates is different for different kinds of input.
Read more >
dynamic type two-way binding • REPL ...
1. <script> ; 2. import Input from './Input.svelte'; ; 3 ; 4. let json = {username: '', password: '', email: ''}; ; 5....
Read more >
Two-way binding
Two -way binding gives components in your application a way to share data. ... The size property is an @Input() , so data...
Read more >
Keeping Data in Sync with Two-way Binding Using Ngmodel
Keeping the data in sync between the UI and control is very important in a form. It's crucial to change the value of...
Read more >
Two-way data binding
Annotate the method that sets the initial value and updates when the value changes using @BindingAdapter : Kotlin Java More. @BindingAdapter(" ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found