SelfTaughtCodingIdiot
SelfTaughtCodingIdiot

Reputation: 109

datepicker not displaying value and posting updating to null on post

I have two issues that I'm not sure if the are related. I have a datepicker in an edit view that is not taking the value from the model property. The rendered HTML has the value, only in a different format than is specified in the placeholder.

Edit Rendered HTML:

<div class="form-group">
        <label class="control-label col-md-2" for="start_date">Activity Date</label>
        <div class="col-md-10">
            <input class="text-box single-line" data-val="true" data-val-date="The field Activity Date must be a date." id="start_date" name="start_date" type="date" value="5/31/2017" />
            <span class="field-validation-valid" data-valmsg-for="start_date" data-valmsg-replace="true"></span>
        </div>
</div>

Edit View:

@model DAR_Team_Site.ViewModels.projectLocationViewModel
<div class="form-group">
        @Html.LabelFor(model => model.start_date, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.start_date)
            @Html.ValidationMessageFor(model => model.start_date)
        </div>
    </div>

ViewModel Code:

using DAR_Team_Site.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web.Security;
using DAR_Team_Site.Infrastructure;
using System.Web.Mvc;
using PagedList;


namespace DAR_Team_Site.ViewModels
{
public class projectLocationViewModel 
{
    public int p_id { get; set; }
    public int l_id { get; set; }
    public int g_id { get; set; }
    public int e_id { get; set; }
    public Nullable<int> b_id { get; set; }
    public Nullable<int> u_id { get; set; }

    [Display(Name = "Active")]
    public string status { get; set; }

    [Display(Name = "Status")]
    public string state { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "Reporting Date")]
    public Nullable<System.DateTime> activity_date { get; set; }

    [Display(Name = "Ignored")]
    public string include { get; set; }

    [Display(Name = "Cost Type")]
    public string cost_type { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "Activity Date")]
    public Nullable<System.DateTime> start_date { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "End of Operations")]
    public Nullable<System.DateTime> end_date { get; set; }

    public virtual BizUnitViewModel bizunit { get; set; }
    public virtual EntityViewModel entity { get; set; }
    public virtual GeographyViewModel geography { get; set; }
    public virtual LocationViewModel location { get; set; }
    public virtual ProjectViewModel project { get; set; }
    public virtual User User { get; set; }
    public SelectList p_names { get; set; }
    public SelectList l_names { get; set; }
    public SelectList e_names { get; set; }
    public SelectList b_names { get; set; }
    public SelectList g_names { get; set; }
    public SelectList u_names { get; set; }
    public SelectList state_list { get; set; }
    public SelectList cost_options { get; set; }
    public SelectList toggles { get; set; }

    public IPagedList<DAR_Team_Site.Models.project_location> projectLocation { get; set; }

    public static implicit operator projectLocationViewModel(project_location project_location)
    {
        return new projectLocationViewModel
        {
            p_id = project_location.p_id,
            l_id = project_location.l_id,
            e_id = project_location.e_id,
            g_id = project_location.g_id,
            b_id = project_location.b_id,
            u_id = project_location.u_id,
            project = project_location.project,
            location = project_location.location,
            entity = project_location.entity,
            geography = project_location.geography,
            bizunit = project_location.bizunit,
            User = project_location.User,
            status = project_location.status,
            state = project_location.state,
            include = project_location.include,
            cost_type = project_location.cost_type,
            start_date = project_location.start_date,
            activity_date = project_location.activity_date,
            end_date = project_location.end_date
        };
    }

    public static implicit operator project_location(projectLocationViewModel vm)
    {
        return new project_location
        {
            p_id = vm.p_id,
            l_id = vm.l_id,
            e_id = vm.e_id,
            g_id = vm.g_id,
            b_id = vm.b_id,
            u_id = vm.u_id,
            project = vm.project,
            location = vm.location,
            entity = vm.entity,
            geography = vm.geography,
            bizunit = vm.bizunit,
            User = vm.User,
            status = vm.status,
            state = vm.state,
            include = vm.include,
            cost_type = vm.cost_type,
            start_date = vm.start_date,
            activity_date = vm.activity_date,
            end_date = vm.end_date
        };
    }
}
}

The post in the Controller that is setting this value null on the update:

public ActionResult Edit( project_location project_location)
    {

        if (ModelState.IsValid)
        {
            db.Entry(project_location).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }

Upvotes: 0

Views: 390

Answers (2)

SelfTaughtCodingIdiot
SelfTaughtCodingIdiot

Reputation: 109

The issue landed on how the date string was formatted. I found that changing the editortemplate from:

@Html.TextBox("", String.Format("{0:d}", 
Model.ToShortDateString()),
new { @class = "datefield", type = "date" })

To:

@model Nullable<DateTime>

@{
DateTime dt = DateTime.Now;
string ds = string.Empty;
if (Model != null)
{
    dt = (System.DateTime)Model;
    ds = dt.ToString("yyyy-MM-dd");
}

@Html.TextBox("", ds, new { @class = "datefield", type = "date"  })
}

This allowed me to get the date to display in the textbox correctly instead of the "yyyy-mm-dd" placeholder, and persisted the value back through the controller. This also allowed for the null values that will occur in other date fields.

Upvotes: 0

C. Helling
C. Helling

Reputation: 1402

You can refer to this example on the Microsoft website to see the proper way to integrate jQuery's Datepicker with C# MVC/Razor. Instead of using the @Html.EditorFor() (which typically expects text input), try this instead:

@Html.TextBox("", String.Format("{0:d}", model.start_date.ToShortDateString()),
  new { @class = "datefield", type = "date" })

Upvotes: 1

Related Questions