Reputation: 1930
I'm trying to build a 12 hour input component in Javascript and I want to validate the format in real time, as the user types, like a parser validates incoming tokens.
I'm using react, so in each render the field value gets passed trhough the following regex:
const validTime = /(0[1-9])|(1[0-2]):([0-5][0-9])\s((a|p|A|P)(m|M))/;
I test if the value is valid, if not I add a red border to the input, but with this approach I can write anything, it wouldn't get submitted but you could write something like ajsjjsdf, and I'm looking for something different. Allow the user to type only the characters allowed by the regex rule above in real time.
Edit:
I'm adding some code...
Basically the input simpliefied is:
<input
ref={(input) => {this[keyName] = input}}
className="form-control"
placeholder="09:00 AM"
value={scheduleTime ? scheduleTime.value : ''}
onChange={(ev) => this.onChangeTimeSchedule(ev, keyName)}/>
And the value handler:
onChangeTimeSchedule = (ev, scheduleKey) => {
const validChar = /[0-9]|[aApPmM]|[\s\b]|:/;
const validTime = /(0[1-9])|(1[0-2]):([0-5][0-9])\s((a|p|A|P)(m|M))/;
const { value } = ev.target;
if(!validTime.test(value))
return;
const { schedule } = this.state;
schedule[scheduleKey] = {value, invalid: false};
this.setState({schedule});
};
if I use validChar it would only allow the characters I want, but it would allow strings like 10:aaaM.
If I use validTime (this is the check I do for each render, to add a red border if invalid) in this context, I always returns false, because it excepts a full match: 10:0 is wrong, 10:00 PM is correct.
Upvotes: 0
Views: 1754
Reputation:
This is one way to do it. Set it to case insensitive.
^(0(?:[1-9]|$)|1(?:[0-2]|$))(?:(:)(?:([0-5])(?:([0-9])(?:(\s)([ap]m?)?)?)?)?)?$
What you can get with this:
There are 2 ways to use this regex.
$
in the regex, allowing a partial match.Formatted / explained :
^ # BOS
( # (1 start)
# Hours
( # (2 start)
0
(?: [1-9] | $ )
| 1
(?: [0-2] | $ )
) # (2 end)
# Minutes
(?:
: # ':'
(?:
( [0-5] ) # (3), Min,digit 1
(?:
( [0-9] ) # (4), Min,digit 2
(?:
\s # space
( # (5 start), AM / PM
[ap] m?
)? # (5 end)
)?
)?
)?
)?
) # (1 end)
$ # EOS
Upvotes: 1