pass the results of a date selected via bootstraps datepicker and put it in a url link

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:

  1. I select a start date within the 1st week of October,
  2. Then I select an end date within the 1st week of October,
  3. Then I realize I should have selected November dates
  4. 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.

Leave a Comment

Your email address will not be published.

Scroll to Top