-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[Site]: Explain How to Format Inputs in the Tutorials #6997
Comments
If I understand you correctly, your confusion came from thinking that you only have the possibility to do |
Not quite. I knew about events. However, my confusion was centered on how to format inputs specifically. So for instance, using a credit card format. (That example uses an In other frameworks like In Does that answer your question? |
Maybe we are talking past each other, but what you describe is possible with Svelte, too: <script>
let value = 'world';
function handle(evt) {
if (value.length > 10) {
value = 'nope';
} else {
value = evt.target.value + 1;
}
}
</script>
<input type="text" {value} on:input={handle} /> You don't need to use |
Yeah some additional expounding like what you mentioned could be useful. Regarding your example, my only concern is situations where a person wants to make sure that the value doesn't change. That is, the input is "blocked". In If I understand correctly (maybe I don't), if the developer does nothing in I've seen someone do |
@dummdidumm Honestly, the discussion on #6998 and the related Twitter thread make me a little more nervous about this kinda stuff... especially since this topic is even tricky for well-known To be fair, the inconsistency that occurs when placing The tutorials would greatly benefit from this, since the significance of #2446 is not immediately apparent, nor is it easily searchable in Google -- meaning people will start thinking there are bugs that don't really exist. Input masking/formatting is a perfect candidate to explain this odd scenario, as it's a common use case that already seems to be tripping people up. And it could easily go in one of the sections I previously mentioned. Thoughts? |
What's wrong with using the reactive block to correct the value? https://svelte.dev/repl/282c70030a864507852a2769639d4043?version=3.44.2 If you don't want to overwrite the user's value, you can define two variables, e.g., |
@7nik Two Things
What confuses and surprises me so much is that in regular HTML + JS, the user would have to mutate I may also have to clarify the problem statement. I tried to keep it shorter in order to reduce the amount of reading people have to do. But historically on the Discord, I've had to explain more specific details as the conversation has gone on. But no one has provided a greater solution for this use case than mutating |
The binding is just a way to synchronize a variable and an element's property. It isn't designed for wedging in a logic "to format the input or something". Assigning to If you need more than just synchronize a variable and a property - don't use binding, do it yourself with whatever additional logic you need. And then wrap all the logic into a separate component so you'll have something like Another way I see is using However, it'd be nice if |
I'm not sure this is 100% true. But it's fair to say that people shouldn't need to create state variables [that they aren't using elsewhere/otherwise] every time they want to format an input [in the context of a general page or section of a page]. Even so, the issue isn't just trying to approach formatting strictly by using state variables. The issue is when an input needs to be formatted and the value needs to be synchronized and the input needs to remain "unchanged" when something invalid was entered (whether "unchanged" means literally unchanged, as above, or it means the value was coerced via regex, etc. to a new value that we're hoping the regex, etc. properly determined to be the previous state of the input). To be fair, even outside that use case, it's impossible to [easily] prevent an input from changing if the correct format is not adhered to because an event handler has no knowledge of what the previous state of the input was by itself. Things like regex are an option, but you have to be incredibly clever and specific with how you employ it as the use case gets more complex (like with money, which seems harder than card numbers). And even then, it's possible to run into bugs. With state variables, you're guaranteed that the input's value did not change at all, and with minimal effort.
I'd rather avoid using components because it complicates/restricts styling due to scoping. An
From what I understand, the behavior I suggested isn't buggy at all. An event has already been produced in the scenario I gave, and that event is exactly what will cause the element to update. When
Yes. Dig actions. I'm using them in my app. And from what I can tell, you don't need to pass in the second parameter for storage if you order directives properly (#2446). They're great for re-use, and they don't create the component issue I mentioned earlier. The problem again comes back to intuition, and how easily a user would find the help in a tutorial. I spent a really long time trying to figure out how to format money inputs (inputs in generally, really). I did see a public component. But personally it seems too convoluted. The main point of this issue is that people need a clear way to do validation + formatting. Though, if |
Mkay. Circling back around to this after exploring a few options in my own projects. I think this is still an option for sure... But I probably disagree with it now. There is a different "purist" option that can be used instead... though the easiest way to make it re-usable is yet again through actions. (However, someone could just as will put this in the // formatAction.ts
function formatAction(input: HTMLInputElement) {
let lastValidValue: string;
function handleBeforeInput(event: InputEvent & { target: HTMLInputElement }) {
lastValidValue = event.target.value;
}
function handleInput(event: InputEvent & { target: HTMLInputElement }) {
const { value, selectionStart } = event.target;
if (/* Value does not match required formatting */) {
event.target.value = lastValidValue;
const cursorPlace = selectionStart - (value.length - event.target.value.length);
requestAnimationFrame(() => event.target.setSelectionRange(cursorPlace, cursorPlace));
return;
}
lastValidValue = value;
}
input.addEventListener("beforeinput", handleBeforeInput as EventListener);
input.addEventListener("input", handleInput as EventListener);
return {
destroy() {
input.removeEventListener("beforeinput", handleBeforeInput as EventListener);
input.removeEventListener("input", handleInput as EventListener);
}
};
} <!-- Somewhere in a Svelte file -->
<input type="text" use:formatAction /> Surely there had to have been a way to format (and restrict) This approach seems a bit more verbose? But I'm assuming (?) that since it doesn't involve Maybe some explanation on formatting would be better handled in the |
I think it easily gets missed, so I just want to add the reminder that the key struggle here is how to prevent invalid inputs from the user. Altering inputs is very easy. Prevention (which has valid uses cases across several websites) requires more effort and can't be accomplished through this method. Some mutation of |
Using the |
Describe the problem
It's not readily apparent from the docs how to format
input
s (at least not for beginners). This can be a significant source of frustration/confusion. I think this is especially true for devs coming from other frameworks, where people are used to easily forcing inputs to adhere to state variables.I've spent a good few hours between days trying to figure out how to make a money-formatted
input
element inSvelte
. I almost opened a new issue in ignorance asking for one-way data-binding fromstate
toelement
(like in React forinput
s) until I saw #6197, and then saw Rich mention masking in #2446.Describe the proposed solution
I believe the
Tutorials
would benefit greatly from a brief explanation on this. Intuitively, when I was trying to figure out how to format myinput
s, I searched the part of the tutorials that talked about inputs. Perhaps a new section could be added calledFormatted Inputs
orMasked Inputs
. I know this is under thebinding
s section, but since it relates tobinding
and to the order of directives, I think this is a proper location.Whatever comments are made, the markup would probably include something like
with the script being something like
Alternatives considered
Alternatively, something like
action
s could be used in the tutorial... which might influence the location of this section. The important thing to me would be whatever makes things clearer/easier. I would think that the previous approach would require less of an established foundation for beginners.This information could also be placed somewhere outside of the docs. But it would be great to have some kind of clear base example easily accessible for all people.
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: