-->

DatePicker Editor Template

2019-03-31 07:14发布

问题:

Below is an EditorTemplate that renders a Bootstrap datetimepicker with EditorFor helpers, the problem I am seeing is with the script section. It works OK for one DateTimePicker per view - but since I am using class selector, whenever I use 2 or more DateTimePickers per view it renders duplicate <script> sections, confusing the DOM as to on which TextBox to invoke the calendar. What am I missing here?

   @model DateTime?
   <div class='input-group date datePicker'>
      <span class="input-group-sm">
         @Html.TextBox("", Model.HasValue ? Model.Value.ToString("d") : String.Empty)
      </span>
   </div>
   <script type="text/javascript">
       $(function() {
       $('.datePicker').datetimepicker({
           pickTime: false
       });
   });
   </script>

回答1:

The problem you have as you have correctly deduced is that the script block defined in the editor template will run twice when you have two datepickers included in a view; When it is run twice, the plugin's behaviour is not as expected.

One solution to this would be to target only the datepicker input in the editor template in each script block. For example,

@model DateTime?
<div class='input-group date datePicker'>
   <span class="input-group-sm">
      @Html.TextBox("", Model.HasValue ? Model.Value.ToString("d") : String.Empty)
   </span>
</div>
<script type="text/javascript">
    $(function() {
        // target only the input in this editor template
        $('#@Html.IdForModel()').datetimepicker({
            pickTime: false
        });
    });
</script>


回答2:

As far as rendering the script once, what about the following? It works for me so far. Any potential issues?

Editor Template - DateTime.cshtml

@model System.DateTime?
@Html.TextBox("", String.Format("{0:d}", Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datepicker" })


_Layout.cshtml

<script type="text/javascript">
  $().ready(function () {
    $('.datepicker').datepicker({
      changeMonth: true,
      changeYear: true,
      showOn: "button",
      buttonImage: "/Images/calendar.gif",
      buttonImageOnly: true
    });
   }
</script>