Goal: formulate this string:
https://www.bookingsite.com/hotelname?checkInDate=2020-11-28&checkOutDate=2020-12-29
I suggest updating the HREF of the link with JS every time a .datpicker
is changed.
Adding an ID to the link will help us out:
<a id="some_id" href="https://www.bookingsite.com/hotelname?checkInDate=2020-11-28&checkOutDate=2020-12-29" target="_blank" class="btn-u btn-brd btn-brd-hover btn-u-dark btn-u-block">RESERVE A ROOM TODAY</a>
Rewrite:
Based on your fiddle, here is my suggested script (my fiddle):
Datepicker = function Datepicker() {
reformatDate = function reformatDate(date) {
// var d = new Date(date);
let year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date);
let month = new Intl.DateTimeFormat('en', { month: 'short' }).format(date);
let day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date);
return year + "-" + month + "-" + day;
};
rebuildHref = function rebuildHref() {
let urlBase = 'https://www.bookingsite.com/hotelname?checkInDate='
// $().datepicker('getDate') returns a Date Object!
let checkInDate = $('#start').datepicker('getDate');
let checkOutDate = $('#finish').datepicker('getDate');
// CONDITION: catch scenario where Check In Date comes after Check Out Date
// only proceed if dateCheckIn is < dateCheckOut
if (checkInDate < checkOutDate) {
let formattedInDate = reformatDate(checkInDate);
let formattedOutDate = reformatDate(checkOutDate);
let newUrl = urlBase + formattedInDate + "&checkOutDate=" + formattedOutDate;
window.alert(newUrl);
$('a#bookdates').removeClass('disabled').attr('href', newUrl);
$('p#link_error').addClass('hidden');
} else {
$('p#link_error').removeClass('hidden');
$('a#bookdates').addClass('disabled').attr('href', 'javascript:void(0)');
}
};
return {
//Datepickers
initDatepicker: function initDatepicker() {
// Regular datepicker
$('#date').datepicker({
dateFormat: 'dd MM, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>'
});
// Date range
$('#start').datepicker({
dateFormat: 'dd M, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>',
minDate: 'TODAY()',
onSelect: function( selectedDate )
{
$('#finish').datepicker('option', 'minDate', selectedDate);
rebuildHref();
}
});
$('#finish').datepicker({
dateFormat: 'dd M, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>',
onSelect: function( selectedDate )
{
// Limiting the start date is probably not beneficial:
// Scenario: I select a start date within the 1st week of October,
// then I select an end date within the 1st week of October,
// then I realize I should have selected November dates
// but when I go back to select a new start date, I'm locked out of
// selecting any dates past the first week of October
// IF #start's selectedDate HAS to be before #end's selectedDate,
// let's handle that a different way. See the new If statement in rebuildHref();
// $('#start').datepicker('option', 'maxDate', selectedDate);
rebuildHref();
}
});
// Inline datepicker
$('#inline').datepicker({
dateFormat: 'dd MM, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>'
});
// Inline date range
$('#inline-start').datepicker({
dateFormat: 'dd MM, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>',
onSelect: function( selectedDate )
{
$('#inline-finish').datepicker('option', 'minDate', selectedDate);
}
});
$('#inline-finish').datepicker({
dateFormat: 'dd MM, yy',
prevText: '<i class="fa fa-angle-left"></i>',
nextText: '<i class="fa fa-angle-right"></i>',
onSelect: function( selectedDate )
{
// probably don't want this one either
// $('#inline-start').datepicker('option', 'maxDate', selectedDate);
}
});
}
}
}();
Major things I changed:
checkInDate = $('#start').datepicker('selectedDate');
checkOutDate = $('#finish').datepicker('selectedDate');
Turns out there’s no ‘selectedDate’ attribute, we needed ‘getDate’:
checkInDate = $('#start').datepicker('getDate');
checkOutDate = $('#finish').datepicker('getDate');
Figuring out what methods are available on $().datepicker()
seems to be your biggest hold-up.
You are using JQuery 1.10.4, so I found the docs specific to that version:
https://api.jqueryui.com/1.10/datepicker
That’s where you’ll find the available methods, like getDate
And, good news, $().datepicker('getDate')
returns a Date Object!
So we don’t need the first line of reformatDate()
to make a new Date:
var reformatDate = function(date) {
// No longer need this line:
// var d = new Date(date);
...
};
I also don’t know why you had everything nested inside a return. I’m not a Javascript guru, so maybe you know something I don’t. But I moved the reusable functions outside of the return
call and only left the initDatepicker
stuff inside the return
.
Minor things I changed:
I made sure all variables were preceded by let
and fixed a few missing ;
.
I’m also suggesting a change to the #start
field’s onSelect
function. I don’t think you really want to limit the values of the Start date.
$('#finish').datepicker({
...
onSelect: function( selectedDate ) {
// See my long comment in the full code example, but I don't think you want to do this.
// $('#start').datepicker('option', 'maxDate', selectedDate);
}
});
Here’s why:
- I select a start date within the 1st week of October,
- Then I select an end date within the 1st week of October,
- Then I realize I should have selected November dates
- But when I go back to select a new start date, I’m locked out of selecting any dates past the first week of October
Because I don’t think you should restrict the start date, we could have a situation where the End date comes before the Start date, so we need a conditional to check for that before we build the link:
rebuildHref = function rebuildHref() {
...
// CONDITION: catch scenario where Check In Date comes after Check Out Date
// only proceed if dateCheckIn is < dateCheckOut
if (checkInDate < checkOutDate) {
// Good dates
} else {
// Bad dates
}
};
And I think the link should be disabled until you have 2 good dates, so I added some CSS:
/* disable the link with CSS */
.disabled {
pointer-events: none;
cursor: default;
}
I also added the .disabled
class to the link’s HTML so it’s there on page load when the form fields are blank.
As a 2nd line of safety against bad link clicking, I set the link up like this:
<a id="bookdates" href="javascript:void(0)" ... /a>
The javascript:void(0)
means that even if the user manages to click the link, it won’t do anything.
This is also a great way to tell if your script works, because
You’ll see calls like $('a#bookdates').addClass('disabled');
or $('a#bookdates').removeClass('disabled');
to handle enabling / disabling the link based upon our conditional.
The same is true for a <p>
I added below the button to display a warning as to why the link is un-clickable. I gave it the class of “hidden” to start off with and I remove or add that class based upon the conditional.
CLICK HERE to find out more related problems solutions.