MVC3: How do I validate a drop down list? - asp.net-mvc-3

In MVC2 the validation I use for a drop down list works;
<tr>
<td align="right">
<%: Html.LabelFor(model => model.contract.ContractTypeId)%><span class="error">*</span>
</td>
<td>
<%: Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->")%>
<%: Html.ValidationMessageFor(model => model.contract.ContractTypeId)%>
</td>
</tr>
and with data annotation;
[DisplayName("Contract Prefix")]
[UIHint("DropDownList")]
[Required(ErrorMessage = "You must select a Contract Prefix")]
public int ContractTypeId { get; set; }
If I try this in MVC3, it no longer works;
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractTypeId)<span class="error">*</span>
</td>
<td>
#Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->")
#Html.ValidationMessageFor(model => model.contract.ContractTypeId)
</td>
</tr>
data annotation;
[DisplayName("Contract Prefix")]
[UIHint("DropDownList")]
[Required(ErrorMessage = "You must select a Contract Prefix")]
public int ContractTypeId { get; set; }
What am I doing wrong?
EDIT
Actually what is happening is that when I click submit, the other fields are flagging up as invalid. When I correct them and click submit, then the drop downs flag up as invalid. So it kind of works, but should work all at the same time, rather than in this sequence.
My controller is;
#region CREATE
/********
* CREATE
***** */
[Authorize(Roles = "Inputter,Administrator")]
public ViewResult Create()
{
return View(new ContractViewModel());
}
//
// POST: /Contract/Create
[Authorize(Roles = "Inputter,Administrator")]
[HttpPost]
public ActionResult Create(ContractViewModel contractViewModel)
{
if (ModelState.IsValid)
{
CapitaliseNames(ref contractViewModel);
int contractId = contractViewModel.contract.Add();
// Store the Addresses for Client and Contract Administrator on the database,
// and store the Ids of the new addresses on the Contract object.
contractViewModel.clientContact.ContractId = contractId;
contractViewModel.contractAdministratorContact.ContractId = contractId;
int clientContactId = contractViewModel.clientContact.Add();
int contractAdministratorContactId
= contractViewModel.contractAdministratorContact.Add();
contractViewModel.contract.Update(clientContactId, contractAdministratorContactId);
return RedirectToAction("List");
}
return View(new ContractViewModel());
}
private static void CapitaliseNames(ref ContractViewModel contractViewModel)
{
contractViewModel.clientContact.ContactName = contractViewModel.clientContact.ContactName.UppercaseFirst();
contractViewModel.clientContact.NameOfContact = contractViewModel.clientContact.NameOfContact.UppercaseFirst();
contractViewModel.contractAdministratorContact.ContactName = contractViewModel.contractAdministratorContact.ContactName.UppercaseFirst();
contractViewModel.contractAdministratorContact.NameOfContact = contractViewModel.contractAdministratorContact.NameOfContact.UppercaseFirst();
}
#endregion
My View is;
#model HITOC.Models.ContractViewModel
#{
ViewBag.Title = "Create";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('#contract_ContractNo_Letter').setMask({ mask: 'a' });
$('#contract_ContractNo_Number').setMask({ mask: '999', type: 'reverse' });
$('#contract_ContractPeriodInWeeks').setMask({ mask: '999', type: 'reverse' });
$('#contract_ContractValue').setMask({ mask: '99.999999999999', type: 'reverse', defaultValue: '000' });
});
</script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<h1>CREATE an Instruction to Open File Form</h1>
<hr />
<p>DIRECTOR OR HEAD OF DIVISION <b>ONLY</b> TO INSTRUCT</p>
<fieldset>
<legend>Enter the contract details here:</legend>
<p>Where you see <span class="error">*</span> you must enter data.</p>
<table>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.SignOffDate)<span class="error">*</span>
</td>
<td>
#Html.EditorFor(model => model.contract.SignOffDate)
#Html.ValidationMessageFor(model => model.contract.SignOffDate)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Contract Number</th>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractTypeId)<span class="error">*</span>
</td>
<td>
#Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->")
#Html.ValidationMessageFor(model => model.contract.ContractTypeId)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractNo_Letter)<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractNo_Letter,
new { autocomplete = "off", maxlength = "1", style = "width:15px;text-transform: uppercase;" })
#Html.ValidationMessageFor(model => model.contract.ContractNo_Letter)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractNo_Number)<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractNo_Number,
new { autocomplete = "off", maxlength = "3", style = "width:30px;" })
#Html.ValidationMessageFor(model => model.contract.ContractNo_Number)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractNo_Suffix)
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractNo_Suffix,
new { maxlength = "2", style = "width:30px;text-transform: uppercase;" })
</td>
</tr>
<tr>
<th colspan="2">-- Enter Estimate and Order Details</th>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.EstimateNumber)<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contract.EstimateNumber,
new { autocomplete = "off", style = "text-transform: uppercase;" })
#Html.ValidationMessageFor(model => model.contract.EstimateNumber)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ClientOrderNumber)
</td>
<td>
#Html.EditorFor(model => model.contract.ClientOrderNumber)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.InstructionWithoutClientOrder)<br />
(Only if no Client Order Number)
</td>
<td>
#Html.TextAreaFor(model => model.contract.InstructionWithoutClientOrder,
new { maxlength = "255", style = "width:200px;height:100px;"})
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.GivenDate)<span class="error">*</span>
</td>
<td>
#Html.EditorFor(model => model.contract.GivenDate)
#Html.ValidationMessageFor(model => model.contract.GivenDate)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Client Details</th>
</tr>
<tr>
<td align="right">
Client Organisation Name<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.clientContact.ContactName, new { autocomplete = "off", style = "text-transform: capitalize;" })
#Html.ValidationMessageFor(model => model.clientContact.ContactName)
</td>
</tr>
<tr>
<td align="right">
Client Address<span class="error">*</span>
</td>
<td>
#Html.EditorFor(model => model.clientContact.AddressLine1)
#Html.ValidationMessageFor(model => model.clientContact.AddressLine1)
</td>
</tr>
<tr>
<td></td>
<td>
#Html.EditorFor(model => model.clientContact.AddressLine2)
</td>
</tr>
<tr>
<td align="right">
Post code<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.clientContact.PostCode,
new { autocomplete = "off", style = "text-transform: uppercase;" })
#Html.ValidationMessageFor(model => model.clientContact.PostCode)
</td>
</tr>
<tr>
<td align="right">
Name of contact
</td>
<td>
#Html.TextBoxFor(model => model.clientContact.NameOfContact, new { autocomplete = "off", style = "text-transform: capitalize;" })
#Html.ValidationMessageFor(model => model.clientContact.NameOfContact)
</td>
</tr>
<tr>
<td align="right">
Tel No
</td>
<td>
#Html.EditorFor(model => model.clientContact.Phone)
#Html.ValidationMessageFor(model => model.clientContact.Phone)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Contract Administrator Details</th>
</tr>
<tr>
<td></td>
<td><input id="chkCopyContact" type="checkbox" name="chkCopyContact" /> Click here to copy across the client contact details </td>
</tr>
<tr>
<td align="right">
Name<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contractAdministratorContact.ContactName, new { autocomplete = "off", style = "text-transform: capitalize;" })
#Html.ValidationMessageFor(model => model.contractAdministratorContact.ContactName)
</td>
</tr>
<tr>
<td align="right">
Address<span class="error">*</span>
</td>
<td>
#Html.EditorFor(model => model.contractAdministratorContact.AddressLine1)
#Html.ValidationMessageFor(model => model.contractAdministratorContact.AddressLine1)
</td>
</tr>
<tr>
<td></td>
<td>
#Html.EditorFor(model => model.contractAdministratorContact.AddressLine2)
</td>
</tr>
<tr>
<td align="right">
Post code<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contractAdministratorContact.PostCode,
new { autocomplete = "off", style = "text-transform: uppercase;" })
#Html.ValidationMessageFor(model => model.contractAdministratorContact.PostCode)
</td>
</tr>
<tr>
<td align="right">
Name of contact
</td>
<td>
#Html.TextBoxFor(model => model.contractAdministratorContact.NameOfContact,
new { autocomplete = "off", style = "text-transform: capitalize;" })
#Html.ValidationMessageFor(model => model.contractAdministratorContact.NameOfContact)
</td>
</tr>
<tr>
<td align="right">
Tel No
</td>
<td>
#Html.EditorFor(model => model.contractAdministratorContact.Phone)
#Html.ValidationMessageFor(model => model.contractAdministratorContact.Phone)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Contract Title/Address</th>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractTitle)<span class="error">*</span>
</td>
<td>
#Html.EditorFor(model => model.contract.ContractTitle)
#Html.ValidationMessageFor(model => model.contract.ContractTitle)
</td>
</tr>
<tr>
<td></td>
<td>
#Html.EditorFor(model => model.contract.ContractAddressLine1)
</td>
</tr>
<tr>
<td></td>
<td>
#Html.EditorFor(model => model.contract.ContractAddressLine2)
</td>
</tr>
<tr>
<td align="right">
Post code<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractPostCode,
new { autocomplete = "off", style = "text-transform: uppercase;" })
#Html.ValidationMessageFor(model => model.contract.ContractPostCode)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Work Description</th>
</tr>
<tr>
<td align="right"><span class="error">*</span></td>
<td >
#Html.TextAreaFor(model => model.contract.WorkDescription,
new { maxlength = "255", style = "width:200px;height:100px;" })
#Html.ValidationMessageFor(model => model.contract.WorkDescription)
</td>
</tr>
<tr>
<th colspan="2">-- Enter Contract Details</th>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.StartDate)
</td>
<td>
#Html.EditorFor(model => model.contract.StartDate)
#Html.ValidationMessageFor(model => model.contract.StartDate)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractPeriodInWeeks)<span class="error">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractPeriodInWeeks, new { style = "width:30px" })
#Html.ValidationMessageFor(model => model.contract.ContractPeriodInWeeks)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.OperationsManagerUserId)<span class="error">*</span>
</td>
<td>
#Html.DropDownListFor(model => model.contract.OperationsManagerUserId, Model.operationManagerSelectList, "<--Select-->")
#Html.ValidationMessageFor(model => model.contract.OperationsManagerUserId)
</td>
</tr>
<tr>
<td align="right">
#Html.LabelFor(model => model.contract.ContractValue)
</td>
<td>
#Html.TextBoxFor(model => model.contract.ContractValue, new {style = "width:120px" })
(Leave as zero if not decided yet).
#Html.ValidationMessageFor(model => model.contract.ContractValue)
</td>
</tr>
<tr>
<td align="center" colspan="2" style="padding-top:20px;"><input type="submit" value="Create" /></td>
</tr>
</table>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "List")
</div>

Your view model doesn't make sense. You are putting Required attribute on a non-nullable integer property which will have always a value (0 in your case). So start by modifying your view model:
[DisplayName("Contract Prefix")]
[UIHint("DropDownList")]
[Required(ErrorMessage = "You must select a Contract Prefix")]
public int? ContractTypeId { get; set; }
Now you can have dropdown lists with null values:
#Html.DropDownListFor(
x => x.contract.ContractTypeId,
Model.contractTypesSelectList,
"<--Select-->"
)
#Html.ValidationMessageFor(x => x.contract.ContractTypeId)
Then if you want to do client side validation in ASP.NET MVC 3, jQuery and the jQuery validate plugins are used for this. So make sure you have included the following scripts to your page:
jquery.validate.js
jquery.validate.unobtrusive.js
Also make sure that your controller action receives properly the selected value:
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
if (!ModelState.IsValid)
{
// there was an error => redisplay the view
return View(model);
}
// model.contract.ContractTypeId will contain a value
// at this stage here => use it to do some processing
...
}

Related

PartialView is not working (whole page refresh instead)

Hello I am new to MVC 4. I am having a problem with partialView.. I goole it and searched alot and studied different tutorials but couldn't find any solution that can address my problem.I created a PagedList to display records at Index.cshtml page. Then I created PartialIndex.cshtml page to display records in Partial View.
Here is problem: When I click on any page number or navigate.. whole page refreshes and post back... partial view is not working.Don't Know where I am doing wrong.
I want to show table inside the DIV in PartialIndex.cshtml
PartialIndex.cshtml:
<div id="targetContainer"> //I want to show this DIV in partial view.
<table>
<tr>
<th>
#Html.ActionLink("ID", "Index", new { sortOrder = ViewBag.customerID, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
</th>
<th>
#Html.DisplayName("First Name")
</th>
<th></th>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.lName, currentFilter=ViewBag.CurrentFilter })
</th>
<th></th>
<th>
#Html.DisplayName("Contact Num")
</th>
<th>
#Html.DisplayName("Address")
</th>
<th>
#Html.DisplayName("Email")
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.customerId)
</td>
<td>
</td>
<td>
#Html.DisplayFor(modelItem => item.fName)
</td>
<td>
</td>
<td>
#Html.DisplayFor(modelItem => item.lName)
</td>
<td>
</td>
<td>
#Html.DisplayFor(modelItem => item.contactNum)
</td>
<td>
</td>
<td>
#Html.DisplayFor(modelItem => item.address)
</td>
<td>
</td>
<td>
#Html.DisplayFor(modelItem => item.email)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID })
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
</div>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "GET", UpdateTargetId = "targetContainer" }))
Index.cshtml:
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.Partial("PartialIndex")
You should better use
Html.RenderPartial("~/Views/Shared/_Yourpartial.cshtml")
Html.RenderPartial("~/Views/Shared/PartialIndex.cshtml")

How to pass search criteria to controller using MVC AJAX PagedList

I'm creating Advanced Search using MVC. What I mean by Advanced Search is user can do combination search, for example, user can search by category = 'Child' and name contains 'A' or age <= 10. then the result is displayed using MVC PagedList.
I followed UnobtrusiveAjax tutorial based on example from PagedList source. I defined 2 files, Index.cshtml for View and _List.cshtml for PartialView. Index contains search criteria and a button to add more clause.
and _List contains table for displaying the result using AJAX
The problem is after I filtered by code for example contains 'A' and click search then navigate to page 2 the filter value is missing and it will display code which not contains 'A'. How to solve this problem?
ViewModel:
public class WorkflowStateListViewModel
{
public IEnumerable<string> FilterField { get; set; }
public IEnumerable<string> FilterOperator { get; set; }
public IEnumerable<string> FilterString { get; set; }
public IEnumerable<string> FilterLogical { get; set; }
public PagedList<WorkflowStateListDetailViewModel> WorkflowStateListDetailVM { get; set; }
public int? Page { get; set; }
}
Controller:
public ActionResult Filter(WorkflowStateListViewModel workflowStateListVM, int? page)
{
var workflowStatesQuery = from ws in db.WorkflowStates
where ws.RowStatus == true
select ws;
if (workflowStateListVM.FilterField != null)
{
for (int i = 0; i < workflowStateListVM.FilterField.Count(); i++)
{
workflowStatesQuery = DoFilter(workflowStatesQuery, workflowStateListVM.FilterField.ElementAt(i), workflowStateListVM.FilterOperator.ElementAt(i), workflowStateListVM.FilterString.ElementAt(i));
}
}
workflowStatesQuery = workflowStatesQuery.OrderBy(ws => ws.Code);
var workflowStateListDetailVM = from ws in workflowStatesQuery
select new WorkflowStateListDetailViewModel()
{
WorkflowStateID = ws.WorkflowStateID,
Code = ws.Code,
Name = ws.Name,
Level = ws.Level,
PIC = ws.PIC
};
int pageNumber = (page ?? 1);
return PartialView("_List", workflowStateListDetailVM.ToPagedList(pageNumber, 5));
}
Index.cshtml
#model ViewModels.WorkflowStateListViewModel
#using (Ajax.BeginForm("Filter", "WorkflowState",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
UpdateTargetId = "workflowStateList"
},
new { #class = "form-inline" }))
{
<div id="clauses">
</div>
<p>
<div class="form-group">
#Html.DropDownList("FilterField", new SelectList(Model.FilterField), new { #class = "form-control" })
</div>
<div class="form-group">
#Html.DropDownList("FilterOperator", new SelectList(Model.FilterOperator), new { #class = "form-control" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.FilterString, new { #class = "form-control" })
</div>
<input type="submit" value="Search" class="btn btn-default" />
</p>
<p>
<div class="form-group">
<span class="glyphicon glyphicon-plus-sign"></span> Add new clause
</div>
</p>
<div id="workflowStateList">
#{ Html.RenderPartial("_List", Model); }
</div>
}
_List.cshtml
#model JOeBilling.ViewModels.WorkflowStateListViewModel
#using PagedList.Mvc;
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed">
<tr>
<th></th>
<th>
Code
</th>
<th>
Name
</th>
<th>
Level
</th>
<th>
PIC
</th>
</tr>
#foreach (var item in Model.WorkflowStateListDetailVM)
{
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
#Html.DisplayFor(modelItem => item.Code)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Level)
</td>
<td>
#Html.DisplayFor(modelItem => item.PIC)
</td>
</tr>
}
</table>
</div>
<br />
Page #(Model.WorkflowStateListDetailVM.PageCount < Model.WorkflowStateListDetailVM.PageNumber ? 0 : Model.WorkflowStateListDetailVM.PageNumber) of #Model.WorkflowStateListDetailVM.PageCount
#Html.PagedListPager(Model.WorkflowStateListDetailVM,
page => Url.Action("Filter", new { page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "workflowStateList" }))
UPDATE
UPDATE 2
UPDATE 3 Response tab
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed">
<tr>
<th></th>
<th>
Code
</th>
<th>
Name
</th>
<th>
Level
</th>
<th>
PIC
</th>
<th>
Created By
</th>
<th>
Created Date
</th>
<th>
Modified By
</th>
<th>
Modified Date
</th>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
A06
</td>
<td>
Preparing Task Code
</td>
<td>
6
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
28/04/2014 4:24:52 PM
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
A07
</td>
<td>
Closed
</td>
<td>
7
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
28/04/2014 4:25:06 PM
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-remove"></span>
</td>
<td>
C01
</td>
<td>
New Invoice
</td>
<td>
1
</td>
<td>
</td>
<td>
JKTWLA
</td>
<td>
13/06/2014 10:49:00 AM
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
</div>
<br />
Page 2 of 2
<div class="pagination-container"><ul class="pagination"><li class="PagedList-skipToPrevious"><a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#workflowStateList" href="/WorkflowState/Filter?page=1" rel="prev">«</a></li><li><a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#workflowStateList" href="/WorkflowState/Filter?page=1">1</a></li><li class="active"><a>2</a></li></ul></div>

Post multiple data from an loaded form ajax mvc 4

I have a form like this
<table>
<thead>
<tr>
<th>Tên học sinh </th>
<th>Giáo lý viên </th>
<th>Năm Học</th>
<th>Điểm TB Học Kỳ 1 </th>
<th>Điểm TB Học Kỳ 2 </th>
<th>Điểm Tổng Kết Năm Học </th>
<th>Lớp </th>
</tr>
</thead>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset class="form-horizontal">
<tbody id="addDetails">
<tr>
<td>
#Html.DropDownList("HocSinhId", String.Empty)
#Html.ValidationMessageFor(model => model.HocSinhId, null, new { #class = "help-inline" })
</td>
<td>
#Html.DropDownList("GiaoLyVienId", String.Empty)
#Html.ValidationMessageFor(model => model.GiaoLyVienId, null, new { #class = "help-inline" })
</td>
<td>
#Html.TextBoxFor(model => model.NamHoc)
#Html.ValidationMessageFor(model => model.NamHoc, null, new { #class = "help-inline" })
</td>
<td>
#Html.EditorFor(model => model.DiemTBHK1)
#Html.ValidationMessageFor(model => model.DiemTBHK1, null, new { #class = "help-inline" })
</td>
<td>
#Html.EditorFor(model => model.DiemTBHK2)
#Html.ValidationMessageFor(model => model.DiemTBHK2, null, new { #class = "help-inline" })
</td>
<td>
#Html.EditorFor(model => model.DiemTongKetNamHoc)
#Html.ValidationMessageFor(model => model.DiemTongKetNamHoc, null, new { #class = "help-inline" })
</td>
<td>
#Html.DropDownList("LopId", String.Empty)
#Html.ValidationMessageFor(model => model.LopId, null, new { #class = "help-inline" })
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
#Ajax.ActionLink("Add", "AddDetails", new AjaxOptions
{
HttpMethod = "GET",
OnSuccess = "successCall",
#*UpdateTargetId = "addDetails",
InsertionMode = InsertionMode.InsertAfter,*#
})
</td>
</tr>
<tr>
<td colspan="6">
#* *#
<input type="submit" value="Lưu thông tin" class="button" />
</td>
</tr>
</tfoot>
</fieldset>
}
</table>
After click Ajax link "Add" it will insert new row to input new data.
Image: http://i808.photobucket.com/albums/zz1/nquangkhaiDST/Postmultipledata_zps5364f0a0.png
The Question is: When I submit to server, it just post the first data, not the data after i click "Add". How i can get all the data even field from ajax to post back to server.
Anyone know how to post all the data even the data of ajax. Thanks a lots
Assuming you'll be adding that same type of object when you click Add, what you need to do is accept an array of your model object in your Post controller parameter.
[HttpPost]
public ActionResult(MyObject[] objects)
{
// do something
}
did you check your html on client side.... while submitting from client side you have to make sure that that the controls added on the page must have naming convention like
<input type="text" value="" name="IncomeDetails[0].IncomeCode" id="IncomeDetails_0__IncomeCode" class="incomeCode valid" disabled="disabled">
on the first row and
<input type="text" disabled="disabled" class="incomeCode valid" id="IncomeDetails_1__IncomeCode" name="IncomeDetails[1].IncomeCode" value="">
on the second row then only while submitting you can get full list of objects.

MVC 3 Ajax.BeginForm submit issue

im trying to submit a form by pressing a button that eventually will refresh the table
this is the form :
#{
AjaxOptions ajaxOpts = new AjaxOptions
{
Confirm = "start ???",
UpdateTargetId = "MainTable",
InsertionMode = InsertionMode.Replace,
Url = Url.Action("Refresh","MainScreen"),
LoadingElementId = "loading",
LoadingElementDuration = 2000,
};}
#using (Ajax.BeginForm(ajaxOpts)){
<div id="loading" style="display: none; color: Red; font-weight: bold">
<p>
Loading Data...</p>
</div>
<div id="header">
<input type="button" value="Submit Form" />
</div>
<table id="MainTable">
<tr>
<th>
ServiceId
</th>
<th>
ServiceInstanceId
</th>
<th>
MessageRole
</th>
<th>
Datetime
</th>
<th>
Message
</th>
<th>
Status
</th>
<th>
ESBErrorCode
</th>
<th>
ESBTecnicalErrorCode
</th>
<th>
ErrorDescription
</th>
<th>
PortName
</th>
<th>
MachineName
</th>
<th>
ConsumerId
</th>
<th>
ExternalId
</th>
<th>
ConsumerMachineName
</th>
<th>
ServiceBehavior
</th>
<th>
RouterConsumerId
</th>
<th>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ServiceId)
</td>
<td>
#Html.DisplayFor(modelItem => item.ServiceInstanceId)
</td>
<td>
#Html.DisplayFor(modelItem => item.MessageRole)
</td>
<td>
#Html.DisplayFor(modelItem => item.Datetime)
</td>
<td>
\
#Html.DisplayFor(modelItem => item.Message.Context)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.ESBErrorCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.ESBTecnicalErrorCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.ErrorDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.PortName)
</td>
<td>
#Html.DisplayFor(modelItem => item.MachineName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ConsumerId)
</td>
<td>
#Html.DisplayFor(modelItem => item.ExternalId)
</td>
<td>
#Html.DisplayFor(modelItem => item.ConsumerMachineName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ServiceBehavior)
</td>
<td>
#Html.DisplayFor(modelItem => item.RouterConsumerId)
</td>
</tr>
}
</table>
}
this is the Controler :
public ViewResult Refresh()
{
var tracks = db.Tracks.Include(t => t.Message);
return View(tracks.ToList());
}
for some reason when i submit the button nothing happen
i already added
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
thanks
miki
The unobtrusive js helper listens on the submit event with
$("form[data-ajax=true]").live("submit"...
but your "submit" button is "just a button" not a submit button:
<input type="button" value="Submit Form" />
Change it to type="submit"and it should work:
<input type="submit" value="Submit Form" />

How to print 2 columns of pictures from a list in asp.net mvc3

I have this code and I am a bit in doubt how to make it print 2 rows instead of just 1 (Later I want it to be dynamic depending on screensize if possible, but for now it should just be 2 columns)
http://pastebin.com/H7CpBWWN
#model IEnumerable<FirstWeb.Models.Picture>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Title
</th>
<th>
Path
</th>
<th>
ConcertYear
</th>
<th>
Title
</th>
<th>
Path
</th>
<th>
ConcertYear
</th>
</tr>
#bool even = false;
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
<a href=#Html.DisplayFor(modelItem => item.Path)><img src=#Html.DisplayFor(modelItem => item.Path) width="250px" /> </a>
</td>
<td>
#Html.DisplayFor(modelItem => item.ConcertYear)
</td>
</tr>
}
</table>
So I want the boolean to be the switch between left and right column
I don't know how you can do it with your boolean flag for left or right, but if you are just after two columns, you could do something like this (apologies for typos/syntax errors, but you get the idea).
#for (int i = 0; i < Model.ContactMethods.Count; i += 2)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model[i].Title)
</td>
<td>
<a href=#Html.DisplayFor(modelItem => Model[i].Path)>
<img src=#Html.DisplayFor(modelItem => Model[i].Path) width="250px" />
</a>
</td>
<td>
#Html.DisplayFor(modelItem => Model[i].ConcertYear)
</td>
#if (Model.ContactMethods.Count > i + 1)
{
<td>
#Html.DisplayFor(modelItem => Model[i + 1].Title)
</td>
<td>
<a href=#Html.DisplayFor(modelItem => Model[i + 1].Path)>
<img src=#Html.DisplayFor(modelItem => Model[i + 1].Path) width="250px" />
</a>
</td>
<td>
#Html.DisplayFor(modelItem => Model[i + 1].ConcertYear)
</td>
}
else
{
<td colspan="3"></td>
}
</tr>
}
As far as dynamic columns, you'll need to look at jquery for that

Resources