将日期时间模型值绑定到datepicker并将其传递给控制器​​方法 [英] Bind Datetime Model value to datepicker and pass them to controller method

查看:536
本文介绍了将日期时间模型值绑定到datepicker并将其传递给控制器​​方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个MVC4应用程序,在我的模型中,我有这些字段:

  [DisplayFormat(DataFormatString ={0 :dd-MM-yyyy},ApplyFormatInEditMode = true)] 
public DateTime mDateCreated {get;组; }

[DisplayFormat(DataFormatString ={0:dd-MM-yyyy},ApplyFormatInEditMode = true)]
public DateTime? mDateModified {get;组; }

[DisplayFormat(DataFormatString ={0:dd-MM-yyyy},ApplyFormatInEditMode = true)]
public DateTime? mDateLastDisplayed {get;组; }

[DisplayFormat(DataFormatString ={0:dd-MM-yyyy},ApplyFormatInEditMode = true)]
public DateTime mStartDate {get;组; }

[DisplayFormat(DataFormatString ={0:dd-MM-yyyy},ApplyFormatInEditMode = true)]
public DateTime? mEndDate {get;组; }

我正试图在视图中设置日期检查器。这是我迄今为止所做的:

 < div class =float-left> 
< p>创建日期:< / p>
< p>上次修改日期:< / p>
< p>上次显示日期:< / p>
< p>促销开始日期:< / p>
< p>促销结束日期:< / p>
< / div>
< div class =float-right>
< p>
@ Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated,new
{
@value = Model.mCardOfTheDay.mDateCreated,
@selectedDate = Model.mCardOfTheDay.mDateCreated ,
@class =datePick,
@type =date,
@id =dateCreated
})
< / p>
< p>
@(Model.mCardOfTheDay.mDateModified!= null?Html.DisplayFor(_item => _item.mCardOfTheDay.mDateModified):Html.Label(ValueDomain.FIELD_UNAVAILABLE))
< / p>
< p> @(Model.mCardOfTheDay.mDateLastDisplayed!= null?Html.DisplayFor(_item => _item.mCardOfTheDay.mDateLastDisplayed):Html.Label(ValueDomain.FIELD_UNAVAILABLE))< / p>
< p>
@ * @ Html.EditorFor(_item => _item.mCardOfTheDay.mStartDate,new {@class =datePick,@ type =date})* @
@ * @ Html.TextBoxFor (_item => _item.mCardOfTheDay.mStartDate,new {@id =dateStart})* @
@ * @ Html.TextBoxFor(_item => _item.mCardOfTheDay.mStartDate,new
{
@value =(DateTime?)Model.mCardOfTheDay.mStartDate,
@selectedDate =(DateTime?)Model.mCardOfTheDay.mStartDate,
@class =datePick,
@ type =date,
@id =dateStart
})* @
< / p>
< p>
@ Html.TextBoxFor(_item => _item.mCardOfTheDay.mEndDate,new
{
@value = Model.mCardOfTheDay.mEndDate,
@selectedDate = Model.mCardOfTheDay.mEndDate ,
@class =datePick,
@type =date,
@id =dateEnd
})
< / p>
< / div>
< div class =clear>< / div>

和CSS显示我在做什么类:

  $('。datePick')。datepicker({
dateFormat:dd / ww / yy,
});

$('。datePick')。each(function(){
var a = $(this).datepicker({
dateFormat:dd / ww / yy ,
defaultDate:new Date($(this).val())
});
});

这显示了我有的各种问题。首先:


  1. 使用 Html.TexborFor 助手与 @值 @selectedDate 等等显示一个日期戳,但这个datepicker的默认显示值是 aaaa-mm-dd 而不是绑定到模型的值,当我将模型传递给控制器​​时,不保留任何数据(意味着mEndDate始终为空);

  2. 尝试只设置一个datepicker最终会得到相同的结果;

  3. 下面是一个Html代码的示例,以显示我的结果: code>< input class =input-validation-error datePickdata-val =truedata-val-date =字段mDateCreated必须是一个日期。 data-val-required =需要mDateCreated字段。 id =dateCreatedname =mCardOfTheDay.mDateCreatedselectedDate =11/21/2013 00:00:00type =datevalue =/>

  4. 如果我使用EditorFor,我所有的都是字符串格式的日期,没有datepicker。

我想要的是一个日期选择器,其中选择适当的日期,将所选日期传递给控制器​​方法。任何人都可以帮我弄清楚为什么这不起作用?

解决方案

你不应该超越日期输入的价值同一日期以不同的格式,没有理由,只会引起头痛。根据我的经验,你最好离开它。

  @ Html.TextBoxFor(_item => _item.mCardOfTheDay。 mDateCreated,新
{
@selectedDate = Model.mCardOfTheDay.mDateCreated,
@class =datePick,
@type =date,
@id = dateCreated
})

然而,您需要做的是正确配置datepicker它知道如何解释数据库中的日期。如果要向用户显示与发送给服务器的格式不同的格式,可以使用 altField )和 altFormat )选项。



这将允许您使用 dateFormat 在用户输入中以您喜欢的格式显示日期同时保持发布的值正确的格式。



您将不再需要这样了:



<$ p $每个(function(){
var a = $(this).datepicker({
dateFormat:dd / ww / yy ,
defaultDate:new Date($(this).val())
});
});

您还需要摆脱 ApplyFormatInEditMode = true 您的模型属性属性。让框架根据当前文化处理日期,不要通过应用所有地方的格式来尝试反对它。



只需将文本框值保留为数据库发送的值,并使用数据触发器的功能在客户端执行所需的操作。



我建议覆盖该值的唯一时间是如果您担心输入显示时间部分,当你只想要的日期。在这种情况下,您应该这样做:

  @ Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated,新
{
@selectedDate = Model.mCardOfTheDay.mDateCreated,
@class =datePick,
@type =date,
@id =dateCreated ,
@Value = Model.mCardOfTheDay.mDateCreated.ToString(mm / d / yyyy)
})

注意事项 @Value 具有资本v,这实际上是重要的,而不是打字错误。然后,将日期格式传递给 ToString 方法,但需要与数据库格式相同。






编辑:



我继续构建了一个小型测试用例来尝试复制你的问题这是我有的:



控制器:

  public ActionResult Test )
{
return View(new TestViewModel()
{
DateCreated = DateTime.Now.AddDays(10)
});
}

[HttpPost]
public ActionResult Test(TestViewModel model)
{
return RedirectToAction(Test);
}

ViewModel:

  public class TestViewModel 
{
public DateTime DateCreated {get;组;
}

查看:

  @using(Html.BeginForm())
{
@ Html.TextBoxFor(m => m.DateCreated,new {
@type =date,
@Value = Model.DateCreated.ToString(d)
})
< input type =submit>
}

//这是渲染输入
< input Value =12/1/2013​​data-val =truedata-val-date = DateCreated字段必须是一个日期。 id =DateCreatedname =DateCreatedtype =datevalue =12/1/2013 4:03:19 PM/>

JS:

 code> $('input [type =date]')。datepicker(); 

这一切都按预期工作; datepicker具有默认选择的输入值的日期,值为 model.DateCreated 设置为 DateTime 对象帖子请注意,我没有将格式放在任何地方,但在显示值中,我用标准的短日期模式替换了完整的日期。



你可以尝试简化你的代码来匹配我有什么,让我知道会发生什么?


I am building an MVC4 app and in my model I have these fields:

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime mDateCreated { get; set; }

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

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

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime mStartDate { get; set; }

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

I am trying to set datepickers in a view. Here's what I have done so far:

<div class="float-left">
    <p>Date Created:</p>
    <p>Date of last modification:</p>
    <p>Date Last Displayed:</p>
    <p>Date of promotion's start:</p>
    <p>Date of promotion's end:</p>
</div>
<div class="float-right">
    <p>
        @Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
            {
                @value = Model.mCardOfTheDay.mDateCreated,
                @selectedDate = Model.mCardOfTheDay.mDateCreated,
                @class = "datePick",
                @type = "date",
                @id = "dateCreated"
            })
    </p>
    <p>
        @(Model.mCardOfTheDay.mDateModified != null ? Html.DisplayFor(_item => _item.mCardOfTheDay.mDateModified) : Html.Label(ValueDomain.FIELD_UNAVAILABLE))
    </p>
    <p>@(Model.mCardOfTheDay.mDateLastDisplayed != null ? Html.DisplayFor(_item => _item.mCardOfTheDay.mDateLastDisplayed) : Html.Label(ValueDomain.FIELD_UNAVAILABLE))</p>
    <p>
        @*@Html.EditorFor(_item => _item.mCardOfTheDay.mStartDate, new { @class = "datePick", @type="date" })*@
        @*@Html.TextBoxFor(_item => _item.mCardOfTheDay.mStartDate, new {@id = "dateStart"})*@
      @*  @Html.TextBoxFor(_item => _item.mCardOfTheDay.mStartDate, new
            {
                @value = (DateTime?) Model.mCardOfTheDay.mStartDate,
                @selectedDate = (DateTime?) Model.mCardOfTheDay.mStartDate,
                @class = "datePick",
                @type = "date",
                @id = "dateStart"
            })*@
    </p>
    <p>
        @Html.TextBoxFor(_item => _item.mCardOfTheDay.mEndDate, new
            {
                @value = Model.mCardOfTheDay.mEndDate,
                @selectedDate = Model.mCardOfTheDay.mEndDate,
                @class = "datePick",
                @type = "date",
                @id = "dateEnd"
            })
    </p>
</div>
<div class="clear"></div>

And CSS to show what I'm doing with the classes:

$('.datePick').datepicker({
    dateFormat: "dd/ww/yy",
});

$('.datePick').each(function () {
    var a = $(this).datepicker({
        dateFormat: "dd/ww/yy",
        defaultDate: new Date($(this).val())
    });
});

This shows the various problems I have. First:

  1. Using Html.TexborFor helpers with @value, @selectedDate and so on does displays a datepicker, but this datepicker's default shown value is aaaa-mm-dd instead of the value binded to the model and when I pass the model to the controller none of the data is kept (meaning that the mEndDate is always null);
  2. Trying only to set a datepicker ends up with the same results;
  3. Here's a sample of Html code behind to show you the "results" I have: <input class="input-validation-error datePick" data-val="true" data-val-date="The field mDateCreated must be a date." data-val-required="The mDateCreated field is required." id="dateCreated" name="mCardOfTheDay.mDateCreated" selectedDate="11/21/2013 00:00:00" type="date" value="" />
  4. And if I use the EditorFor, all I have is a date in string format, no datepicker.

What I want is a datepicker with the proper date selected that passed the selected date to the controller method in post. Can anyone help me figure out why this does not work?

解决方案

You shouldn't be overriding the value of the date input with the same date in a different format, there is no reason to and it will only cause headaches. From my experience you're better off leaving it as is.

@Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
{
    @selectedDate = Model.mCardOfTheDay.mDateCreated,
    @class = "datePick",
    @type = "date",
    @id = "dateCreated"
})

What you need to do however is configure the datepicker properly so that it knows how to interpret the date coming from your database. If you want to show a different format to the user than the one posted back to the server, you can make use of the altField (source) and altFormat (source) option.

That will allow you to use dateFormat to display the date in whichever format you like in the input to the user, while keeping the posted value in the right format.

You won't need this anymore :

$('.datePick').each(function () {
    var a = $(this).datepicker({
        dateFormat: "dd/ww/yy",
        defaultDate: new Date($(this).val())
    });
});

You'll also need to get rid of ApplyFormatInEditMode = true on your model property attributes. Let the framework handle dates based on current culture, don't try working against it by applying formats all over the place.

Just leave the textbox value be whatever your database sends, and use the datapicker's functionality to do what you need on the client side.

The only time I would advise overriding the value is if you're worried about the input showing the time part when you only want the date. In that case, you should do it like so :

@Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
{
    @selectedDate = Model.mCardOfTheDay.mDateCreated,
    @class = "datePick",
    @type = "date",
    @id = "dateCreated",
    @Value = Model.mCardOfTheDay.mDateCreated.ToString("mm/d/yyyy")
})

Notice @Value with a capital v, that is actually important and not a typo. You then pass a date format to the ToString method, but it needs to be the same format as your database.


Edit:

I went ahead and built a small test-case to try and replicate your issue. Here's what I have :

Controller :

public ActionResult Test()
{
    return View(new TestViewModel()
    {
        DateCreated = DateTime.Now.AddDays(10)
    });
}

[HttpPost]
public ActionResult Test(TestViewModel model)
{
    return RedirectToAction("Test");
}

ViewModel :

public class TestViewModel
{
    public DateTime DateCreated { get; set; }
}

View :

@using (Html.BeginForm())
{
    @Html.TextBoxFor(m => m.DateCreated, new {
        @type = "date",
        @Value = Model.DateCreated.ToString("d")
    })
    <input type="submit">
}

// This is the rendered input
<input Value="12/1/2013" data-val="true" data-val-date="The field DateCreated must be a date." id="DateCreated" name="DateCreated" type="date" value="12/1/2013 4:03:19 PM" />

JS:

$('input[type="date"]').datepicker();

This all works as expected; datepicker has the date in the input's value selected by default, value of model.DateCreated is set to a DateTime object on post. Notice I haven't messed with formats anywhere but in the display value where I replaced the full date with the standard short date pattern.

Can you try simplifying your code to match what I have and let me know what happens?

这篇关于将日期时间模型值绑定到datepicker并将其传递给控制器​​方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆