I have an entity called Person who has a list of colours. The colours have a name and active field. When I edit a person I want to be able to edit the colours attached to them. I'm having trouble doing this in the razor view - as I am getting errors.
#model InterviewTest.Domain.Entities.Person
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PersonId)
<div class="form-group">
#Html.LabelFor(model => model.IsAuthorised, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsAuthorised)
#Html.ValidationMessageFor(model => model.IsAuthorised, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsEnabled, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsEnabled)
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
</div>
</div>
I'm trying to attempt it doing this - but not working.
<h2>Favourite Colours</h2>
#foreach(var item in Model.Colours)
{
<div class="form-group">
#Html.LabelFor(item.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(item.IsEnabled)
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
</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", "Index")
</div>
Syntax error. It is incomplete in the following div
<div class="checkbox">
#Html.EditorFor**(item.)**
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
Rather use item.Name
Please make sure whether the properties in Colour class is all public and whether the isEnabled property exists.
Looking at your code it seems like IsAuthorised and IsEnabled property is available for the Model i.e the Person entity.
But in the forearch item in Model.Colours you are trying to use IsEnabled for an item i.e in this case it is Colour entity.
Are you missing the lambda expression in the LabelFor and EditorFor? You used it everywhere else.
#Html.EditorFor(model => model.IsAuthorised)
Related
I've been trying to get this problem fixed for several hours now, but can't seem to find out what's wrong here.
I have a view with a few fields that I want to post to my controller. Now, I want to check for validation errors on the client side. I've used this in several projects before by adding:
- jquery.js (version 1.12.1)
- jquery.validate.js (version 1.14.0)
- jquery.validate.unobtrusive.js (version 3.2.3)
- jquery-unobtrusive-ajax.js (version 3.2.3)
As soon as a I reference jquery.validate.unobtrusive.js, the client sided validation works. But when I press the submit button, it just won't submit the form anymore. It just won't hit the controller.
My view is as following:
<div class="row">
<div class="col-md-12">
<div class="portlet light bordered">
<div class="portlet-title">
<div class="caption">
<span class="caption-subject bold uppercase font-dark">Auto toevoegen</span>
</div>
<div class="actions">
#Html.ActionLink("Terug", "Index", null, new { #class = "btn btn-circle green btn-outline btn-sm" })
</div>
</div>
<div class="portlet-body">
#using (Html.BeginForm("Create", "Car", FormMethod.Post, new { #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.Merk, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Merk, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Merk)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Type, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Type)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Kenteken, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Kenteken, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Kenteken)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Kilometervergoeding, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Kilometervergoeding, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Kilometervergoeding)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AccountNumber, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AccountNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.AccountNumber)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DefaultCar, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DefaultCar)
#Html.ValidationMessageFor(model => model.DefaultCar)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Opslaan" class="btn blue" />
#Html.ActionLink("Annuleren", "Index", null, new { #class = "btn btn-white" })
</div>
</div>
</div>
}
</div>
</div>
</div>
My controller action looks like this:
[HttpPost]
[DisableValidation]
public ActionResult Create(CarViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
try
{
var tblCar = mapper.Map<CarViewModel, tblCar>(model);
_carAppService.Insert(tblCar);
return RedirectToAction("Index");
}
catch(Exception ex)
{
//Add proper error messages
Logger.Debug("Error occured during car adding process: " + ex.InnerException);
//add common container with errors
TempData["Error"] = "Er is iets fout gegaan :(";
return RedirectToAction("Index");
}
}
The scripts are loading in a bundle on startup and are loading in the order stated above. Now as soon as I remove the jquery.validate.unobtrusive from my bundle config, the submit button works. The client sided validation doesn't work anymore then though.
Does any know what's going on here? Thanks!
Alright I fixed the problem!
This answer will most likely only be useful is you make use of ASP.NET Boilerplate Zero template.
In ~/Common/Scripts a Javascript file was added (jquery-validation-custom.js).
The content messed with the submit button. I replaced it with my own version of a custom validation handler for modals and now it works!
I have a Form that creates an entry into my database. I am trying to add an additional form via a modal that will allow the user to populate the first form by searching a property on the webservice.
What I need is for when the user types hits search in the modal it will call an action on controller that then runs my web service client that then returns a list of appropriate information. I then want this list displayed as a table on the page. The user can then select which search result they want to use to which will then populate the original form. I think I can figure most of this out but wasnt sure of the best way to kick off the search from the modal. Code is as follows.
View
#model *******
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#Search">Populate From Service</button>
<!-- Modal -->
<div id="Search" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Search By Property</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<p>blah blah blah</p>
<div class="form-group">
<label for="API14" class="control-label col-md-2">API</label>
<div class ="col-md-10">
<input type="text" class="form-control" id="API14" aria-describedby="API14" placeholder="Enter API">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Search" class="btn btn-success" />
<input type="button" value="Close" data-dismiss="modal" class="btn btn-danger" />
</div>
</div>
</div>
</div>
</div>
</div>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.API14, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.API14, new { htmlAttributes = new { #class = "form-control"} })
#Html.ValidationMessageFor(model => model.API14, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PROP_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PROP_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PROP_NO, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PROP_NM, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PROP_NM, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PROP_NM, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTITY, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10 ">
#Html.EditorFor(model => model.ENTITY, new { htmlAttributes = new { #class = "form-control" } } )
#Html.ValidationMessageFor(model => model.ENTITY, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PROD_ZONE_NM, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PROD_ZONE_NM, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PROD_ZONE_NM, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LEASE_NAME, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LEASE_NAME, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LEASE_NAME, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.WELL_NO, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.WELL_NO, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.WELL_NO, "", 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-success" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
You could divide your issue into two steps.
Step 1: "What I need is for when the user types hits search in the modal it will call an action on controller that then runs my web service client that then returns a list of appropriate information. I then want this list displayed as a table on the page."
Add the following to your scripts section:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function () {
$('#submitModal').click(function () {
var data = {
API14: $('#API14').val()
}
$.ajax({
url: '/Default/SearchByProperty',
data: data
}).success(function (html) {
$('#API14List').html(html);
$('#Search').modal('toggle');
});
});
});
</script>
}
This is a simple ajax call that takes the value from you modal input and submits to the server. Note the "url" parameter passed in the call as this will need to match your "/{controller}/{action}". Important: You will also need to update your "Search" button#API14 to type "button", not "submit", as this will avoid a postback which is undesired when making AJAX calls.
You can then add something like this to your controller:
public ActionResult SearchByProperty()
{
var model = new List<string>();
model.Add("one");
model.Add("two");
model.Add("three");
return PartialView(model);
}
... which will require the following in a partial view file I named SearchByProperty.cshtml:
#model List<string>
<table>
#foreach (var item in Model) {
<tr class="API14-item">
<td>#item</td>
</tr>
}
</table>
Step 2: "The user can then select which search result they want to use to which will then populate the original form. I think I can figure most of this out but wasnt sure of the best way to kick off the search from the modal. Code is as follows."
If you are confident in writing jQuery, then you should be able to write some js in the scripts section of your create page that will take the values you place in your table and populate your form:
$(document).on('click', '.API14-item', function () {
//
// TODO: your code here
//
});
Hope this helps!
I have a view which contains two partial views. One to select a customer and one to create a new customer both shown within tabs on the parent page. If somebody selects a customer, and then continues with the data entry form, but then has to go back to create a new customer instead, then the data from the selected customer remains. I can replace the data by entering the new data, however, the important bit is that the customer id remains and therefore none of the other data is taken into account. Is there a way for me to reset the customer object on click of e.g. an edit button without losing data from the rest of the page?
My parent view (relevant section) is:
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-12">
#if (Model.CommunicationModel.Communication.Customer.Name == null)
{
<input id="btnCust" type="button" value="Select" class="btn btn-default selectCustomer" />
}
else
{
<span id="custSpan" style="font-size:16px; font:bold;">
#Html.DisplayFor(model => model.CommunicationModel.Communication.Customer.Name)
#Html.HiddenFor(model => model.CommunicationModel.Communication.Customer.CustomerId)
<input id="btnEditCust" type="button" value="Edit" class="btn btn-default selectCustomer" />
</span>
}
<div id="customerTabs" style="display:none;">
<hr />
<p>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Select Customer</li>
<li role="presentation">Create New Customer</li>
</ul>
</p>
<div class="tab-content">
<div id="tabs-1" role="tabpanel" class="tab-pane active">
#Html.Partial("~/Views/Communication/SelectCustomer.cshtml", Model.CustomerViewModel.AllCustomers)
</div>
<div id="tabs-2" role="tabpanel" class="tab-pane">
#Html.Partial("~/Views/Communication/CreateCustomer.cshtml", Model)
</div>
</div>
</div>
</div>
</div>
And my create customer partial view is:
#model CommunicationsLog.ViewModels.CommunicationViewModel
<div class="form-horizontal" id="addCustomerForm">
<div class="row">
<div class="col-md-12">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CommunicationModel.Communication.Customer.Name, new { htmlAttributes = new { #class = "form-control" }, #id = "name" })
#Html.ValidationMessageFor(model => model.CommunicationModel.Communication.Customer.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.ContactEmail, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CommunicationModel.Communication.Customer.ContactEmail, new { htmlAttributes = new { #class = "form-control" }, #id = "email" })
#Html.ValidationMessageFor(model => model.CommunicationModel.Communication.Customer.ContactEmail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.ContactTel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CommunicationModel.Communication.Customer.ContactTel, new { htmlAttributes = new { #class = "form-control" }, #id = "phone" })
#Html.ValidationMessageFor(model => model.CommunicationModel.Communication.Customer.ContactTel, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.CompanyName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CommunicationModel.Communication.Customer.CompanyName, new { htmlAttributes = new { #class = "form-control" }, #id = "company" })
#Html.ValidationMessageFor(model => model.CommunicationModel.Communication.Customer.CompanyName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommunicationModel.Communication.Customer.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.CommunicationModel.Communication.Customer.Address, new { htmlAttributes = new { #class = "form-control" }, #id = "address" })
#Html.ValidationMessageFor(model => model.CommunicationModel.Communication.Customer.Address, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
Any help would be greatly appreciate. Im stumped :)
You're using Partials, meaning the html already been loaded and rendered when it reach the client.
To handle the case of Id is being sent, you should mark ..Customer.CustomerId has disabled="disabled" or readonly, this will avoid the Client side of submitting the Input tag, which will result of the Server side "think" (If you implemented it in that fashion) that this is a new customer.
You can easily achieve it using jQuery 1.6+:
$('#TheCustomerId').prop('disabled', true);
$('#TheCustomerId').prop('disabled', false);
Disable on < 1.6: Disable/enable an input with jQuery?
I Have the following form on a view
#using (Html.BeginForm("AddInterest", "Club", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
<div class="form-group">
<div class="col-md-10 col-md-offset-1">
<h3>Not listed? - Add extras here</h3>
</div>
</div>
#Html.HiddenFor(model => model.ClubTypeId)
#Html.HiddenFor(model => model.ClubId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="row col-md-offset-1 col-md-11">
<div class="col-md-4">
#Html.LabelFor(model => model.InterestName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InterestName, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<input type="submit" value="Add" class="btn btn- success" />
</div>
</div>
</div>
</div>
</div>
</div>
}
Everything is good apart from the submit button sits inline horizontally with the labels not the editor boxes, how can I get it to drop down?
i.e.
Label Label
Text Box Text Box Button
NOT
Label Label Button
Text Box Text Box
Its currently showing like this:
You should recreate your form following this pattern:
<div class="form-group">
#Html.LabelFor(model => model.InterestName, htmlAttributes: new { #class = "col-md-4 control-label" })
<div class="col-md-8">
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InterestName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "col-md-4 control-label" })
<div class="col-md-8">
#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">
<div class="col-md-offset-4 col-md-8">
<input type="submit" value="Add" class="btn btn-success" />
</div>
</div>
More information at http://getbootstrap.com/css/#forms-horizontal
Edit
If you want them inline vertically:
<form class="form-inline">
<div class="form-group">
#Html.LabelFor(model => model.InterestName)
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description)
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
</div>
<input type="submit" value="Add" class="btn btn-success" />
</form>
More information at http://getbootstrap.com/css/#forms-inline
Edit 2
If you want them inline horizontally but in two columns and submit button aligned to the right:
<form>
<div class="col-md-4">
<div class="form-group">
#Html.LabelFor(model => model.InterestName)
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="col-md-4">
<div class="form-group">
#Html.LabelFor(model => model.Description)
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<button type="submit" class="btn btn-default" style="margin-top: 25px;">Add</button>
</div>
</div>
</form>
I have a view that allows user to add new items to a database.
The view looks like this:
#model News.Models.NewsEntry
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>NewsEntry</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.title, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.title)
#Html.ValidationMessageFor(model => model.title)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.body, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.body)
#Html.ValidationMessageFor(model => model.body)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.category, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.category)
#Html.ValidationMessageFor(model => model.category)
</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")
}
Can I write some function (if sentance) inside my view that checks if the title input or the body input are empty and displays a message if they are.
My attempt so far:
EDIT:
In ASP MVC this should be done on the model, decorate the property using Required attribute
[Required(ErrorMessage = "Title is required!")]
public string title { get; set; }
[Required(ErrorMessage = "Body is required !")]
public string body { get; set; }
You will need to add following namespace:
using System.ComponentModel.DataAnnotations;
I created a project for you.
Try it its very simple: