MVC5 with EF6 : EditorFor() with an ICollection - asp.net-mvc

I have a problem with my MVC5/EF6 website. I have a model like this :
(source: hostingpics.net)
When I'm creating an activity, I would like to add at least one date to it. So I created a new field in the form :
<div class="form-group">
#Html.LabelFor(model => model.Days, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Days)
#Html.ValidationMessageFor(model => model.Days)
</div>
</div>
According to various sources I've read here and there (https://stackoverflow.com/a/11403858/360708), I must create a file Day.cshtml in View/Shared/EditorTemplates/ so that I can tell MVC I want Day to have an editor for "day1" (DatePicker here).
This is because my model Day is an ICollection inside Activity, so I can't access the field day1 like this : "model.Days.day1". I've tried creating the Day.cshtml but it doesn't work. Here's the content of Day.cshtml
#model GAS_VS2013.Models.Day
#Html.EditorFor(o => o.day1)
Am I forgetting something or doing something wrong ?
Thanks

Thanks to Fals, it's now working with :
<div class="form-group">
#Html.LabelFor(model => model.Days, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Days, "Day")
#Html.ValidationMessageFor(model => model.Days)
</div>
</div>
To display the textbox as a HTML5 DatePicker, don't forget to add a DateTime.cshtml in the EditorTemplates with the following code (type of your day field must be DateTime) :
#model Nullable<DateTime>
#{
DateTime dt = DateTime.Now;
if (Model != null)
{
dt = (System.DateTime)Model;
}
#Html.TextBox("", String.Format("{0:d}", dt.ToShortDateString()), new { #class = "form-control datecontrol", type = "date" })
}
Source : http://www.aubrett.com/InformationTechnology/WebDevelopment/MVC/DatePickerMVC5.aspx(

Related

MVC Saving field data from a view

I am using MVC and on my Index view I have placed a 'EditorFor' and a 'DropDownFor' fields on it for data entry. I would like a user to enter values and then 'Save' the record from the view. However I am having problems retrieving the data entered. I have tried creating an ActionResult and binding the data however nothing comes across. I have tried giving the fields id names and passing them in as parameters and again nothing is passed.
This is what I have in my View -
<h3>Sensitive Areas</h3>
#Html.HiddenFor(model => model.BurnSitesID, new { #id = "burnSitesID"})
<div class="form-group">
#Html.LabelFor(model => model.SensitiveTypesID, "Sensitive Area", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("SensitiveTypesID", string.Empty)
#Html.ValidationMessageFor(model => model.SensitiveTypesID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DistSensitiveArea, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DistSensitiveArea, new { #id = "distSensitiveArea" })
#Html.ValidationMessageFor(model => model.DistSensitiveArea, "", new { #class = "text-danger" })
</div>
<input type="submit" id="CreateArea" value="Save"/>
How would you take the values entered and pass them to the controller? I have tried a button however if my button is not named the exact same thing as the view it does not do anything.
Please use Html.BeginForm("ActionName","ControllerName", FormMethod.Post) .
Button should be Submit type .
If you are use textbox .
#Html.TextBoxFor("txtName", "", new { #class = "form-control", #maxlength = "50" })
<input type="submit" id="CreateArea" value="Save"/>
[HttpPost]
public ActionResult ActionName(FormCollection form)
{
string Name=form["txtName"].ToString();
}
Where Name is a name/ID of field name .
Thanks .

CSS Class for DropDownListFor

Using scaffolded items in an MVC5 application, I see things like text fields given the CSS class "form-control". The fields all have consistent rounded corners, same font color/size etc.
Now I've added a dropdown list using "#Html.DropdownListFor" and it's square, with a different font colour.
I know I can specify which CSS class to use in the Razor e.g.
#Html.DropDownListFor(model => model.OrderItemTypeId, (SelectList)ViewBag.OrderItemTypes, new { htmlAttributes = new { #class = "###########" } })
But I don't know what to replace ########### with. If I specify "form-control" just gives me the square box I described above. "form-control select" doesn't seem to do much either.
Here's a bigger snippet showing a well-styled text field directly above it
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderItemTypeId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.OrderItemTypeId, (SelectList)ViewBag.OrderItemTypes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OrderItemType, "", new { #class = "text-danger" })
</div>
</div>
Is there a value I can use that will give my dropdown the same appearance as all the other text fields I already have?
Thanks
The third parameter already is the htmlAttributes field, so your syntax is wrong. This is what you're after:
#Html.DropDownListFor(model => model.OrderItemTypeId,
(SelectList)ViewBag.OrderItemTypes,
new { #class = "form-control etc" })
See Microsoft Docs.
You need to make sure it sits within proper hierarchy of outer tags with their corresponding classes.
See the code below that I took from this article - How to use Bootstrap 3 validation states with ASP.NET MVC Forms
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<div class="panel panel-default">
<div class="panel-body">
#using (Html.BeginForm("UserProfile", "Profile", FormMethod.Post, new { role = "form", id="userForm" })) {
#* State selection dropdown *#
<div class="form-group">
#Html.LabelFor(m => m.State)
#Html.DropDownListFor(m => m.State, // Store selected value in Model.State
// This argument needs some explanation - here we take a Distionary<string, string>
// and turn it into an instance of SelectList, see blog post for more details
new SelectList(Model.States, "Key", "Value"),
// Text for the first 'default' option
"- Please select your state -",
// A class name to put on the "<select>"
new { #class = "form-control" }
)
#Html.ValidationMessageFor(m => m.State)
</div>
<button type="submit" class="btn btn-primary">Update</button>
}
</div>
</div>
</div>
</div>

Confused with difference in MVC 5 TextBoxFor, EditFor, and TextAreaFor?

I've been having problems getting formatting to work in my MVC 5 View. The View was scaffold as a TextAreaFor. I added DataFormatting for my property in my ViewModel but it doesn't actually format for me. From everything I have researched I'm formatting the ViewModel correctly but I haven't been able to figure out why the formatting isn't actually working.
So, I tried using #Html.EditFor. That seemed to make the date formatting work but it didn't to apply the Bootstrap "form-control" class. I then tried #Html.TextBoxFor and it responded like the #Html.TextAreaFor, no formatting but did apply the Bootstrap class.
I don't know which one to use and what else I need to do to get my View to not only format the date but to also apply the Bootstrap CSS.
Here is my ViewModel property.
[DisplayName("Call Date")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime? CallDate { get; set; }
This is the original TextAreaFor that the scaffolding created. No formatting but Bootstap CSS works.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
This is the EditFor that formats the date but doesn't apply Bootstrap CSS.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
This is the TextBoxFor that responded like the TextAreaFor.
<div class="form-group">
#Html.LabelFor(model => model.CallDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CallDate, new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(model => model.CallDate, "", new { #class = "text-danger" })
</div>
</div>
To add html attributes using #Html.EditorFor() you must be using MVC-5.1+, and if you are, then the usage is
#Html.EditorFor(m => m.CallDate, new { htmlAttributes = new { #class="form-control datepicker" }})
If you not using MVC-5.1+, and you want to generate a textbox and also format the date value, then the usage is (where the 2nd parameter is the format string)
#Html.TextBoxFor(m => m.CallDate, "{0:d}", new { #class = "form-control datepicker" })
Note that #Html.TextAreaFor() generate a <textarea> element for multi-line text and would not be appropriate for a DateTime property.

Fill the date time view with current date

I would like to fill the textbox field with the current date automatically when the page loads and still be able to edit it but when I place 'datetime.now' it does not seem to work
this is my view:
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, "Returned date", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate,DateTime.Now.ToShortDateString()),new { htmlAttributes = new { #class = "box" } })
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
You need to assign your date something like below.
#Html.TextBoxFor(model => model.ReturnedDate, new { #Value = #DateTime.Now.ToShortDateString() })

MVC Client side validation?

I have 3 textboxes ...one for day, second for month and third for year. I want to use mvc validation to check if one of this field is empty and then show *. Is it possible on button submit display just one error message if one of those fields are empty?
<div class="form-group">
<label for="dateofbirth" class="control-label col-lg-5">
#Html.Label(#BetXOnline.TranslationProvider.Instance.GetTranslationMessage("BIRTHDATE")):
#Html.ValidationMessage("*")
</label>
<div class="col-lg-2">
#Html.TextBoxFor(m => m.Register.Day, new { id = "day_birthdate", #class = "form-control" })
</div>
<div class="col-lg-2">
#Html.TextBoxFor(m => m.Register.Month, new { id = "month_birthdate", #class = "form-control" })
</div>
<div class="col-lg-3">
#Html.TextBoxFor(m => m.Register.Year, new { id = "year_birthdate", #class = "form-control" })
</div>
You can add the #ValidationMessageFor for all fields under same label.
<label for="dateofbirth" class="control-label col-lg-5">
#Html.Label(#BetXOnline.TranslationProvider.Instance.GetTranslationMessage("BIRTHDATE"))
:
#Html.ValidationMessageFor(m => m.Register.Day,"", new { #class = "text-danger" })
#Html.ValidationMessageFor(m => m.Register.Month,"", new { #class = "text-danger" })
#Html.ValidationMessageFor(m => m.Register.Year,"", new { #class = "text-danger" })
</label>
In your module class on the property attached with textbox provide attribute [Required].
than you can use of ValidationSummary which is already available in Asp.net MVC.
if you want to display message just beside file than do use ValidationMessageFor
Check : ASP.NET MVC Client Side Validation
class property definition for this
[Required(ErrorMessage = "*")]
public string Name { get; set; }
Example
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>

Resources