Inputs inside Partialview takes value from main model - asp.net-mvc

I render a PartialView inside my main View
View:
#model FullProductViewModel
...
<div class="send-container">
#Html.Partial("_CommentForm", new CommentViewModel { ProductId = Model.Id, Title = "" , Context="" })
</div>
...
I have a filed with name "Title" in Both my classes "FullProductViewModel" and "CommentViewModel".
_CommentForm PartialView:
#model CommentViewModel
<p class="page-title">#Resources.SendComment</p>
#using (Html.BeginForm("Comment", "Home", FormMethod.Post, new { #class = "form-comment form-submit" }))
{
#Html.AntiForgeryToken()
<div class="input-group">
#Html.LabelFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="input-group">
#Html.LabelFor(model => model.Context)
#Html.ValidationMessageFor(model => model.Context, "", new { #class = "text-danger" })
#Html.TextAreaFor(model => model.Context, htmlAttributes: new { #class = "form-control", rows = "8" })
</div>
<div class="input-group">
#Html.LabelFor(model => model.CaptchaCode)
#Html.ValidationMessageFor(model => model.CaptchaCode, "", new { #class = "text-danger" })
#Html.EditorFor(model => model.CaptchaCode, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="captcha-wrapper">
<img alt="Captcha" id="imgcaptcha" src="#Url.Action("Captcha", "Captcha")" />
</div>
<button class="btn btn-submit" type="submit">#Resources.SendMessage</button>
}
The problem is "Title" inside PartialView take its value form "FullProductViewModel" model but not "CommentViewModel ". i can easily change the field name "Title" inside one of models to solve problem... but why this happened and how i can fix it without change field name?

Your Title property is conflicting with the #{ ViewBag.Title = ".. line of code in your view (the ViewBag code is used by the _Layout.cshtml file to set the global <title> attribute for the page).
All the HtmlHelper methods that generate form controls set the value by checking (in order)
ModelState
The ViewDataDictionary (ViewData or ViewBag)
The value of the models property
In your case, nothing has been added to ModelState. But because a value for Title has been added to the ViewDataDictionary, its that value which is used for the value of your textbox. The method never gets to read the actual value you have set in your model.
The only realistic option (unless you want to modify the code in the _Layout and all views that use it) is to change the name of the property.

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>

#Html.CheckboxFor not displaying in mvc

The checkbox is not displaying in page. I tried many solutions in google. Nothing worked. Here s the code:
#model project.gamestatus
#using (Html.BeginForm("Create", "Calculator", FormMethod.Post, new { id = "frmID" }))
{
//other codes
<div class="form-group">
#Html.Label("Show on Screen", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.CheckBoxFor(m => m.display_status)
#Html.ValidationMessageFor(model => model.display_status, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-info" />
</div>
</div>
}
Only if the checkbox is shown in page i can proceed with validation. In my view there is no checkbox
First of all, you need to ensure that the display_status model is of boolean type and assigned the display name to it along with any validation.
[Display(Name="CheckBox Display Name")]
[Required]
public bool display_status { get; set; }
Also, #Html.CheckBoxFor do not support the label of checkbox. Therefore, you can have the label of the checkbox using #Html.LabelFor as follow:
<div class="form-group">
#Html.Label("Show on Screen", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.CheckBoxFor(m => m.display_status)
#Html.LabelFor(m => m.display_status)
#Html.ValidationMessageFor(m => m.display_status, "", new { #class = "text-danger" })
</div>
</div>
though its a very old post but I undergo this issue todat, but when I inspected I found that the CSS property opacity was set to 0 so changing it to 1 will solve the issue
#Html.EditorFor(model => model.Active, new { htmlAttributes = new { style = "opacity: 1" } })
I fixed the problem by setting the height to 20px explicitly. When I examined the page, it was being set to 20%:
#Html.CheckBoxFor(m => m.ExistingUser, new { style="height:20px" })

How do I post varied length list to controller?

MVC4. I have a dynamic list on a view, a new textbox is added with button click (which adds a partialView) so user can enter a list of stuff. That is contained in a form element with a submit button.
In the controller I have tried three different types:
[HttpPost]
public ActionResult Index(IEnumerable<AccessoryVM> form)
{
-- form is NULL
[HttpPost]
public ActionResult Index(AccessoryVM form)
{
-- form has only the first item in the list
[HttpPost]
public ActionResult Index(FormCollection form)
{
-- seems to receive the list, but having trouble getting the values
All the examples I have seen are using a for list to add an index to each item, but they aren't using a dynamic list (it has a fixed length).
What should the Controller receiving type be?
EDIT to add more detail:
Button click appends partial view:
$("#add-item").on("click", function () {
$.ajax({
url: '/Accessory/AddItem',
cache: false,
success: function (html) {
$("#form-body").append(html);
}
})
return false;
})
Partial View:
#model EmployeeHardwareRequest.Models.ViewModels.AccessoryVM
<div class="form-group col-md-3">
#Html.LabelFor(model => model.ItemDescription, htmlAttributes: new { #class = "control-label" })
<div>
#Html.DropDownListFor(model => model.AccessoryId, Model.AccessoryDdl, new { #class = "form-control" })
</div>
</div>
<div class="form-group col-md-9">
#Html.LabelFor(model => model.ProductLink, htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.ProductLink, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductLink, "", new { #class = "text-danger" })
</div>
</div>
Main View - partial is appended to the #form-body:
#using (Html.BeginForm("Index", "Accessory", FormMethod.Post, new { #id="accessory-form", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div id="form-body">
<div class="form-group col-md-3">
#Html.LabelFor(model => model.ItemDescription, htmlAttributes: new { #class = "control-label" })
<div>
#Html.DropDownListFor(model => model.SelectedAccessory, Model.AccessoryDdl, new { #class = "form-control" })
</div>
</div>
<div class="form-group col-md-9">
#Html.LabelFor(model => model.ProductLink, htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.ProductLink, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductLink, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button id="add-item" class="btn btn-primary">Add Another Item</button>
</div>
<div class="col-md-6">
<input type="submit" value="Select Software" class="btn btn-default pull-right" />
</div>
</div>
}
Most likely, you have a binding issue. Assuming all you're posting is a collection of AccessoryVM, then the parameter should be List<AccessoryVM> form. However, in order for the modelbinder properly bind the posted values, your input names must be in a specific format, namely either form[N].Foo or just [N].Foo.
You haven't given any detail about what's going on in your view, but since these are dynamically added, you must be using JavaScript to add additional inputs to the page. If you're doing it via AJAX (returning a partial view), you'll need to pass the index to your endpoint so that it can be utilized to generate the right input names. If you're using something like Knockout, Angular, etc., you should ensure that whatever template is being used to generate the inputs takes an index into account.

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