传递在 Bootstrap 日期选择器中选择的日期的结果,并将其放在 URL 链接中

Posted

技术标签:

【中文标题】传递在 Bootstrap 日期选择器中选择的日期的结果,并将其放在 URL 链接中【英文标题】:Pass the results of a date selected via Bootstraps datepicker, and put it in a URL link 【发布时间】:2021-02-11 02:17:52 【问题描述】:

我正在使用 Bootstrap 日期选择器让用户选择他们的“入住”和“退房”日期的酒店网站。单击按钮时,这两个日期都应传递到“预订”网站。

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

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

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

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

$('.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>

目前,我已在上述链接中手动输入签入/签出字段的日期。这显然是我需要一些脚本来提取日期选择器提供的日期参数的地方。

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

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

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

对于如何将所选日期传递到链接中的任何建议,我将不胜感激。

谢谢!

【问题讨论】:

这有帮助吗? ***.com/questions/23767162/… 【参考方案1】:

目标:制定这个字符串:

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

我建议每次更改.datpicker 时用JS 更新链接的HREF。 在链接中添加 ID 将帮助我们:

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

重写:

根据您的小提琴,这是我建议的脚本 (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() 上可用的方法似乎是您最大的障碍。 您使用的是 JQuery 1.10.4,所以我找到了特定于该版本的文档: https://api.jqueryui.com/1.10/datepicker

您可以在那里找到可用的方法,例如 getDate

还有,好消息,$().datepicker('getDate') 返回一个日期对象!

所以我们不需要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);
  
);

原因如下:

    我选择了 10 月第一周内的开始日期, 然后我选择 10 月第一周内的结束日期, 然后我意识到我应该选择 11 月的日期 但是当我返回选择新的开始日期时,我无法选择 10 月第一周之后的任何日期

因为我认为您不应该限制开始日期,我们可能会遇到结束日期早于开始日期的情况,因此我们需要一个条件来检查,然后再建立链接:

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
    
  ;

而且我认为应该禁用链接,直到您有 2 个好的日期,所以我添加了一些 CSS:

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

我还在链接的 HTML 中添加了 .disabled 类,因此当表单字段为空白时,它会在页面加载时出现。 作为防止错误链接点击的第二道安全线,我将链接设置如下:

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

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

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

我在按钮下方添加的&lt;p&gt; 也是如此,以显示有关链接不可点击的原因的警告。我给它一个“隐藏”类开始,然后根据条件删除或添加该类。

【讨论】:

感谢 Chiperific,非常感谢您提供的所有宝贵帮助。但是,我在执行您的建议时遇到问题。首先我需要注意我使用的是 $start 和 $finish 脚本(不是 $inline-start 和 $inline-finish)。我相应地调整了您的代码,但它似乎卡在“checkInDate”行上,并且不执行重新格式化日期函数。我也无法弄清楚我需要在 html 代码中的实际 a href 链接上进行哪些更改才能拉入 newUrl。 我在这里创建了一个 Fiddle 设置,其中包含我所有特定的 javascript、css 和 html 代码:jsfiddle.net/SunnyOz/jm2hdx96/5。当您运行它时,您会注意到我添加了一些警报来调试它。它们被放置以指示是否实际访问了每个部分的编码。您可以根据需要更改它。 (在JS框中显示datepicker.js,以便在测试过程中更容易更改。)。 @SunnyOz,我非常感谢小提琴,它帮助我给了你一个更好的答案。请参阅上面的重写答案。 天啊@Chiperific。你真的超越了,非常感谢。如果可以的话,我会给你一百个加价。只是为了让您知道我所做的不同:我将月份格式更改为数字以创建 URL;我取消了 javascript:void(0) 的默认 href 并将其替换为不带日期的预订页面的通用链接(本网站上的许多其他链接都允许这样做 - 他们可以在到达预订网站后选择日期) . 非常感谢 IF 声明,以及旧版本 jQuery 的文档。 (我认为我遇到的问题是其中一个脚本是旧版本,但我不确定是哪一个。注意:我继承了 datepicker.js,所以我不确定他们为什么使用“return”语句,所以我把它留在了。)如果你想现场观看你的作品,这里是网站:citycentrebudgethotel.com.au/stage/default.asp。再次感谢您的辛勤工作!

以上是关于传递在 Bootstrap 日期选择器中选择的日期的结果,并将其放在 URL 链接中的主要内容,如果未能解决你的问题,请参考以下文章

无法从 bootStrap 日期选择器中读取值

检测bootstrap-vue日期选择器中v-for中每个元素的目标

Angular 2 在日期选择器中禁用特定日期

在日期时间选择器中禁用时间选择器

如何检查日期范围选择器中的日期是不是更改?

在引导日期时间选择器中禁用时间