How to use jQuery UI DatePicker and MVC 4 with cus

2019-08-07 15:21发布

Let's say you want to use the datepicker with the custom Romanian format: dd.MM.yyyy

How can you do this without encountering jquery validation problems and misinterpreting of the date time after a postback ?

1条回答
狗以群分
2楼-- · 2019-08-07 15:38

First of all include datepicker-ro.js after jquery-ui.js.

After that set the format in the model like this:

public class ProductionCalculationReportModel
    {
        [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? BeginDate { get; set; }

        [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? EndDate { get; set; }        
    }

Then, in .cshtml file you can put the textboxes:

@Html.TextBoxFor(x => x.BeginDate, "{0:dd.MM.yyyy}", new { @class = "datefield" })
@Html.TextBoxFor(x => x.EndDate, "{0:dd.MM.yyyy}", new { @class = "datefield" })

Then, also in the cshtml file, let's take care of the validation:

<script>
  $(function() {
      $("#BeginDate").datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 3,
      onClose: function( selectedDate ) {
          $("#EndDate").datepicker(
              {
                  minDate: selectedDate
                  , dateFormat: 'dd.mm.yy'
              }
              //"option", "minDate", selectedDate
              );
      }
    });
      $("#EndDate").datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 3,
      onClose: function( selectedDate ) {
          $("#BeginDate").datepicker(
              {
                  maxDate: selectedDate
                  , dateFormat: 'dd.mm.yy'
              }
              //"option", "maxDate", selectedDate
              );
      }
    });
  });

  $(function ()
  {
      $.validator.addMethod('date',
      function (value, element)
      {
          if (this.optional(element))
          {
              return true;
          }
          var ok = true;
          try
          {
              $.datepicker.parseDate('dd.mm.yy', value);
          }
          catch (err)
          {
              ok = false;
          }
          return ok;
      });          
  });

</script>

After that create a model binder:

public class ProductionCalculationReportModelBinder : DefaultModelBinder
    {

        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            if (propertyDescriptor.ComponentType == typeof(PAS.Areas.Admin.Models.ProductionCalculationReportModel))
            {
                if (propertyDescriptor.Name == "BeginDate")
                {
                    var obj = bindingContext.ValueProvider.GetValue("BeginDate");
                    return DateTime.ParseExact(obj.AttemptedValue.ToString(), "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
                }

                if (propertyDescriptor.Name == "EndDate")
                {
                    var obj = bindingContext.ValueProvider.GetValue("EndDate");
                    return DateTime.ParseExact(obj.AttemptedValue.ToString(), "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
                }
            }
            return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
        }
    }

Add it in Global.asax like this:

ModelBinders.Binders.Add(typeof(ProductionCalculationReportModel), new ProductionCalculationReportModelBinder()); 

And then use it like this:

[HttpPost]
        public ActionResult Index([ModelBinder(typeof(ProductionCalculationReportModelBinder))]ProductionCalculationReportModel model) {}
查看更多
登录 后发表回答