使用具有各种日期格式的jQuery Datepicker,但始终使用val()以ISO8601格式获取/设置

时间:2019-02-25 19:04:57

标签: jquery jquery-ui-datepicker iso8601

我正在尝试使用jQuery UI的datepicker作为起点编写一个用于显示和输入日期的jQuery插件。

调用它应该像这样:

jQuery(document).ready(function() {

  jQuery(document).find('input.mydatepicker').mydatepicker({
    myformat : 'mm/dd/yy'
  });

});

使得具有class =“ mydatepicker”的任何输入都将具有mydatepicker行为。

问题是我希望myformat支持各种不同的日期格式,但是,每当我使用val()函数获取/设置日期时,我都希望它位于iso8601格式yyyy-mm-dd

因此,即使我指定了上面的格式mm/dd/yy来初始化所有元素,我仍然希望:

<input type="text" class="mydatepicker" id="myelement" value="02/23/2019">

var mydate = $('#myelement').val();   //mydate = '2019-02-23'

$('#myelement').val('2019-02-24');

<input type="text" class="mydatepicker" id="myelement" value="02/24/2019">

使用此处描述的技术:Override jQuery .val() function?这是我尝试过的:

(function($) {

  // options & defaults
  var defaultOptions = {
    myformat : 'mm/dd/yy'
  };

  // attach jQuery.UI datepicker with specified options
  $.fn.mydatepicker = function(options) {
    options = $.extend({}, defaultOptions, options || {});

    return this.each( function() {
      var jq = $(this);
      jq.addClass('plugin-mydatepicker').datepicker({
        dateFormat: options.myformat,
        prevText: '<i class="fa fa-angle-left"></i>',
        nextText: '<i class="fa fa-angle-right"></i>',
        constrainInput: true,
        onSelect: function(date) { 
        }
      });
    });

  }


  // override val() to get/set in ISO8601 regardless of format
  var _origVal = $.fn.val;

  $.fn.val = function(value) {
    if ( $(this).hasClass('plugin-mydatepicker') ) {
      if (arguments.length >= 1) {
        // setter
        return $(this).val('x' + value);
      } 
      else {
        // getter
        return 'x' + $(this).val();
      }
    }
    return _origVal.apply(this, arguments);
  };

})(jQuery);

这里发生了几件事:

  • 每当我调用val()时,都会收到“深度递归”错误,但我并不是真的没有为什么。我没有编写jQuery插件的经验。
  • 我尚未完成myformat <-> iso8601转换,欢迎提出有关如何轻松实现此目的的建议。实际上,myformat可以限制为mm / dd / yy和dd / mm / yy,不需要在那里发疯。
  • 要标记每个附加了插件的元素,我添加了一个类plugin-mydatepicker。不知道这是否是最好的方法。
  • 我已经看到有些人在datepicker中使用altFormat选项。如果可以避免,则对此方法不感兴趣,因为它需要创建第二个隐藏的输入字段,并在两者之间进行同步。
  • 我对覆盖val()函数有点担心;我还会对插件中的其他get / set函数开放,例如mydateVal()
  • 我很乐意使用其他已经存在的插件!只是自己还没找到自己...

帮助?

1 个答案:

答案 0 :(得分:0)

我很确定我的答案不是您所期望的...我认为您在这里使任务复杂化了。关于日期操作,我总是使用moment.js。我真的认为我的答案比您深入研究的要简单得多。

Moment可以轻松处理各种日期格式。这是一个简单的演示,其中有3个使用jQuery-ui datepicker和不同格式实例化的输入。

现在jQuery-UI datepickerMoment之间的格式定义稍有不同...

所以我用了2 data- attributes来存储它们两个。因此,很容易从HTML标记中设置日期选择器格式。然后,为了检索ISO日期,它使用矩格式正确地解析它并转换为ISO。

$(document).ready(function() {

  // Instantiate all datepickers with their own format
  $('.mydatepicker').each(function(){
    var format = $(this).data("datepicker_format");
    console.log("Datepicker initialised with format: "+format);
    $(this).datepicker({
      dateFormat : format
    });
  });

  // A button to console log the date conversion to ISO
  $(".getDate").on("click",function(){
    var input = $(this).prev('.mydatepicker');
    
    var date = input.val();
    var format = input.data("moment_format");
    console.log("Date from the input: "+date);

    var iso_date = moment(date,format).format("YYYY-MM-DD");
    console.log("ISO date: "+iso_date);
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>

<input type="text" class="mydatepicker" id="myelement1" value="02/23/2019" data-datepicker_format="mm/dd/yy" data-moment_format="MM/DD/YYYY">
<button class="getDate">Console log the ISO date</button>
<br>
<br>

<input type="text" class="mydatepicker" id="myelement2" value="2019-02-02" data-datepicker_format="yy-mm-dd" data-moment_format="YYYY-MM-DD">
<button class="getDate">Console log the ISO date</button>
<br>
<br>

<input type="text" class="mydatepicker" id="myelement3" value="September 19, 2019" data-datepicker_format="MM dd, yy" data-moment_format="MMM Do, YYYY">
<button class="getDate">Console log the ISO date</button>
<br>
<br>

请以全页模式运行以上代码段

CodePen


如果希望将其用作从任何地方(而不是按钮)调用的函数:

function ISO_date(datepicker){
  return moment(datepicker.val(),datepicker.data("moment_format")).format("YYYY-MM-DD");
}

然后这样称呼它:

var convertedDate = ISO_date( $("someSpecificDatePickerSelector") );  // Pass the datepicker element.