How to Optimize a React Date Picker
We'll discuss a few small changes that can be made to optimize the date pickers for when a user is to book a certain listing.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two with a single-time purchase.
[00:00 - 00:16] In this short lesson, we'll spend a little time talking about one thing we can do with regards to the date pickers when a user is able to book a listing within a certain listing page. Now, one comment we made during the course was sort of the capability to prevent a user from booking a date that is at a certain point in the future.
[00:17 - 00:30] So, for example, assuming our application, we wanted to have a restriction and say, users can't book listings a year from now, or maybe six months from now, or a month from now. And to actually convey this capability is fairly straightforward.
[00:31 - 00:49] And we can make some simple changes both on the server project and the client projects. Now, in the server project, if we recall, the create booking mutation function is the one that's fired when the user provides the booking details that they want, the check-in and check-out dates, as well as the valid payment information from the Stripe element.
[00:50 - 00:56] And only then when they confirm their booking is this mutation fired. And this mutation function was part of the booking resolver's map.
[00:57 - 01:03] We've set up in the source graph, cool resolver's booking directory. And in this particular function, we do a bunch of different checks.
[01:04 - 01:07] We authorize the viewer making the request. We try to find the listing that's being booked.
[01:08 - 01:19] We try to verify the viewer can't book their own listing, etc, etc. And one of the check we made before as well is we basically try to make sure that the check-out date that was selected isn't before the check-in date.
[01:20 - 01:29] And the comparison we've done before is just basically get the date object representation of each of these and just make sure one is less than the other. So make sure that check-out date isn't before or less than check-in dates.
[01:30 - 01:42] And what we can do here is add two more additional checks that basically check the fact that the user isn't selecting a check-in or check-out date that is a certain time in the future. And we'll just say 90 days for this example.
[01:43 - 01:58] And we can make this check by essentially getting the time representation and comparing the check-in time that the user has made and make sure that they haven't selected it, that it's 90 days from today's time. How do we get today's time? We basically run the date object constructor in JavaScript.
[01:59 - 02:16] And what we've done before when it comes to comparing times, since we don't have moments in our server, is we just use the get time function available in JavaScript to get the millisecond representation of these dates from a certain time in the past, which is the Unix epoch. And this millisecond format essentially allows us to make these comparisons.
[02:17 - 02:33] So what we can simply say is if the check-in date is greater than the dates for today and 90 days in the future, and how do we make the 90 days into the future check ? We just basically multiply the number of milliseconds per day with 90, which is 90 days.
[02:34 - 02:43] And if this was to ever happen, we'll throw an error and say check-in dates can 't be more than 90 days from today. And we can do something very similar for the check-out date because it's practically the same.
[02:44 - 02:59] Here we can say if the check-out date, millisecond value is greater than today 's date, millisecond value plus 90 times the milliseconds per day, we'll throw an error and say check-out date can't be more than 90 seconds per day or from today. Now, what is this milliseconds per day constant?
[03:00 - 03:05] We've used this value before. So in this particular example, we can just make it a constant value that can be used anywhere in this file.
[03:06 - 03:17] And it's essentially the number of milliseconds for a single day, which is practically 8.64 times 10 to the power of 7. Now, we're doing this in the server because once again, we don't have a lot of day comparisons and this does the job for us.
[03:18 - 03:34] However, if this was to be used quite a bit in our server application, we would probably install a comparison date library in JavaScript, most likely moment JS and make these comparisons for us. Now, with this server side work done, we can also do some simple client side work as well.
[03:35 - 03:48] Now, if you recall, this section in the listing page is essentially the listing creates a booking child component you've created. There's a child of the actual parent to listing component that's rendered in the listing ID routes.
[03:49 - 03:55] And in this listing create booking component, we render essentially two date pickers from anti-sign. And this is what we've done from before.
[03:56 - 04:12] And these date pickers and anti-sign are pretty robust because they give us a lot of UI capabilities as well as other capabilities to make sure we're disabling certain dates, we're allowing you to select dates, etc. And there's a disabled date prop that allowed us to basically specify which dates in these date pickers can be disabled.
[04:13 - 04:38] And the function we had before essentially made sure to check that any dates before the end of day, which essentially any date before today, as well as any date that's already been booked, will be actually disabled. We can just add one other check here and basically be like, if a date is more than three months ahead, 90 days ahead, and we can do this with moment now because we have the moment's library in our client, we can just say basically get the moment of the date that's being iterated.
[04:39 - 04:47] Now as a quick recall, this disabled date function is run for every single date in the grid that opens up in the date picker. We just basically get that date value.
[04:48 - 05:08] And in this case, say if this particular current date is after the end of days to date date and you add 90 days, we'll want it to be disabled as well. And some other small changes we can make to the date picker elements to make them a little bit more, I guess, UI focus to the user is use some of the other props and anti-zine gives us.
[05:09 - 05:20] So there's one other prop that we haven't used before called render extra foot er that allows us to basically render some extra information in the footer of the date pickers. And we can do this by just simply applying a function that returns a react node .
[05:21 - 05:28] And in this react node for the check in date picker, we can just have a footer that basically conveys to the user. You can only book a listing within 90 days from today.
[05:29 - 05:49] And very similar on the checkout date picker, we can have another simple message to convey to the user that, Hey, check out cannot be before check in. And the one other thing we can do with the checkout date picker, which can be pretty useful, is we can use a date to render prop function, but essentially allows us to basically control the UI for an actual date element to render in the grid.
[05:50 - 06:02] And why would we do this for the checkout date picker? Because what we can try and do is basically say, if the user has selected the date for check in, let's just show a different UI element to convey to the user that this is the check in date that they've selected.
[06:03 - 06:13] And what we can do here to make that happen is this date render function essentially gets the current date being rendered in the grid. We just simply make sure to check is this current date within the grid the same as the check in date that will select it.
[06:14 - 06:22] If so, we'll want this element here to render the div that shows the current date value. However, we'll also want to show maybe a tool tip that says check in dates.
[06:23 - 06:34] And we can perhaps add another class that we can create to just sort of give this element its own unique styling. And this particular class here and calendar date is from the and design library .
[06:35 - 06:44] It gives us the UI for how each date element looks. And then we can just add an extra class for the check in date date here to basically convey that there's the data the user has selected.
[06:45 - 07:00] And last but not least, if this current date is not the date that's been selected, it'll just simply show the original element before without the tool tip and without the additional class. Now, tool tip is a component that and design provides that essentially provides a tool tip message over a certain element.
[07:01 - 07:11] So let's just see what we've done here and just see how it looks in our UI. So first of all, within the disabled date prompt, we've specified that 90 days from a certain day for both check in and check out will be disabled.
[07:12 - 07:24] So in this example today, it's the sixth of January, 2020. If I was to click to go to February to March and I can see from April, 2020, the sixth of April, 2020 is disabled all the way up to the future.
[07:25 - 07:31] Right. And this is the same for the actual checkout date as well. If I try to click elsewhere up to the point of April, this is disabled.
[07:32 - 07:35] So that UI capability works as intended. The other thing we've done is we added the extra footers.
[07:36 - 07:47] Right. So here we can see for the check in date picker, it tells us you can only book a listing within 90 days from today. Now the checkout date picker, this is where we actually have the capability to see the tool tip around the element that is the check in date.
[07:48 - 08:00] Right. So this is basically just a good UI capability to tell the user that, hey, this is the check in date for you to recall. If you want to pick a checkout date, just make sure it's not before check in the user can click the eighth of January, for example.
[08:01 - 08:04] And that's essentially all we've done here. So just to reiterate, it isn't that difficult.
[08:05 - 08:08] It's fairly straightforward. The server side validation is probably the most important.
[08:09 - 08:20] We want to make sure if this is a requirement that we want, that the user can select a date that's 90 days from today and we just compare the millisecond times from today's date as well as the check in and check out dates. And I'm a client.
[08:21 - 08:33] We just simply use some props additionally, like the date render prop to just convey a new element UI for the check in date selected in the checkout date picker. And we use the render extra footer prop to show some footer messaging for both of these day pickers.
[08:34 - 08:46] And lastly, within the disabled date functionality that we have, we make sure that the UI element itself also disables the date that is 90 days from today. Now, one other thing we quickly mentioned before as well that we won't do.
[08:47 - 08:52] There's another restriction that one can perhaps do. And this could be maybe that there should be a maximum length of booking.
[08:53 - 09:01] And it might be a valid requirement, right? Let's assume we don't want people to book a listing for, I don't know, two months in time or three months in time or five months in a row.
[09:02 - 09:21] And what you can do here is once again, very similar, but you just need to specify what the requirement is. So, for example, if we have the check in date value and the checkout date value on the server, we can just simply be like, if the difference in time between check in and checkout is, I don't know, is not greater than a week or two weeks or three weeks, you know, throw an error.
[09:22 - 09:37] And then on the UI, we want to reflect something similar, right? For example, if the user selects a certain check in date, let's say, I don't know, the 22nd, and if you want the maximum length of booking to be three weeks , and in the UI, we just simply have to reflect this here and just disable every date after the three weeks.
[09:38 - 09:44] There's many different things that can be done. And each of the things that we can do essentially comes down to the feature we want supported in our application.
[09:45 - 10:03] And for example, whether it's making sure we disable any dates that is to be selected a year from now or whether we want to restrict the length of time a booking can be made, etc. At the end of the day, if something like this needs to be implemented, it's important to first make the server side validation check and then have the UI in our client reflect what we want to convey to the user.
[10:04 - 10:06] user.