Implement Conditional Logic in a Zag.js Action to Enforce a Single Character Per Input

Segun Adebayo
InstructorSegun Adebayo
Share this video with your friends

Social Share Links

Send Tweet
Published a year ago
Updated a year ago

We have a bug in our pin input. Only 1 value should be allowed per input but if we focus an input that already has a value we can still input another value.

Let's fix that.

We'll need to implement a function getNextValue that will take in the focused value of the current input and the event input that is coming in. After a set of conditionals we will select the value that wasn't the current focused value to update the field.

Instructor: [0:00] One thing we're going to notice here is if we type one, two, three, four and head back to any previously viewed input. Let's say two here, and we type nine. While we see that the focus moves to three, we can still see nine and two, which in this case means multiple characters are showing up in a previously viewed input.

[0:21] This shouldn't be the case. Let's see how we can troubleshoot this and get this fixed. If we take a look at the flow of logic, looking through the unchanged handler, we are only just passing through everything that is sent from the event target.

[0:36] So that means every character that entered into that input regardless of the number of characters, whether it's one or two characters or even three characters, we're just sending that over into the machine. If we trace our step back into the input transition for the machine, if we scroll down here to input, we call setFocusValue.

[0:56] If we trace our step back into the input transition for the machine, if we scroll down here to input, we call setFocusValue. If we trace it back down to setFocusValue, what is happening here, we're basically just forwarding through the event value all the way into the focus index.

[1:09] Now that's the reason why this bug is happening. What we want to achieve is if I've got two in the input and the next time around I try to type two, nine, the result of that computation or the function we're going to write now should give us nine.

[1:28] In a similar fashion, if I've got two in the input and the next time I typed nine before the two, which means the character was somewhere here and I pressed nine, the result should also give me nine. The key takeaway here is we're only allowing the new character to go through.

[1:48] Obviously, another test case would be if I've got two and I type two, two, the output of that should also be two. This is the function here we need to write. We need to write a function to satisfy these use cases.

[2:02] Let's start by extracting the event value. We see here that the event value, we know that's a string, is equal to event.value. We're also going to grab the current focus value of the input. The value that is at the index we're currently looking at, that would match context.value looking into context.focus index.

[2:27] This is the value that is currently in the input we're focused on and this is the value that's coming in through the onChange handler. Then we're going to create a new variable for the next value. We're going to create a function called getNextValue, passing in the current value, which is the focus value and the event value.

[2:49] Here, we're going to write this function to figure out what the next value should be based on the logic we just outlined here. Then I'm going to set the next value in here, like so. Now, let's try to figure out how to write this getNextValue function.

[3:06] I'll copy out all this logic so it's pretty clear and easy for us to figure out. I'll come all the way to the bottom here, create a function called getNextValue, passing in the focus value, which is a string and the event value, which is also a string. There if I paste the scenarios up there, we're able to figure out all the different pieces that we want.

[3:32] We'll start by defining a next value variable here, assigning it to the event value. Then we do a check if the focus value, the first character of the focus value is equal to the first character of the event value, which in this case is pointing to this first scenario right here, which you got two first and then you type nine after two.

[3:58] We see the first value here, the first characters, they are equal. In this scenario, we actually want to set the next value to be equal to the event value, next character or second character. What this reads, it reads like if you got two there and the next time you type nine after two, we actually want to pick nine, which is a second character there at index one.

[4:23] Then we change this with the else if here, checking again if the focus value's first character is equal to the event value, second character, we want to set the next value to be equal to the event value, first character.

[4:43] Now, what we've written here satisfies the second condition. At first, we have two in the input and then I type nine just before two. In this scenario, the first character of the focus value, which was initially the current value, and then the second character of the event value, we're just going to create or compute the differences between that and again end at nine.

[5:08] So that gets us to the first scenario. If we move the comments, so it's pretty easy to read, we're just going to move the comment down into each of those. Then here we're basically going to return the next value.

[5:25] In this scenario, we have everything sorted out as expected. Let's just give it a try and see what it looks like.

[5:32] Now, if you go into the input and type one, two, three, four, come here into the second field and type nine. What you see now is the character gets replaced correctly. Let's try the other scenario again. If I come here to nine and place the cursor right after nine and then press...let's say we press two.

[5:56] Now what we see again is that the value gets replaced correctly. Now, we have some of the functions exactly as we want. This means we can press five, six, seven, eight and all characters gets replaced correctly, which is awesome.

[6:11] A nice addition we can also add to the application is to come here and add a max length to the input, set the max length to two. This means we can only enter two characters per time. This further tightens the components.

egghead
egghead
~ an hour ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today