-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Provide a way to dynamically set input type (with or without two way binding) #3921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@soullivaneuh I've created an example with your component: https://svelte.dev/repl/b220a2c7855a47fcbb713648d33aba49?version=3.14.1 You can use a dynamic Moreover, you can write a component which handles all kind of input types: https://svelte.dev/repl/31ee5896ee5c4364bf6d73538c895bd5?version=3.14.1 |
The proposal here, I guess, is to allow dynamic |
Thanks for the samples @rise2semi, I indeed didn't understand that way. Still, it's kinda workaround to me. It would be great to have this natively managed by Svelte, this is why I opened this issue. 👍 At least, the current possible implementation is a good candidate for the official documentation/tutorial/examples as this seems to be a quite common case. |
I also encountered this problem, so I solved it: Input component:
External call:
I don't know if this is really correct,superficially works. |
I would also like to see this, for all of the reasons @soullivaneuh listed. |
If the only issue is the difference between number-based inputs (range, number, etc.), text-based (text, email, password, etc.), and [insert type here]-based inputs, the API should make it possible to switch between all input types that all produce the same type for One option would be to drop the compile-time dynamic-input-type check entirely and let the user run into an error if they end up changing the type to something incompatible. A warning about this could be added to the documentation. Another option would be to generate slightly less efficient code i.e. change the automatically generated handler any time the type changes. Another option (which I'm not sure is possible) is to make the |
I want to thank the svelte team for making it so that numbers-typed inputs return numbers. But in this particular instance, if it's causing an issue like this then I'm 100% for letting developers deal with the conversion of number-based types, which is what they would have to do using vanilla JS anyway, and I'm pretty sure even React just has you (the developer) handle the numbers yourself. I'm interested in checking out the code responsible, perhaps there's a way for the numbered returns and also a way to dynamically set the type on inputs without needing any of the above work arounds? |
@jhechtf the dynamic thing might the perfect solution. If svelte detects that an input's type is two-way bound, it should simply generate an input handler that checks the type each time. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Solution found on youtube for this problem, and works correctly in 2021 :
|
I encountered this same problem yesterday and think I found a reasonable workaround pattern for those who want to implement their own "Input"/"Field" components. Problem: Having a Solution: rather than have a component like // parent.svelte
// problem: dynamic type attribute error
<Field id="email" label="Email" type="password" bind:value={values.password} /> you could instead move the declaration of the input (with all it's props) into the parent component as a slotted child component that renders into a // parent.svelte
// solution: no error, no forwarding of props needed etc.
<Field id="password" label="Password">
<input id="password" type="password" bind:value={values.password} />
</Field>
// field.svelte
<div class="flex flex-col space-y-1">
{#if label || $$slots.label}
<div class="flex flex-row items-center justify-between">
<label for={id}>
<slot name="label">{label}</slot>
</label>
<slot name="aside" />
</div>
{/if}
<slot />
</div> This allows me to still standardise my fields and how they render, and avoid dealing with cumbersome management of input props and forwarding event handlers etc. When it comes to styles, rather than pass class names to given slotted In the original case of wanting to render additional content based on // field.svelte
<div> // flex row
<slot />
<slot name="input-after" />
</div>
// parent.svelte
<Field id="password" label="Password">
<input id="password" type="password" bind:value={values.password} />
<button slot="input-after" on:click={...}>Show/Hide</button>
</Field> Or even wrap up such logic into another component like This has worked for me so far, however I'm still just learning about svelte (and love it so far) and would be open to seeing how others approach what I can presume is a fairly common |
@vince83110 your answer is a neat trick! Just one remark: Most likely you have custom stylings on your inputs based on type e.g for |
You can also get around this is just to do |
Export input to a standalone component, and then handle the input manually instead of binding, then you can set dynamic type. See example here: |
All the solution/workaround proposed above will always return a Because numeric inputs should return a number, like in Svelte Tutorial Related issue: |
What's the downside of using this approach? |
If you do |
Tuve que hacer un hack para poder hacer un bind del value mientras hay un type dinámico en el input por este issue levantando que tienen: sveltejs/svelte#3921  
Is this creating any problems on the compilation side other than returning a string instead of number ? Specially on Svelte 4?
|
Is your feature request related to a problem? Please describe.
I am currently making a
Input.svelte
component to manage common logic:It is currently not possible to assign a prop to the
type
html attribute as you well answered here: https://stackoverflow.com/a/57393751/1731473Otherwise, it will produce this error:
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
, ortel
: https://www.w3schools.com/html/html_form_input_types.aspI would like to avoid to make a
if
forest if I only need to change thetype
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:
With or without two-way binding. The goal is to quickly define what type I want from my input component:
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.
The text was updated successfully, but these errors were encountered: