传递通过 Bootstraps 日期选择器选择的日期的结果,并将其放入 URL link

Pass the results of a date selected via Bootstraps datepicker, and put it in a URL link

我在一个酒店网站上工作,该网站使用 Bootstrap 日期选择器让用户 select 他们的 'Check In' 和 'Check Out' 日期。单击按钮时,这两个日期都应传递到 'booking' 网站。

例如,如果用户 select 的入住日期为:2020 年 11 月 28 日,退房日期为:2020 年 12 月 29 日,那么我需要将这两个日期都输入url 使用这种格式:

bookingsite.com/hotelname?checkInDate=2020-11-28&checkOutDate=2020-12-29

我希望我可以通过一些 JavaScript 来做到这一点,但我不知道如何访问使用日期选择器选择的日期。而且,由于日期选择器结果的格式不是 URL 允许的格式,所以我想我将不得不获取日期每个部分的变量(即:日、月和年) 分开。

这是棘手的部分。不幸的是,该站点似乎有 旧版本的 Bootstrap 或日期选择器,它没有获取我在页面上为日期选择器设置格式添加的任何脚本(不使用较新的日期选择器脚本使用的标准变量)。这是一个脚本示例,通常适用于较新的日期选择器,但不适用于我的。 (Chiperific 在回答我的另一个 post 时提供的示例):

$('.datepicker').datepicker({
    format: {
        // We're sending an object, not a string
        toDisplay: function (date, format, language) {
            // this gets messy, sorry
            var d = new Date(date);
            var year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(d);
            var month = new Intl.DateTimeFormat('en', { month: 'short' }).format(d);
            var day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(d);
            return day + " " + month + ", " + year;
        }
    }
}); 

而不是我认为正常的datepicker.js,这是本站正在使用的那个(注:我已经在本站上根据我的需要进行了调整):

var Datepicker = function () {

  return {
    
    //Datepickers
    initDatepicker: function () {
        // 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 MM, 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);
            }
        });
        $('#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 )
            {
                $('#start').datepicker('option', 'maxDate', selectedDate);
            }
        });
        
        // 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 )
            {
                $('#inline-start').datepicker('option', 'maxDate', selectedDate);
            }
        });
    }

  };
}();

下面是 HTML 显示日历字段的代码:

    <form action="#" id="sky-form" class="sky-form">
        <div class="row" style="margin: auto;">
            <section class="col-md-6">
                <label class="input">
                    <i class="icon-append fa fa-calendar"></i>
                    <input type="text" name="start" id="start" placeholder="Check In Date" class="datepicker">
                </label>
            </section>
            <section class="col-md-6">
                <label class="input">
                    <i class="icon-append fa fa-calendar"></i>
                    <input type="text" name="finish" id="finish" placeholder="Check out Date" class="datepicker">
                </label>
            </section>
        </div>
</form>

这是按钮代码:

    <div class="call-action-v1-in inner-btn page-scroll" style="padding-top: 20px;">
        <a 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>
</div>

目前,我已经在上面 link 的 check-in/check-out 字段中手动输入了日期。这显然是我需要一些脚本来提取日期选择器提供的日期参数的地方。

所以这个部分应该是这样的:?checkInDate=2020-11-28&checkOutDate=2020-12-29,而不是:?<script>document.write(Date.parse(startDate), Date.parse(endDate));</script>

在别处创建上述 startDate 和 endDate 变量。

任何人都可以帮我弄清楚我可以在我的 datepicker.js 版本中添加什么(如上所示),这样我就可以将 selected 日期放入一个可传递的变量中用于创建 URL? (可能需要将日、月和年作为开始和结束日期的单独变量,因为日历显示的日期格式是“dd MMM,yyyy”,而 URL 格式需要为“yyyy-mm-dd

对于如何将日期 select 传递到 link 中的任何建议,我将不胜感激。

谢谢!

目标: 制定此字符串:

https://www.bookingsite.com/hotelname?checkInDate=2020-11-28&checkOutDate=2020-12-29

我建议每次 .datpicker 改变时用 JS 更新 link 的 HREF。 添加一个 ID 到 link 将帮助我们:

<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>

重写:

根据您的 fiddle,这是我建议的脚本 (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);
          }
      });
    }
  }
}();

我更改的主要内容:

checkInDate = $('#start').datepicker('selectedDate');
checkOutDate = $('#finish').datepicker('selectedDate');

原来没有 'selectedDate' 属性,我们需要 'getDate':

checkInDate = $('#start').datepicker('getDate');
checkOutDate = $('#finish').datepicker('getDate');

弄清楚 $().datepicker() 上可用的方法似乎是你最大的问题 hold-up。 您使用的是 JQuery 1.10.4,因此我找到了该版本的特定文档: https://api.jqueryui.com/1.10/datepicker

这是您可以找到可用方法的地方,例如 getDate

而且,好消息,$().datepicker('getDate') return 是一个日期对象!

所以我们不需要reformatDate()的第一行来创建一个新的日期:

var reformatDate = function(date) {
  // No longer need this line:
  // var d = new Date(date);
  ...
};

我也不知道为什么你把所有东西都嵌套在 return 里。我不是 Javascript 大师,所以也许你知道一些我不知道的事情。但是我将可重用函数移到了 return 调用之外,只将 initDatepicker 内容留在了 return.

我更改的小东西:

我确保所有变量前面都有 let 并修复了一些缺失的 ;

我还建议更改 #start 字段的 onSelect 函数。我不认为你真的想限制开始日期的值。

$('#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);
  }
});

原因如下:

  1. 我 select 开始日期在 10 月的第一个星期内,
  2. 然后我 select 结束日期在 10 月的第一个星期内,
  3. 然后我意识到我应该 select11 月的日期
  4. 但是当我回到 select 新的开始日期时,我被锁定在 select十月第一周之后的任何日期

因为我认为你不应该限制开始日期,我们可能会遇到结束日期早于开始日期的情况,所以我们需要在构建 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
    }
  };

而且我认为 link 应该被禁用,直到你有 2 个好约会,所以我添加了一些 CSS:

/* disable the link with CSS */
.disabled {
  pointer-events: none; 
  cursor: default; 
}

我还将 .disabled class 添加到 link 的 HTML 中,因此当表单字段为空白时它会在页面加载时出现。 作为防止不良 link 点击的第二道防线,我将 link 设置如下:

<a id="bookdates" href="javascript:void(0)" ... /a>

javascript:void(0) 意味着即使用户设法点击 link,它也不会做任何事情。 这也是判断脚本是否有效的好方法,因为

你会看到像 $('a#bookdates').addClass('disabled');$('a#bookdates').removeClass('disabled'); 这样的调用来根据我们的条件处理启用/禁用 link。

我在按钮下方添加的 <p> 也是如此,以显示关于为什么 link 是 un-clickable 的警告。我给了它 class 的“隐藏”开始,我根据条件删除或添加 class。