【问题标题】:jQuery Datepicker: Prevent closing picker when clicking a datejQuery Datepicker:单击日期时防止关闭选择器
【发布时间】:2010-11-18 03:50:19
【问题描述】:

大家好,stackoverflow:ers,

我正在使用jQuery Datepicker pluginMartin Milesich Timepicker 插件。一切都很好,除了单击日期选择器中的日期会关闭小部件,没有时间选择时间。

问题:所以我想知道是否有办法阻止小部件在单击日期时关闭,而是强制用户单击“完成”按钮(启用“showButtonPanel:true”选项时会显示该按钮) ,或单击小部件外部。我不希望我的用户必须打开小部件两次!查看行为online at the timepicker demo

感谢任何解决此问题的帮助,甚至是正确方向的指针!

更多信息: 我正在使用 Martins 下载链接提供的文件:http://milesich.com/tpdemo/timepicker-0.2.0.zip

  • jquery-ui-1.7.2.custom.min.js
  • timepicker.js(最新版本 0.2.0)

这些是我正在使用的选项:

$(document).ready(function(){
    $(".datepicker").datepicker({
        duration: '',  
        showTime: true,  
        constrainInput: false,  
        stepMinutes: 5,  
        stepHours: 1, 
        time24h: true,
        dateFormat: "yy-mm-dd",
        buttonImage: '/static/images/datepicker.png',
        buttonImageOnly: true,
        firstDay: 1,
        monthNames: ['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December'],
        showOn: 'both',
        showButtonPanel: true
     });
})

【问题讨论】:

  • 快速说明,这个问题在当前版本的 TimePicker 插件中不再是问题。
  • @JamesMcGrath:谢谢,很高兴知道!
  • @lucifer:对不起,没有。您使用 StackOverflow 错误。如果你有一个问题,写一个新的,尽可能多的信息。您可能会在几个小时内收到回复。

标签: javascript jquery jquery-ui jquery-ui-datepicker


【解决方案1】:

最好使用现有事件,而不是更改源

onSelect: function() {
    $(this).data('datepicker').inline = true;                               
},
onClose: function() {
    $(this).data('datepicker').inline = false;
}

【讨论】:

  • 这是一个更好的解决方案。注意:如果您启用了showButtonPanel: true,这将删除“完成”按钮。还没有想出如何阻止这种行为。
  • 非常感谢。这是完美的解决方案。
  • @PhilMoorhouse 有点晚了,但也许仍然可以帮助某人:在 jquery-ui 中,你会找到一个 _generateHTML 函数,如果实例有 inline: true,它不会添加“完成”按钮放。您可以在那里搜索唯一出现的 ui-datepicker-close 并摆脱这种行为。
  • @Min Hur:这有点好用,但是如果日期选择器上有一个按钮,那么如果使用此代码,它将不会保持可见。请您告诉如何在选择日期时防止关闭日期选择器并防止其上的按钮。
  • 当您使用 js 进行一些自定义样式时,此解决方案并不好,因为它会重新初始化 datepicker 弹出窗口。 $(this).data('datepicker').inline = true; 之后所有的更改都消失了;
【解决方案2】:

供参考,因为人们通过邮件问过我这个问题。这是需要添加到 timepicker.js 中的代码块:

/**
 * Don't hide the date picker when clicking a date
 */
$.datepicker._selectDateOverload = $.datepicker._selectDate;
$.datepicker._selectDate = function(id, dateStr) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    inst.inline = true;
    $.datepicker._selectDateOverload(id, dateStr);
    inst.inline = false;
    this._updateDatepicker(inst);
}

祝你好运!

【讨论】:

  • +1 一个老问题,但仍然有效!感谢您添加此参考。
  • @zaf:感谢您回复我并投票:)
  • 这可行,但在选择日期时会滚动到屏幕顶部……至少在 Chrome 中是这样。
  • 给我这个错误:Uncaught RangeError: Maximum call stack size exceeded
  • @OmidHezaveh:您可能没有正确复制内容。请注意名称 _selectDateOverload 和 _selectDate。它们需要不同。
【解决方案3】:

您必须自己破解日期选择器。这是它使用的代码。如果它不是内联的,它将在您选择日期时隐藏。

您可以传入自己的 onSelect 方法并快速将 datePicker 实例更改为内联,然后将其改回而无需更改 datepicker 内部结构,但这是一个非常老套的解决方案。

if (inst.inline)
        this._updateDatepicker(inst);
else {
      this._hideDatepicker(null, this._get(inst, 'duration'));
      this._lastInput = inst.input[0];
      if (typeof(inst.input[0]) != 'object')
      inst.input[0].focus(); // restore focus
      this._lastInput = null;
}

【讨论】:

  • 非常感谢 redsquare,您的回复让我朝着正确的方向前进。似乎 onSelect 仅在选择日期时触发,因此只需在 select 上的实例上调用 show() 即可获得我想要的行为。 ... onSelect: function(dateText, inst){ inst.show(); }
  • 不,我的错。上面抛出了一个错误,这似乎阻止了选择器隐藏。我仍然无法让您的建议发挥作用。如果我把它变成“内联”,完成按钮就会消失,除了点击它之外没有其他方法可以关闭窗口。我尝试设置超时并将内联模式重置为无效。
  • 好的,我找到了第二种方法来做我想做的事。实际上可以使用自定义方法覆盖 _selectDate 方法,您在上面提供的代码来自哪里。该方法包含与原始文件中完全相同的代码,但没有“_hideDatepicker”行。简单,而且相当老套,但它确实有效。
  • 很高兴你对它进行了排序,埃米尔。祝你好运
【解决方案4】:

这是一个解决方案:

onSelect: function ( dateText, inst ) {
    ..... // Your code like $(this).val( dateText );`


    //Set inline to true to force "no close"
    inst.inline = true;
},
onClose: function(date,inst){
    //Set inline to false => datapicker is closed
    // onClose is called only if you click outside the datapicker, onSelect will not
    // trig onClose due to inline = true
   inst.inline = false;
}

`

【讨论】:

    【解决方案5】:

    为什么所有 cmets 都提供解决方法?它是直字:

    使用带有 altField 的内联日历 :)

        <input type="text" id="alternate" size="30" />
        <div id="datepicker"></div>
    
        <script>
           $("#datepicker").datepicker({
              altField: "#alternate"
           });
        </script>
    

    检查这个小提琴: http://jsfiddle.net/menocomp/y2s662b0/1/

    【讨论】:

      【解决方案6】:

      酷,如果你使用 jquery-ui-1.8.5.custom.min.js 和 jquery-ui.multidatepicker.js,你可以修改 jquery-ui-1.8.5.custom.min.js: 来自:

      if(a.inline)this._updateDatepicker(a);
      

      进入:

      if(a.inline || !this._get(a, 'closeOnSelect'))this._updateDatepicker(a);
      

      【讨论】:

        【解决方案7】:

        这是一个肮脏的解决方法......但它对我有用......即使使用 showButtonPanel: true

          $(function() {
            var dp_c = null, dp_once = false;
            $( '#datepicker' ).datepicker({
              showButtonPanel: true,
              onSelect: function() {
                $(this).data('datepicker').inline = true;  
                setTimeout(function () {
                  $('#ui-datepicker-div').find('.ui-datepicker-buttonpane').append(dp_c);
                }, 1);
        
              },
              onClose: function() {
                $(this).data('datepicker').inline = false;
              }
            }).click(function () {
              if(!dp_once) {
                setTimeout(function () {
                  dp_c = $('#ui-datepicker-div').find('.ui-datepicker-close').clone();
                }, 500);
                dp_once = !!1;
              }
            });
        
            $('#ui-datepicker-div').on('click', '.ui-datepicker-close', function () {
              $('#datepicker').datepicker( "hide" );
            });
        
          });
        

        【讨论】:

          【解决方案8】:

          你应该重写原生 js 函数:

           /* Update the input field with the selected date. */
                  _selectDate: function(id, dateStr) {
                      var target = $(id);
                      var inst = this._getInst(target[0]);
                      dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
                      if (inst.input)
                          inst.input.val(dateStr);
                      this._updateAlternate(inst);
                      var onSelect = this._get(inst, 'onSelect');
                      if (onSelect)
                          onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
                      else if (inst.input)
                          inst.input.trigger('change'); // fire the change event
                      if (inst.inline)
                          this._updateDatepicker(inst);
                      else {
                          if(inst.settings.hideOnSelect != false){
                              this._hideDatepicker();
                          }
                          this._lastInput = inst.input[0];
                          if (typeof(inst.input[0]) != 'object')
                              inst.input.focus(); // restore focus
                          this._lastInput = null;
                      }
                  },
          

          并为 datepicker 配置添加适当的选项,例如:

          var defaultDatePickerOptions = {
                  hideOnSelect: false,
                  ...
              }; 
           var birthDate = jQuery.extend({}, defaultDatePickerOptions);
           $('#birthdate').datepicker(birthDate);
          

          【讨论】:

            【解决方案9】:

            按照 Emil 的建议,我找到了一种更好、更简单的方法来修改小部件以支持在选择事件时不关闭小部件。

            首先,我在小部件的默认字典中添加了另一个属性:

            closeOnSelect:true //True to close the widget when you select a date
            

            其次,在_selectDate方法中找到这条语句:

            if (inst.inline)
                    this._updateDatepicker(inst);
            else {
                    ...
                }
            

            然后把条件改成这样:

            var closeOnSelect = this._get(inst, "closeOnSelect");        
            if (inst.inline || !closeOnSelect)
                    this._updateDatepicker(inst);
            else {
                    ...
                }
            

            试一试,它对我有用。我是在 JQuery UI 1.8.5 版本上完成的。

            【讨论】:

              猜你喜欢
              • 2023-04-02
              • 1970-01-01
              • 2013-11-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-05-29
              • 1970-01-01
              • 2014-08-10
              相关资源
              最近更新 更多