I have a Product Model like this
public class ProductViewModel
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
public ProductTypeFlag ProductType { get; set; }
public string BikeMake { get; set; }
public string BikeModel { get; set; }
public string CarMake { get; set; }
public string CarModel { get; set; }
public string TrainMake { get; set; }
public string TrainModel { get; set; }
}
public enum ProductTypeFlag
{
Bike = 0,
Car = 1,
Train = 2
}
As you can see, I only have three products to choose from: bike, car or train.
My Create New Product View is currently looking like this ... where I have a drop down list selection for ProductType
#model WebApplication14.Models.ProductViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>ProductViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsActive, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.ProductType, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ProductType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BikeMake, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BikeMake, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BikeMake, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BikeModel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BikeModel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.BikeModel, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CarMake, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CarMake, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CarMake, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CarModel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CarModel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CarModel, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TrainMake, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TrainMake, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TrainMake, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TrainModel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TrainModel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TrainModel, "", 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-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Now, what I want to do is, only display Product information that is relevant to selected product. For example, if I select Bike as a product then I only want to see the BikeMake and BikeModel available - i.e. I do not want to see Car/Train-Make&Model to be there as it is irrelevant.
You can group the properties related to each vehicle type in a container div and conditionally hide/show based on the selection from the dropdown.
For example
<div my-section="section-0" style="display:none;">
<div class="form-group">
#Html.LabelFor(model => model.BikeMake, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BikeMake, new { #class = "form-control" } )
#Html.ValidationMessageFor(model => model.BikeMake)
</div>
</div>
</div>
<div my-section="section-1" style="display:none;">
<!-- Inputs for code car related fields goes here -->
</div>
<div my-section="section-2" style="display:none;">
<!-- Inputs for Train related fields goes here -->
</div>
And now listen to the change event on your SELECT element and show only that container div.
$(function () {
// Show the section for the current(default) selection of the dropdown
var t = $("#ProductType").val();
var item = $("[my-section='section-" + t + "']").show();
// Wire up change event code for dropdown
$("#ProductType").change(function (e) {
// Hide all the sections (including previously shown)
$("[my-section]").hide();
//Select only the section corresponding the the dropdown selection
var item = $("[my-section='section-" + $(this).val() + "']").show();
})
});
For example, If you select the second item in your dropdown, The jQuery selector code $("[my-section='section-" + $(this).val() + "']") will return the div with my-section attribute value set to "section-1"
Related
I cannot figure out why my view only passes back a NULL for a model to my controller.
This is for an Edit Post method. I checked other controllers with Edit Post methods that are structured the same way as this one and they work fine. It seems to be just this view and controller.
Here is my view:
#model Non_P21_Quote_System_v1._0.Models.gl_code
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#if (TempData["Message"] != null)
{
<div style="color:green">
#TempData["Message"]
</div><br />
}
#if (ViewBag.error != null)
{
<div style="color:red">
<h3>#ViewBag.error</h3>
</div><br />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>gl_code</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_code, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.GL_description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("expense_type_ID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.expense_type_ID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("eag", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.eag, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "gl_Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
if (ModelState.IsValid)
{
db.Entry(gl_code).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("gl_Index");
}
ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
return View(gl_code);
}
When I debug it, I see the model being passed in is of value NULL. I am seeing this on the controller side at the the parameters part of the Edit method.
Its null because your model contains a property named gl_code and you have also named the parameter for your model gl_code in the POST method.
Change the name of one or the other and the model will bind correctly.
What is happening internally is that the form submits a name/value pair for each successful form control, in your case gl_code=someValue. The DefaultModelBinder first initializes a new instance of your model. It then reads the form values and finds a match for the property in your model and sets it to someValue. But it also finds a match in the method parameters and tries set the value of the parameter to someValue, which fails (because you cannot do gl_code gl_code = "someValue";) and the model becomes null.
It appears you have a property on your view model called gl_code. In your controller, you also refer to the view model as gl_code.
Try changing this.
public async Task<ActionResult> Edit(gl_code gl_code)
To
public async Task<ActionResult> Edit(gl_code model)
I have a VIEW which has a form plus a submit button.
I also have a MODEL which I used to create my view but now I really have no idea on how to use JavaScript in such a view which does not have input tags or form tags to check if the input field are empty.
Please help with options i could possible use to validate my fields.
This is my View below
<h2>Index2</h2>
<h5>#ViewBag.Msg</h5>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>BookViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<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.Author, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Author, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Author, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Year, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Year, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Year, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Genre, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Genre, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Genre, "", 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-default" />
</div>
</div>
</div>
}
This is my MODEL below where I tried so set validations but did not work
public class BookViewModel {
[Required(ErrorMessage = "This Name field can not be empty.")]
[Display(Name = "Title")]
public string Title { get; set; }
[Required(ErrorMessage = "This Author field can not be empty.")]
[Display(Name = "Author")]
public string Author { get; set; }
[Required(ErrorMessage = "This Year Published field can not be empty.")]
[Display(Name = "Year")]
public string Year { get; set; }
[Required(ErrorMessage = "This Genre field can not be empty.")]
[Display(Name = "Genre")]
public string Genre { get; set; }
}
Lastly is my CONTROLLER
public ActionResult Index2() {
return View();
}
public ActionResult Display(string Title, string Author, string Genre, string Year) {
BookViewModel NewBook = new BookViewModel();
NewBook.Title = Title;
NewBook.Author = Author;
NewBook.Genre = Genre;
NewBook.Year = Year;
myList.Add(NewBook);
return View(myList);
}
Add following code in your web config:-
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
And Add following scripts in your master page:-
<script src="/Scripts/jquery-1.7.1.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js">
</script>
I have two partial views in my application. One contains a select list to decide between payments methods. If the user chooses Direct debit another partial opens with the relevant input fields and validation. If they choose Cheque this form is hidden. However the validation isn't removed
Direct Debit Partial View
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Sort Code", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(Model => Model.SortCode12, new { #class = "control-label col-md-1", #readonly = "readonly" })
<div class="col-md-1"> - </div>
#Html.TextBoxFor(Model => Model.SortCode34, new { #class = "control-label col-md-1", #readonly = "readonly" })
<div class="col-md-1"> - </div>
#Html.TextBoxFor(Model => Model.SortCode56, new { #class = "control-label col-md-1", #readonly = "readonly" })
</div>
<div class="col-md-10">
#Html.ValidationMessageFor(model => model.SortCode12, "", new { #class = "text-danger" })
#Html.ValidationMessageFor(model => model.SortCode34, "", new { #class = "text-danger" })
#Html.ValidationMessageFor(model => model.SortCode56, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("Account Number", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(Model => Model.BankAccountNumber, new { #class = "control-label col-md-2", #readonly = "readonly" })
</div>
<div class="col-md-10">
#Html.ValidationMessageFor(model => model.BankAccountNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("Account Name", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(Model => Model.BankAccountName, new { #class = "control-label col-md-10", #readonly = "readonly" })
</div>
<div class="col-md-10">
#Html.ValidationMessageFor(model => model.BankAccountName, "", new { #class = "text-danger" })
</div>
</div>
Payment method partial view
<div id="CurrentPaymentMethod">
<div class="panel-group">
<div class="panel panel-default">
<div class="cl panel-heading">
<h4 class="panel-title">
Payment Method
</h4>
</div>
<div class="panel-body">
<div class="form-group">
#Html.Label("Payment Method", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(Model => Model.PaymentMethodID,
new SelectList(Model.PaymentMethods, "Id", "Description"),
"Select Payment Method",
new { #class = "form-control", #required = "required", #onchange = "ChangePaymentMethod(this.value)" })
</div>
<div class="col-md-10">
#Html.ValidationMessageFor(model => model.PaymentMethodID, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function ChangePaymentMethod(paymentMethodID)
{
#* Show Direct Debit section if the DD payment option (ID=0) has been selected*#
if (paymentMethodID == 0) {
document.getElementById("CurrentDirectDebitDetails").style.display = "block";
}
else {
document.getElementById("CurrentDirectDebitDetails").style.display = "none";
document.getElementById("SortCode34").removeAttribute("data-val-required");
document.getElementById("SortCode12").removeAttribute("data-val-required");
document.getElementById("SortCode56").removeAttribute("data-val-required");
document.getElementById("BankAccountNumber").removeAttribute("data-val-required");
document.getElementById("BankAccountName").removeAttribute("data-val-required");
}
}
At the bottom I have created some javascript to show and hide the direct debt from depending on the drop down selection item. This works however the validation remains
Any help with this would be appreciated
You can give specific class Name for all validation messages, errorMessagesForm1 form2 etc ...
then using this class to select the messages and hide it or remove it or whatever you want to do with it.
something like this,
#Html.ValidationMessageFor(model => model.PaymentMethodID, "", new { #class = "text-danger ErrMsgsForm2" })
js
var ErrorMSGs= document.getElementsByClassName("ErrMsgsForm2");
// Array of all error messages, loop through it
for(var i = 0; i < ErrorMSGs.length; i++){
ErrorMSGs[i].style.visibility = "hidden"; // or any other method, maybe change innerHTML etc
}
having Html code :
<div class="form-group has-feedback">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Name" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
<span class="form-control-clear glyphicon glyphicon-remove form-control-feedback"></span>
</div>
</div>
trying to make clear button with javascript :
$(document).ready(function() {
$('.form-control-clear').on("click", function () {
$(this).val('')
});
});
but not working
I have following razor code. I need to add this dynamically on button click in client side.
<div class="form-group" id="transitem" name="transitem">
<div class="col-md-11" id="tritem" name="tritem">
#Html.LabelFor(model => model.transaction_item_id, "transaction_item_id", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div id="trans_dd_1" name="trans_dd_1">#Html.DropDownList("transaction_item_id", null, htmlAttributes: new { #class = "form-control", #id = "trans_id_#", #Name = "trans_id_#" })</div>
#Html.ValidationMessageFor(model => model.transaction_item_id, "", new { #class = "text-danger" })
</div>
<div>
#Html.LabelFor(model => model.transaction_itmQty, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-3">
#Html.EditorFor(model => model.transaction_itmQty, new { htmlAttributes = new { #class = "form-control", #id = "trans_qty_#", #Name = "trans_qty_#" } })
#Html.ValidationMessageFor(model => model.transaction_itmQty, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-2"><input type="button" class="btnPlus" value="+" /></div>
</div>
</div>
I have written following script, but it is not working as expected. I need to change the name and id of trans_id_# and trans_qty_#. They are being generated by html helper, html.editorfor. Below is my script, which can copy the new element, but i am not able to change the id or name.
<script type="text/javascript">
var itm_cnt = 1;
$(document).ready(function () {
$(document).on("click", ".btnPlus", function () {
var new_clone = $('#tritem').clone();
itm_cnt = itm_cnt + 1;
var new_name = "trans_id_" + itm_cnt.toString();
$(new_clone).attr("name", "new_name");
$('#transitem').append(new_clone);
window.alert(itm_cnt);
});
});