MVC EditorTemplate с несколькими входными данными для одного и того же значения

Я создал этот шаблон редактора:

@model DateTime?

@using MyMvcApp.Properties

<div id="dateTimePicker_@(ViewData.ModelMetadata.PropertyName)">
    <script type="text/javascript" language="javascript">
        //<![CDATA[
        $(document).ready(function () {
            var $div = $('#dateTimePicker_@(ViewData.ModelMetadata.PropertyName)');

            $div.find('.date').datepicker({ altFormat: 'dd-mm-yy' });
        });

        function clearDateTimePicker_@(ViewData.ModelMetadata.PropertyName)() {
            var $div = $('#dateTimePicker_@(ViewData.ModelMetadata.PropertyName)');

            $div.find('.date').val('');
            $div.find('.hour').val('00');
            $div.find('.minute').val('00');
        }
        //]]>
    </script>

    @* Date - should equal DatePicker.cshtml *@
    @Html.TextBox("Value.Date", Model.HasValue ? Model.Value.Date.ToString() : string.Empty, new { @class = "date" })
    <img alt="@Resources.SelectDate" src="../../../images/calendar.png" class="calendarIcon" />

    @* Time - should equal TimePicker.cshtml *@
    @Html.DropDownList("Value.Hour", new SelectList(new[] { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" }, Model.HasValue ? Model.Value.Hour.ToString("D2") : "00"), 
        null, new { style = "width: auto; margin-left: 5px;", @class = "hour" })
    :
    @{
        List<string> availableMinutes = new List<string>();
        for (int minute = 0; minute < 60; minute += 1)
        {
            availableMinutes.Add(minute.ToString("D2"));
        }

        @Html.DropDownList("Value.Minute", new SelectList(availableMinutes, Model.HasValue ? Model.Value.Minute.ToString("D2") : "00"), 
            null, new { style = "width: auto;", @class = "minute" });
    }
    <img alt="@Resources.SelectTime" src="../../../images/icon_clock_2.gif" style="margin-right: 5px" />
    <input type="button" value="@Resources.Clear" class="ui-state-default" onclick="javascript:clearDateTimePicker_@(ViewData.ModelMetadata.PropertyName)()" />
</div>

Как видите, я пытаюсь добиться того, чтобы пользователь мог ввести дату/время. Однако в качестве ввода я хочу использовать DateTime? (можно обнулить), поскольку возможно, что пользователь не хочет выбирать ЛЮБУЮ дату/время.

Этот EditorTemplate не работает, когда входная модель имеет значение null. Есть ли способ создать EditorTemplate, который принимает нулевые значения, а затем может заполнять значение, если оно введено пользователем?


person Geert van Horrik    schedule 28.02.2011    source источник
comment
Значение http post равно null, когда я ввожу дату/время, и исходное значение модели также равно null.   -  person Geert van Horrik    schedule 01.03.2011
comment
что вы отправляете обратно в Action? ваш шаблон редактора @model DateTime ??   -  person swapneel    schedule 06.03.2011
comment
Это модель с DateTime? имущество. Свойство представлено так: @Html.EditorFor(model => model.StartTime, DateTimePicker)   -  person Geert van Horrik    schedule 07.03.2011


Ответы (1)


Хорошо, я, наконец, прибил проблему. Мое решение словами:

Я использую скрытое поле, в котором хранится текущее значение в текстовом представлении. Это скрытое поле всегда преобразуется в саму модель (тогда оно корректно преобразуется в значение null или значение, включающее часы и минуты). Каждый раз, когда элемент ввода изменяется, я обновляю локальное значение, которое отправляется обратно на сервер.

Мое решение в коде:

@model DateTime?

@using Narcast.Server.Properties

<div id="dateTimePicker_@(ViewData.ModelMetadata.PropertyName)">
    <script type="text/javascript" language="javascript">
        //<![CDATA[
        $(document).ready(function () {
            var $div = $('#dateTimePicker_@(ViewData.ModelMetadata.PropertyName)');

            $div.find('.date').datepicker({ altFormat: 'dd-mm-yy' });
        });

        function clearDateTimePicker_@(ViewData.ModelMetadata.PropertyName)() {
            var $div = $('#dateTimePicker_@(ViewData.ModelMetadata.PropertyName)');

            $div.find('.date').val('');
            $div.find('.hour').val('00');
            $div.find('.minute').val('00');

            updateData_@(ViewData.ModelMetadata.PropertyName)();
        }

        function updateData_@(ViewData.ModelMetadata.PropertyName)() {
            var $div = $('#dateTimePicker_@(ViewData.ModelMetadata.PropertyName)');

            var $date = $div.find('.date').val();
            var $hour = $div.find('.hour').val();
            var $minute = $div.find('.minute').val();

            var $data = '';

            if ($date != '')
            {
                $data = $date + ' ' + $hour + ':' + $minute;
            }

            $div.find('.data').val($data);
        }
        //]]>
    </script>

    @* Hidden field holding the client data *@
    @Html.Hidden("", Model.HasValue ? Model.Value.ToShortTimeString() : string.Empty, new { @class = "data" })

    @* Date - should equal DatePicker.cshtml *@
    <input type="text" class="date" onchange="javascript:updateData_@(ViewData.ModelMetadata.PropertyName)()" />
    @*@Html.TextBox("Date", Model.HasValue ? Model.Value.Date.ToString() : string.Empty, new { @class = "date" })*@
    <img alt="@Resources.SelectDate" src="../../../images/calendar.png" class="calendarIcon" />

    @* Time - should equal TimePicker.cshtml *@
    <select class="hour" style="width: auto; margin-left: 5px;" onchange="javascript:updateData_@(ViewData.ModelMetadata.PropertyName)()">
    @{
        for (int hour = 0; hour < 24; hour += 1)
        {
            <text><option @{ if (Model.HasValue && Model.Value.Hour == hour) { <text>selected="selected"</text> }}>@(hour.ToString("D02"))</option></text>
        }        
    }
    </select>

    :

    <select class="minute" style="width: auto; margin-left: 5px;" onchange="javascript:updateData_@(ViewData.ModelMetadata.PropertyName)()">
    @{
        for (int minute = 0; minute < 60; minute += 1)
        {
            <text><option @{ if (Model.HasValue && Model.Value.Minute == minute) { <text>selected="selected"</text> }}>@(minute.ToString("D02"))</option></text>
        }        
    }
    </select>
    <img alt="@Resources.SelectTime" src="../../../images/icon_clock_2.gif" style="margin-right: 5px" />
    <input type="button" value="@Resources.Clear" class="ui-state-default" onclick="javascript:clearDateTimePicker_@(ViewData.ModelMetadata.PropertyName)()" />
</div>
person Geert van Horrik    schedule 06.03.2011
comment
И я написал сообщение в блоге с несколькими DateTime? EditorTemplates: blog.catenalogic. com/post/2011/03/06/ - person Geert van Horrik; 07.03.2011