I am unable to determine why my Razor View Page is not able to show Model Errors. I have applied Data Annotation to my model class. I am submitting the form using Ajax Form Upload Plugin (See Reference -> http://malsup.com/jquery/form/).
Model Class
public class Category
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
[FileExtensions(Extensions = ".jpeg,.jpg,.png",ErrorMessage ="Please upload valid image format.")]
public string BannerImage { get; set; }
[FileExtensions(Extensions = ".jpeg,.jpg,.png", ErrorMessage = "Please upload valid image format.")]
public string ThumbImage { get; set; }
private HttpPostedFileBase _bannerImageFile;
[Display(Name = "Banner Image")]
public HttpPostedFileBase BannerImageFile
{
get
{
return _bannerImageFile;
}
set
{
_bannerImageFile = value;
if(value != null)
BannerImage = _bannerImageFile.FileName;
}
}
private HttpPostedFileBase _thumbImageFile;
[Display(Name = "Thumb Image")]
public HttpPostedFileBase ThumbImageFile
{
get
{
return _thumbImageFile;
}
set
{
_thumbImageFile = value;
if (value != null)
ThumbImage = _thumbImageFile.FileName;
}
}
[Display(Name = "Meta Keywwords")]
public string MetaKeywords { get; set; }
[Display(Name = "Meta Description")]
public string MetaDescription { get; set; }
[Display(Name = "Created Date")]
public string CreatedDate { get; set; }
[Display(Name = "Last Updated Date")]
public string LastUpdatedDate { get; set; }
public bool Status { get; set; }
public List<SubCategory> SubCategories { get; set; }
public bool IsSaved(string spNameOrSql, Dictionary<string, object> parameters, QueryType type = QueryType.SQL)
{
try
{
if (type == QueryType.StoredProcedure)
{
var p = new SqlParameter[parameters.Count];
var count = 0;
foreach (var item in parameters)
{
var key = item.Key;
var value = item.Value;
value = String.Join(" ", Convert.ToString(value).Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));
p[count++] = new SqlParameter("#" + key, value);
}
return Convert.ToBoolean(DataFunctions.ExecuteScalar(spNameOrSql, p, type));
}
return Convert.ToBoolean(DataFunctions.ExecuteScalar(spNameOrSql, type));
}
catch (Exception ex)
{
Error.Log(GetType().Name, MethodBase.GetCurrentMethod().ToString(), ex.Message, ex.Source, ex.StackTrace);
return false;
}
}
}
Controller
public ActionResult AddCategory(Category model)
{
if (ModelState.IsValid)
{
var param = model.GetType().GetProperties().ToDictionary(prop => prop.Name,
prop => prop.GetValue(model, null));
param.Remove(Nameof<Category>.Property(e => e.Id));
param.Remove(Nameof<Category>.Property(e => e.BannerImageFile));
param.Remove(Nameof<Category>.Property(e => e.ThumbImageFile));
param.Remove(Nameof<Category>.Property(e => e.CreatedDate));
param.Remove(Nameof<Category>.Property(e => e.LastUpdatedDate));
var result = model.IsSaved(AppConstants.StoredProcedures.CATEGORY_ADD, param, QueryType.StoredProcedure);
if (result)
{
for (int i = 0; i < Request.Files.Count; i++)
{
switch (Request.Files.Keys[i])
{
case "BannerImageFile":
UploadImage(Request.Files[i], AppConstants.FilePath.CATEGORY_BANNER_IMAGE_PATH);
break;
case "ThumbImageFile":
UploadImage(Request.Files[i], AppConstants.FilePath.CATEGORY_THUMB_IMAGE_PATH);
break;
}
}
ModelState.Clear();
}
}
return PartialView("_PartialAddCategory",model);
}
View
#model TristarJewelry.Shared.Models.Category
<script type="text/javascript">
$(document).ready(function () {
var options = {
beforeSubmit: BeginLoader,
success: OnSuccess,
error: OnFailure,
target: '#myForm'
};
$('#myForm').ajaxForm(options);
});
function OnSuccess() {
$("#app_message").removeClass("alert-success alert-danger alert-warning alert-info");
$("#app_message").addClass("alert-success");
$("#app_message").html("Category Succesfully Added !");
$("#app_message").fadeIn(2000).delay(2000).fadeOut(2000);
StopLoader();
}
function OnFailure() {
$("#app_message").html("Oops something went wrong ! Try after sometime. ");
$("#app_message").removeClass("alert-success alert-danger alert-warning alert-info");
$("#app_message").addClass("alert-danger");
$("#app_message").fadeIn(2000).delay(3000).fadeOut(2000);
}
function BeginLoader() {
$('#loader').modal({ toggle: "model", backdrop: 'static', keyboard: false });
}
function StopLoader() {
$('#loader').modal("hide");
}
</script>
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Add Category</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Please fill all the details.
</div>
<div class="panel-body">
<div class="row">
<form id="myForm" action="#Url.Action("AddCategory","Dashboard")" method="POST" enctype = "multipart/form-data">
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-lg-6">
<div class="form-group">
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter Name" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description)
#Html.TextAreaFor(model => model.Description, new { #class = "form-control", #placeholder = "Enter Description", #rows = "3", style = "resize:vertical" })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.ThumbImageFile)
#Html.TextBoxFor(model => model.ThumbImageFile, new { type = "file" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.BannerImageFile)
#Html.TextBoxFor(model => model.BannerImageFile, new { type = "file" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Status)
#Html.CheckBoxFor(model => model.Status)
#Html.ValidationMessageFor(model => model.Status, "", new { #class = "text-danger" })
</div>
<button type="submit" class="btn btn-default">Submit Button</button>
<button id="form_reset" type="reset" class="btn btn-default">Reset Button</button>
</div>
<!-- /.col-lg-6 (nested) -->
<div class="col-lg-6">
<div class="form-group">
#Html.LabelFor(model => model.MetaKeywords)
#Html.EditorFor(model => model.MetaKeywords, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter Meta Keywords" } })
#Html.ValidationMessageFor(model => model.MetaKeywords, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(model => model.MetaDescription)
#Html.TextAreaFor(model => model.MetaDescription, new { #class = "form-control", #placeholder = "Enter Meta Description", #rows = "3", style = "resize:vertical" })
#Html.ValidationMessageFor(model => model.MetaDescription, "", new { #class = "text-danger" })
</div>
</div>
<!-- /.col-lg-6 (nested) -->
</form>
</div>
<!-- /.row (nested) -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
</div>
On Controller ,ModelState.IsValid becomes false if any of the model property doesn't validate but it is not displaying error on view page. Don't know why. can anybody tell me.
Note* : I am not using Ajax.BeginForm here because i can't able to upload files with this approach. So instead i am using jquery form upload puglin.
Any help would be appriciated. If you need to know anything let me know here.
Related
I am trying to upload a photo using MVC but it is returning null, I have already used HttpPostedFileBase, yet I still don't know why I am not getting the file. I saw youtube tutorials where they use HTTPPost in their Controller Action Result, but mine is different and I can't update it. Here is my code:
Controller:
public ActionResult CreateOrUpdateOperator(Operator_Profiles operator_Profiles) {
string fileName = Path.GetFileNameWithoutExtension(operator_Profiles.ImageFile.FileName);
string extension = Path.GetExtension(operator_Profiles.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
operator_Profiles.OperatorPic = "../Content/assets/images/operators/" + fileName;
fileName = Path.Combine(Server.MapPath("../Content/assets/images/operators/"), fileName);
operator_Profiles.ImageFile.SaveAs(fileName);
using (db) {
if (operator_Profiles.OperatorID > 0) {
db.Entry(operator_Profiles).State = System.Data.Entity.EntityState.Modified;
} else {
db.Operator_Profiles.Add(operator_Profiles);
}
db.SaveChanges();
ModelState.Clear();
return Json(true, JsonRequestBehavior.AllowGet);
}
}
Model:
public partial class Operator_Profiles
{
public int OperatorID { get; set; }
[DisplayName("Upload Operator Photo")]
public string OperatorPic { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
public string Lastname { get; set; }
public string Firstname { get; set; }
public string Email { get; set; }
[DisplayName("Phone Number")]
public string PhoneNumber { get; set; }
[DataType(DataType.Date, ErrorMessage = "Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> Birthdate { get; set; }
public string Gender { get; set; }
public string Status { get; set; }
}
View:
<form name="operatorForm" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken();
<div class="modal-header">
<h4 class="modal-title">
<span id="headertitle"></span>
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">×</button>
</div>
<div class="modal-body">
#Html.HiddenFor(c => c.OperatorID)
<div class="form-row mb-3">
<div class="col-6">
#Html.LabelFor(x => x.OperatorPic, htmlAttributes: new { #class = "control-label" })
<input type="file" name="ImageFile" class="form-control-file" />
</div>
</div>
<div class="form-row">
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Lastname, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Lastname, new { htmlAttributes = new { #class = "form-control", required = true } })
#Html.ValidationMessageFor(x => x.Lastname, "Invalid Lastname", new { #class = "invalid-feedback" })
</div>
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Firstname, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Firstname, new { htmlAttributes = new { #class = "form-control", required = true } })
#Html.ValidationMessageFor(x => x.Firstname, "Invalid Firstname", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.Email, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Email, new { htmlAttributes = new { #class = "form-control", type = "email", required = true } })
#Html.ValidationMessageFor(x => x.Email, "Invalid Email", new { #class = "invalid-feedback" })
</div>
<div class="col-md-6 col-sm-12 form-group">
#Html.LabelFor(x => x.PhoneNumber, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.PhoneNumber, new { htmlAttributes = new { #class = "form-control", type = "tel", required = true } })
#Html.ValidationMessageFor(x => x.PhoneNumber, "Invalid Phone Number", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Birthdate, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(x => x.Birthdate, new { htmlAttributes = new { #class = "form-control", type = "date", required = true } })
#Html.ValidationMessageFor(x => x.Birthdate, "Invalid Birthdate", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Gender, htmlAttributes: new { #class = "control-label" })
#{
var genderList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Male", Value = "Male" }, new SelectListItem { Text = "Female", Value = "Female" }, }, "Value", "Text");
}
#Html.DropDownListFor(x => x.Gender, genderList, "Select Gender", new { #class = "form-control", required = true })
#Html.ValidationMessageFor(x => x.Gender, "Please choose a Gender", new { #class = "invalid-feedback" })
</div>
</div>
<div class="form-row">
<div class="col form-group">
#Html.LabelFor(x => x.Status, htmlAttributes: new { #class = "control-label" })
#{
var statusList = new SelectList(new List<SelectListItem> { new SelectListItem { Text = "Clear", Value = "Clear" }, new SelectListItem { Text = "Suspended", Value = "Suspended" }, }, "Value", "Text");
}
#Html.DropDownListFor(x => x.Status, statusList, "Select Status", new { #class = "form-control", required = true })
#Html.ValidationMessageFor(x => x.Status, "Invalid Status", new { #class = "invalid-feedback" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger ml-auto" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-success mr-auto" onclick="SaveOperatorProfile()">Submit</button>
</div>
JS:
function SaveOperatorProfile() {
var modal = $("#operatorModal");
var form = $('form[name = operatorForm]');
form.validate({
errorClass: 'is-invalid',
validClass: 'is-valid',
highlight: function (element, errorClass, validClass) {
$(element).removeClass(validClass).addClass(errorClass);
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
},
errorPlacement: function () {
// Done in highlight/unhighlight
},
submitHandler: function (form) {
alert('Operator Profile has been successfuly saved.');
}
});
if (!form.valid()) {
return;
} else {
var data = form.serialize();
$.post("/Admin/CreateOrUpdateOperator", data, function (res) {
if (res) {
modal.modal('hide');
OprTable.ajax.reload();
}
})
}
}
You aren't getting anything in your ActionResult from the form because you are not asking for it. The "name" of your image object is "ImageFile" as per your HTML input. This needs to match up in your POST method. For example,
[HttpPost]
public ActionResult CreateOrUpdateOperator(HttpPostedFileBase ImageFile, FormCollection col) {
Operater_Profiles operater_Profiles = new Operator_Profiles();
string myString1 = col["SomeName1"].ToString();
string myString2 = col["SomeName2"].ToString();
}
The name of the parameter needs to match with the name from the HTML.
EDIT:
In addition to your controller, you need to actually mark it as a POST method, it's highly recommended. To do this, just add the attribute [HttpPost] before the method declaration.
You are using jquery/js to also post via an ajax method. This is not really how you should be doing this since you aren't doing any dynamic page loading here. You should be making full use of the MVC architecture - why else are you using ASP.NET's MVC?
Instead of using the jquery, you can instead change your input to this:
#using (Html.BeginForm("ACTIONNAME", "CONTROLLERNAME", null, FormMethod.Post, new { enctype = "multipart/form-data" })) {
<input type="file" name="ImageFile" class="form-control-file" />
#Html.LabelFor(x => x.Lastname, htmlAttributes: new { #class = "control-label", #name = "SomeName1" })
#Html.LabelFor(x => x.Firstname, htmlAttributes: new { #class = "control-label", #name = "SomeName2" })
#Html.LabelFor(x => x.Email, htmlAttributes: new { #class = "control-label", #name = "SomeName3" })
}
As you can see, I added names to your data you are posting. These names can be grabbed via FormCollection in the controller.
So after some modifications, It worked! I used FormData instead of serializing my form.
My form now calls the ajax post function if submitted using this modification:
<form name="operatorForm" method="post" enctype="multipart/form-data" onsubmit="SaveOperatorProfile(this)">
Then this is my js code
function SaveOperatorProfile(formData) {
var modal = $("#operatorModal");
var form = $('form[name = operatorForm]');
form.validate({
errorClass: 'is-invalid',
validClass: 'is-valid',
highlight: function (element, errorClass, validClass) {
$(element).removeClass(validClass).addClass(errorClass);
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
},
errorPlacement: function () {
// Done in highlight/unhighlight
},
submitHandler: function (form) {
alert('Operator Profile has been successfuly saved.');
}
});
if (!form.valid()) {
return;
} else {
var ajaxConfig = {
type: "post",
url: "/Admin/CreateOrUpdateOperator",
data: new FormData(formData),
success: function (res) {
if (res) {
modal.modal('hide');
OprTable.ajax.reload();
}
}
}
if ($(formData).attr('enctype') == "multipart/form-data") {
ajaxConfig["contentType"] = false;
ajaxConfig["processData"] = false;
}
$.ajax(ajaxConfig);
return false;
}
}
I am developing an administration page in ASP.NET MVC.
But I have a problem when I edit the film.
When I edit a movie, the sessions appear on my page. And I can remove them.
If I click on edit without removing anything, I get the values well. But when I remove the first session, my array is null.
When I remove the second session, the array comes with this value.
Does anyone know why?
My code:
Edit.cshtml
#using (Html.BeginForm("Edit", "Trans", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID, htmlAttributes: new { #id = "id" })
#Html.HiddenFor(model => model.Selected, htmlAttributes: new { })
<div class="form-group">
#Html.LabelFor(model => model.Titulo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Titulo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Titulo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Descricao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Descricao, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Descricao, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Selected, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Selected, new SelectList(Model.tipos, "ID", "Tipo", Model.Selected), htmlAttributes: new { #id = "ddldropdown", #class = "form-control", #disabled = "disabled" })
#Html.ValidationMessageFor(model => model.Selected, "", new { #class = "text-danger" })
</div>
</div>
<div id="partialDiv">
</div>
<div id="CinemaDiv" style="display:none">
#Html.Partial("Edit_Cinema", Model)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Edit" id="Save" class="btn btn-default" onclick="Fillarrays()" />
</div>
</div>
</div>
}
#section Scripts {
<script type="text/javascript">
//Script para adicionar os Views da pasta Outros no div "partialDiv"
$(document).ready(function () {
var txt = $("#ddldropdown option:selected").text();
var id = $("#id").val();
$.ajax({
type: 'get',
url: '/Outros/Edit_Cinema' + '/' + id,
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
</script>
#*< !--Script Cinema (Partial View)-- >*#
<script type="text/javascript">
//funcao para remover o campo sessao
function rmSessao(id) {
$('#sessao_' + id + '').remove();
}
</script>
<script type="text/javascript">
$('#Save').click(function () {
var form = $("#formH");
var url = form.attr("action");
var formData = form.serialize();
$.post(url, formData, function (data) {
$("#msg").html(data);
//Script para adicionar os campos das partial views
var txt = $("#ddldropdown option:selected").text();
var frm = $("form");
var data = new FormData($("form")[0]);
$.ajax({
url: '/Outros/Edit_Cinema' + '/' + id,
type: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
</script>
}
Edit_Cinema.cshtml
#model ProjetoFinal.Models.ItemViewModel
<div class="form-horizontal">
#*#Html.ValidationSummary(true, "", new { #class = "text-danger" })*#
#Html.HiddenFor(model => model.Cinema.ID)
#Html.LabelFor(model => model.Cinema.Sessoes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="form-group">
#for (int i = 0; i < Model.Cinema_array_Sessoes_Edit.Count; i++)
{
<div class="col-md-10" style="margin-left:195px;margin-bottom:10px" id="sessao_#i">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => Model.Cinema_array_Sessoes_Edit[i], new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => Model.Cinema_array_Sessoes_Edit[i], "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="-" onclick="rmSessao(#i)" />
</span>
</div>
</div>
}
</div>
</div>
Models
ItemViewModel
public class ItemViewModel
{
public int ID { get; set; }
[Display(Name = "Tipo", ResourceType = typeof(Resource))]
//public List<Tipo> tipos { get { return Services.GetTypes(); } } get all types
public List<Tipo> tipos { get; set; }
[Display(Name = "Tipo", ResourceType = typeof(Resource))]
public int? Selected { get; set; }
#region Cinema
public Cinema Cinema { get; set; }
public string[] Cinema_array_sessoes { get; set; }
[Display(Name = "Cinema_array_Sessoes_Edit")]
public List<DateTime?> Cinema_array_Sessoes_Edit { get; set; }
public string[] array_Sessoes_Edit { get; set; }
public string[] array_sessoes { get; set; }
#endregion
public ItemViewModel()
{
tipos = new List<Tipo>();
Cinema = new Cinema();
#region For the cinema
Cinema_array_Sessoes_Edit = new List<DateTime?>();
#endregion
//vai buscar os tipos para aparecer no dropdown
tipos = Services.GetTypes();
}
public class TransmontanosDBContext : DbContext
{
public DbSet<Item> Transmontanos { get; set; }
}
}
TransController.cs
public class TransController : Controller
{
[HttpPost]
public ActionResult Edit(ItemViewModel item, string Latitude, string Longitude)
{
Item obj = new Item();
if (item.Titulo != null)
{
obj.ID=item.ID;
obj.Titulo = item.Titulo;
obj.Descricao = item.Descricao;
obj.Localidade = item.Localidade;
obj.Endereco = item.Endereco;
obj.Latitude =Latitude;
obj.Longitude = Longitude;
obj.Selected = item.Selected;
if (item.Main_Image != null)
{
if (item.Main_Image.ContentLength != 0)
{
//Adiciona a imagem principal à pasta Images
var pathMain = Path.Combine(Server.MapPath("~/Images/"), obj.ID + ".jpg");
item.Main_Image.SaveAs(pathMain);
//Adiciona a imagem principal no ultimo item inserido
Services.AddImage_ToItem(obj.ID);
}
}
Services.EditObject(obj);
return RedirectToAction("Index", "Trans");
}
return View(item);
}
}
OutrosController.cs
public class OutrosController : Controller
{
[HttpPost]
public ActionResult Edit_Cinema(ItemViewModel item)
{
Cinema cinema = new Cinema();
cinema = item.Cinema;
}
}
Results:
Sessions in my movie when I click edit
When I do not remove any of the fields
When I remove the second field
When I remove the first field (Problem)
I would change your view code to this:
#for (int i = 0; i < Model.Cinema_array_Sessoes_Edit.Count; i++)
{
<div class="col-md-10" style="margin-left:195px;margin-bottom:10px" id="sessao_#i">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => Model.Cinema_array_Sessoes_Edit[i], new { htmlAttributes = new { #class = "form-control" #id="id_#i" } })
#Html.ValidationMessageFor(model => Model.Cinema_array_Sessoes_Edit[i], "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="-" onclick="rmSessao(#i)" />
</span>
</div>
</div>
}
Change your delete javascript function:
/funcao para remover o campo sessao
function rmSessao(id) {
$('#id_' + id + '').val(null); //assingn null to date value
$('#sessao_' + id + '').addClass("d-none"); // just hide it
}
And change your controller action:
public ActionResult Edit_Cinema(ItemViewModel item)
{
item.Cinema_array_Sessoes_Edit.RemoveAll(x => x== null);
.... //your code
// you don't need it at all - Cinema cinema = new Cinema();
var cinema = item.Cinema;
}
So I have some custom validation implemented to prevent similar records being entered into the db. The only problem I have is that it is not presenting the user an error/validation message but rather an error page.
Where am I going wrong? Or how do I correctly implement this?
Validation:
public class ValidSimilarRequests : ValidationAttribute
{
private LotusWorksEntities db = new LotusWorksEntities();
protected override ValidationResult
IsValid(object value, ValidationContext validationContext)
{
var model = (Models.HolidayRequestForm)validationContext.ObjectInstance;
int empID = Convert.ToInt32(model.EmployeeID);
DateTime _startdate = Convert.ToDateTime(model.StartDate);
DateTime _finishdate = Convert.ToDateTime(model.FinishDate);
var holidayexist = db.HolidayRequestForms.Any( x => x.EmployeeID==empID && x.StartDate <= _startdate && x.FinishDate >= _finishdate );
if (holidayexist)
{
return new ValidationResult
("A holiday Request for this date range has already been requested");
}
else
{
return ValidationResult.Success;
}
}
}
Model:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
[ValidSimilarRequests(ErrorMessage =
"A holiday Request for this date range has already been requested")]
public int EmployeeID { get; set; }
[ValidSameWeek(ErrorMessage =
"Holiday Request Must be made on a weekly Period")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime StartDate { get; set; }
[ValidStartFinishDate(ErrorMessage =
"Finish Date can not be Greater than Start date.")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime FinishDate { get; set; }
[Range(0.0001, int.MaxValue, ErrorMessage = "Hours Requested must be greater than zero. ")]
public decimal HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public int DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
public Nullable<bool> Approved { get; set; }
public string SubmittedBy { get; set; }
public string ApprovedBy { get; set; }
public Nullable<int> WorkWeek { get; set; }
public Nullable<int> MonthOfHoliday { get; set; }
public virtual Employee Employee { get; set; }
}
The Error Page shows:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Controller:
[Authorize(Roles = "Admin,User,SuperUser")]
public ActionResult Create()
{
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName");
return View();
string name = Session["Name"].ToString();
var EmployeeIDCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID);
}
// POST: HolidayRequestForms/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "RequestID,StartDate,FinishDate,HoursTaken,Comments,YearCreated,MonthCreated,DayCreated,YearOfHoliday,Approved,SubmittedBy,ApprovedBy")] HolidayRequestForm holidayRequestForm)
{
if (ModelState.IsValid)
{
if (Session["Name"] == null)
{
TempData["msg"] = "Your Session Expired - Please Login";
return RedirectToAction("Login", "Account");
}
string name = Session["Name"].ToString();
var employeeID = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID).FirstOrDefault();
holidayRequestForm.EmployeeID = employeeID;
var submittedby = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.Email).FirstOrDefault();
holidayRequestForm.SubmittedBy = submittedby;
//Saves changes and begins Email Actions
db.HolidayRequestForms.Add(holidayRequestForm);
db.SaveChanges();
SendMailToAreaManager();
SendMailToManager();
SendMailToAdmin();
return RedirectToAction("Index", "Calendar");
}
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName", holidayRequestForm.EmployeeID);
return View(holidayRequestForm);
}
VIEW:
#model HolidayTracker.Models.HolidayRequestForm
<div>
<div class="col-md-12">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h2 align="center">Holiday Request Form</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StartDate, "Start Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StartDate, "Start Date", new { htmlAttributes = new { #class = "form-control", #style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.StartDate, "", new { #class = "text-warning" })
<p id="warning" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FinishDate, "Finish Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FinishDate, new { htmlAttributes = new { #class = "form-control",#style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.FinishDate, "", new { #class = "text-danger" })
<p id="warningFD" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HoursTaken, "Hours Requested", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HoursTaken, new { htmlAttributes = new { #class = "form-control", #style = "width:400px" } })
#Html.ValidationMessageFor(model => model.HoursTaken, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#Html.TextAreaFor(
model => model.Comments,
new { placeholder = "Enter Dates and how many Hours per Date Here. ", style = "width: 400px; height: 200px;" })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-warning" />
</div>
</div>
}
</div>
</div>
</div>
I have implemented Required validation for my MVC view. The text controls show the validation message but the kendo combobox doesnt. I'm doing an ajax postback.
Any reason why the comboxbox doest show the message? The work Type combo is mandatory, but its not showing the validation message.
View
#using (Ajax.BeginForm("ActivityWorkLog_Create", "Activity", new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "OnWorklogStatusSuccess",
OnFailure = "OnWorklogStatusFailure"
}, new { id = "workLogForm" }))
{
<div class="k-popup-edit-form k-window-content k-content" data-role="window">
<div class="k-edit-form-container">
#Html.HiddenFor(x => x.RequestID, new { data_bind = "value: requestId" })
#Html.HiddenFor(x => x.ActivityID, new { data_bind = "value: activityId" })
#Html.HiddenFor(x => x.CountryCode, new { data_bind = "value: countryCode" })
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogAppliesToName)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.WorkLogAppliesToName)
.Name("WorkLogAppliesToID")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px", #readonly = "readonly" })
.Placeholder("Select...")
.DataTextField("WorkLogAppliesToName")
.DataValueField("WorkLogAppliesToID")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetWorkLogAppliesTo", "WorkLog", new { id = 0 }).Type(HttpVerbs.Post)
)
)
)
#Html.ValidationMessageFor(model => model.WorkLogAppliesToName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.ActivitySLA)
</div>
<div class="editor-field">
#*#Html.EditorFor(model => model.ActivitySLA)*#
#Html.TextBoxFor(model => model.ActivitySLA, new { id = "ActivityDesc", #readonly = "readonly", Class = "textBoxFor" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.ActivityID)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.ActivityID)
.Name("Activity")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px", #readonly = "readonly" })
.Placeholder("Select...")
.DataTextField("Description")
.DataValueField("ActivityID")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetActivity", "WorkLog").Data("additionalActivityInfo").Type(HttpVerbs.Post)
)//.ServerFiltering(true)
)//.CascadeFrom("ServiceID").Filter("contains")
)
#Html.ValidationMessageFor(model => model.ServiceID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogType)
</div>
<div class="editor-field">
#(Html.Kendo().ComboBoxFor(model => model.WorkLogTypeCode)
.Name("WorkLogTypeCode1")
.Filter("contains")
.HtmlAttributes(new { style = "width:300px"})
.Placeholder("Select...")
.DataTextField("WorkLogType")
.DataValueField("WorkLogTypeCode")
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetWorkLogType", "WorkLog").Data("additionalWLTInfo").Type(HttpVerbs.Post))
)
)
#Html.ValidationMessageFor(model => model.WorkLogTypeCode, "Please select a worklog type", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogSubject)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.WorkLogSubject)
#Html.ValidationMessageFor(model => model.WorkLogSubject, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.WorkLogDetails)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.WorkLogDetails, new { htmlAttributes = new { #class = "form-control", cols = "50" } })
#Html.ValidationMessageFor(model => model.WorkLogDetails, "", new { #class = "text-danger" })
</div>
</div>
<div class="worklogStatusButtonAlign">
<button id="btnWorkLogSave" type="submit" class="k-button k-button-icontext k-primary k-grid-update">Save</button>
<button id="btnClose" type="button" class="k-button k-button-icontext k-grid-cancel">Cancel</button>
</div>
<div id="worklogStatusMessage"> </div>
</div>
</div>
}
Javacript
<script>
$(document).ready(function () {
var form = $("#workLogForm")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
View model
public class ActivityWorkLogViewModel
{
[ScaffoldColumn(false)]
[Display(Name = "WorkLogID", ResourceType = typeof(Resources.Resource))]
public int WorkLogID { get; set; }
[Required(ErrorMessage = "WorkLogType is required")]
[Display(Name = "WorkLogTypeCode", ResourceType = typeof(Resources.Resource))]
public string WorkLogTypeCode { get; set; }
[Display(Name = "WorkLogType", ResourceType = typeof(Resources.Resource))]
public string WorkLogType { get; set; }
[Required]
[Display(Name = "WorkLogAppliesToID", ResourceType = typeof(Resources.Resource))]
public int WorkLogAppliesToID { get; set; }
[Display(Name = "WorkLogAppliesToName", ResourceType = typeof(Resources.Resource))]
public string WorkLogAppliesToName { get; set; }
[Required]
[Display(Name = "RequestID", ResourceType = typeof(Resources.Resource))]
public int RequestID { get; set; }
[Display(Name = "ServiceID", ResourceType = typeof(Resources.Resource))]
public Nullable<int> ServiceID { get; set; }
[Display(Name = "ActivityID", ResourceType = typeof(Resources.Resource))]
public Nullable<int> ActivityID { get; set; }
[Required(ErrorMessage = "Subject is required")]
[Display(Name = "WorkLogSubject", ResourceType = typeof(Resources.Resource))]
public string WorkLogSubject { get; set; }
[Required(ErrorMessage = "Details is required")]
[Display(Name = "WorkLogDetails", ResourceType = typeof(Resources.Resource))]
public string WorkLogDetails { get; set; }
[Display(Name = "EmailTo", ResourceType = typeof(Resources.Resource))]
public string EmailTo { get; set; }
[Display(Name = "IsActive", ResourceType = typeof(Resources.Resource))]
public bool IsActive { get; set; }
[Display(Name = "CountryCode", ResourceType = typeof(Resources.Resource))]
public string CountryCode { get; set; }
[Display(Name = "ActivitySLA", ResourceType = typeof(Resources.Resource))]
public string ActivitySLA { get; set; }
}
Try to add this:
<script>
$(function () {
$("form").kendoValidator();
});
</script>
and/or:
<script>
$.validator.setDefaults({
ignore: ""
});
</script>
You can set validation rules to force the a item selection:
$("form").kendoValidator({
rules: {
invalidSelection: function (input) {
if (input.is("[name=COMBO_NAME]")) {
if (input.val() != "" && $("#TCOMBO_NAME").data("kendoComboBox").selectedIndex == -1) {
return false;
}
}
return true;
}
}
});
This way it travel all the fields of the form, being able to establish rules for each field. Regards.
I am working on small ticket system for operations maintenance services comp.
Customer open a ticket and gives general information like location,
category description etc.
After technician fix the problem he must give sum details of the
problem from predefined set, use later for statistical reports.
My problem the repair method unable to post updated values to database plus nothing added to Defects_List table.
Note: I used this tutorial as guide
Models:
public partial class Tickets
{
public Tickets()
{
this.DefectsList = new HashSet<Defects_List>();
}
[Key]
[Display(Name = "Ticket Id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Ticket_Id { get; set; }
[Display(Name = "Project")]
public int Project_Id { get; set; }
[Display(Name = "Issue Date")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime Issue_Date { get; set; }
[Display(Name = "Category")]
[DisplayFormat(NullDisplayText = "[Not set]")]
public int Category_Id { get; set; }
//Other Properties Removed for clarity
public virtual Business_Category businessCategories { get; set; }
public virtual ICollection<Defects_List> DefectsList { get; set; }
}
public partial class Business_Category
{
public Business_Categories()
{
this.Tickets = new HashSet<Tickets>();
this.Malfunctions = new HashSet<Malfunctions>();
}
[Key]
[Display(Name="Category Id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Category_Id { get; set; }
[Display(Name = "Name (eng)")]
[StringLength(60, ErrorMessage = "Name cannot be longer than 60 characters.")]
public string Category_Name { get; set; }
public virtual ICollection<Tickets> Tickets { get; set; }
public virtual ICollection<Manufacturers> Manufacturers { get; set; }
public virtual ICollection<Malfunctions> Malfunctions { get; set; }
}
public partial class Defects_List
{
[Key, Column(Order = 0)]
[Display(Name = "Ticket Id")]
public int Ticket_Id { get; set; }
[Key, Column(Order = 1)]
[Display(Name = "Malfunction Id")]
public int Malfunction_Id { get; set; }
[StringLength(125, ErrorMessage = "Other cannot be longer than 125 characters.")]
public string Other { get; set; }
public virtual ICollection<Tickets> Tickets { get; set; }
public virtual Malfunctions Malfunctions { get; set; }
}
Controller:
// GET: /Tickets/Edit/5
public ActionResult Repair(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var tickets = db.nt_Tickets
.Include(t => t.DefectsList).Where(t => t.Ticket_Id == id)
.Single();
if (tickets == null)
{
return HttpNotFound();
}
PopulateSelectedDefects(tickets);
//Other codes Removed for clarity
return View(tickets);
}
private void PopulateSelectedDefects(nt_Tickets Tickets)
{
int categoryId;
if (Tickets.Category_Id == 2)
categoryId = 1;
else categoryId = Tickets.Category_Id;
var allDefects = (from m in db.sys_Malfunctions
where m.Category_Id == categoryId
select m).ToList();
var ticketDefects = new HashSet<int>(Tickets.DefectsList.Select(t => t.Malfunction_Id));
var viewModel = new List<TicketDefectsViewModel>();
foreach (var defect in allDefects)
{
viewModel.Add(new TicketDefectsViewModel
{
Malfunction_Id = defect.Malfunction_Id,
Malfunction_Name_e = defect.Malfunction_Name_e,
IsSelected = ticketDefects.Contains(defect.Malfunction_Id)
});
}
ViewBag.Defects = viewModel;
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Repair(int? id, string[] selectedDefects)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var ticketToUpdate = db.nt_Tickets
.Include(i => i.DefectsList)
.Where(i => i.Ticket_Id == id)
.Single();
if (TryUpdateModel(ticketToUpdate, "",
new string[] { Ticket_Id,Project_Id,Category_Id,Subject,Workshop_Id,Requested_By,Requestor_Mobile, Requestor_eMail,Location_Id,Ticket_Status,Periority_Id,Assigned_To,Description,Issue_Date,Created_By,Created_Date,Updated_By,Updated_Date" }))
{
ticketToUpdate.Updated_By = User.Identity.Name;
ticketToUpdate.Updated_Date = DateTime.UtcNow;
db.Entry(ticketToUpdate).State = EntityState.Modified;
SetTicketDefects(selectedDefects, ticketToUpdate);
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
if (!string.IsNullOrEmpty(message))
ViewBag.errorMessage = message;
}
return View("Error");
}
throw raise;
}
}
PopulateSelectedDefects(ticketToUpdate);
return View("Index");
}
private void SetTicketDefects(string[] selectedDefects, Tickets ticketToUpdate)
{
if (selectedDefects == null)
{
ticketToUpdate.DefectsList = new List<Defects_List>();
return;
}
var selectedDefectsHS = new HashSet<string>(selectedDefects);
var tcketDefects = new HashSet<int>
(ticketToUpdate.DefectsList.Select(c => c.Ticket_Id));
foreach (var defect in db.DefectsLists)
{
if (selectedDefectsHS.Contains(defect.Malfunction_Id.ToString()))
{
if (!tcketDefects.Contains(defect.Malfunction_Id))
{
ticketToUpdate.DefectsList.Add(defect);
}
}
else
{
if (tcketDefects.Contains(defect.Malfunction_Id))
{
ticketToUpdate.DefectsList.Remove(defect);
}
}
}
}
db.DefectsLists here [foreach (var defect in db.DefectsLists)] always empty.
Repair View:
#using (Html.BeginForm("Repair", "Tickets", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
#*#using (Html.BeginForm())*#
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Ticket_Id)
#Html.HiddenFor(model => model.Issue_Date)
#Html.HiddenFor(model => model.Created_By)
#Html.HiddenFor(model => model.Project_Id)
#Html.HiddenFor(model => model.Created_Date)
<div class="form-group">
#Html.Label("Ticket_Id", new { #class = "control-label col-md-2" })
<div class="col-md-1 " style="margin-top:7px">
#Html.DisplayFor(model => model.Ticket_Id)
</div>
#Html.LabelFor(model => model.Issue_Date, new { #class = "control-label col-md-2" })
<div class="col-md-2" style="margin-top:7px">
#Html.DisplayFor(model => model.Issue_Date, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Category_Id, new { #class = "control-label col-md-2" })
<div class="col-md-3" style="margin-top:7px">
#Html.DropDownList("Category_Id", null, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Subject, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Subject, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Description, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Requested_By, new { #class = "control-label col-md-2" })
<div class="col-md-5" style="margin-top:7px">
#Html.DisplayFor(model => model.Requested_By, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Requestor_Mobile, new { #class = "control-label col-md-2" })
<div class="col-md-3" style="margin-top:7px">
#Html.DisplayFor(model => model.Requestor_Mobile, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Requestor_eMail, new { #class = "control-label col-md-2" })
<div class="col-md-10" style="margin-top:7px">
#Html.DisplayFor(model => model.Requestor_eMail, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Ticket_Status, new { #class = "control-label col-md-2" })
<div class="col-md-4" style="margin-top:7px">
#Html.EnumDropDownListFor(model => model.Ticket_Status, new { #class = "form-control" })
</div>
#Html.LabelFor(model => model.Periority_Id, new { #class = "control-label col-md-2" })
<div class="col-md-4" style="margin-top:7px">
#Html.EnumDropDownListFor(model => model.Periority_Id, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Location_Id, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.DropDownList("Location_Id", null, new { #class = "form-control", #disabled = "disabled" })
#Html.ValidationMessageFor(model => model.Location_Id)
</div>
#Html.LabelFor(model => model.Assigned_To, new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.DropDownList("Assigned_To", null, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Defects")
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<table class="table table-hover">
<tr>
#{
int cnt = 0;
List<MaintCare.ViewModels.TicketDefectsViewModel> defects = ViewBag.Defects;
foreach (var defect in defects)
{
if (cnt++ % 3 == 0)
{
#:</tr><tr>
}
#:<td>
<input type="checkbox"
name="selectedDefects"
value="#defect.Malfunction_Id"
#(Html.Raw(defect.IsSelected ? "checked=\"checked\"" : "")) />
#defect.Malfunction_Name_e
#:</td>
}
#:</tr>
}
</table>
</div>
</div>
<br />
<div class="form-group">
<div class="col-md-2">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>