AJAX with partial view MVC 4 ASP.net C# - c#

Ok thanks to you guys i got it nearly working now but i don't get why it won't reload the data the current code is:
My partial view:
#model IEnumerable<Smoelenboek.Models.Person>
#{
ViewBag.Title = "Search details";
}
<div class="searchresults">
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
Knowledge
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th>
Skills to learn
</th>
<th>
Project
</th>
<th>
Years of work experience
</th>
<th>
Hobby projects
</th>
<th>
Summary
</th>
<th>
Extra Information
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink(item.Name.ToString(), "/SearchSkillsDetails", new { id = item.ID })
</td>
<td>
#Html.DisplayFor(modelItem => item.LearntSkillsAndLevelOfSkills)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.SkillsToLearn)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stand)
</td>
<td>
#Html.DisplayFor(modelItem => item.YearsOfWorkExperience)
</td>
<td>
#Html.DisplayFor(modelItem => item.HobbyProjectICTRelated)
</td>
<td>
#Html.DisplayFor(modelItem => item.Summary)
</td>
<td>
#Html.DisplayFor(modelItem => item.ExtraInfo)
</td>
</tr>
}
</table>
</div>
my view:
#model IEnumerable<Smoelenboek.Models.Person>
#{
ViewBag.Title = "Search Skills";
}
<h2>Search People</h2>
#using (Html.BeginForm("SearchSkills", "Person", FormMethod.Get))
{
<div class="search">
#Html.TextBox("parameter")
<select name="choice" class="choicecheckbox">
<option id="knowsalready">Knows Already</option>
<option id="wantstolearn">Wants To Learn</option>
<option id="hobbies">Hobbies</option>
<option id="name">Name</option>
</select>
<input class="inputsearch" type="submit" value="Search" />
</div>
}
<br />
<h2>Search results</h2>
<div class="searchfilters">
<br />
<input id="checkboxlocationfilter" type="checkbox" name="locationFilter" class="locationFiltercss" onchange="changeFilter()">
<label for="checkboxlocationfilter" class="locationFiltercss">Filter on location</label>
<br />
<input id="checkboxlevelofknowledgefilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxlevelofknowledgefilter" class="locationFiltercss">Filter on skill level of knowledge</label>
<br />
<input id="checkboxlevelofwantstolearnfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxlevelofwantstolearnfilter" class="locationFiltercss">Filter on skills level of wants to learn</label>
<br />
<input id="checkboxpopularityfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxpopularityfilter" class="locationFiltercss">Filter on popularity</label>
<br />
<input id="checkboxhobbyprojectsfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxhobbyprojectsfilter" class="locationFiltercss">Filter on only hobbyprojects</label>
<br />
<input id="checkbox5yearsfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkbox5yearsfilter" class="locationFiltercss">Filter on years of work experience more than 5</label>
<script type="text/javascript">
$(checkbox5yearsfilter).click(function () {
if ($(checkbox5yearsfilter).is(':checked')) {
$.ajax({
type: 'POST',
url: '../Person/changeFilter',
datatype: 'html',
success: function (data) {
$('#_SearchSkills').html(data);
alert(data);
},
error: function (data) {
alert("failed");
}
});
}
});
</script>
<br />
<input id="checkbox10yearsfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkbox10yearsfilter" class="locationFiltercss">Filter on years of work experience more than 10</label>
<br />
<input id="checkbox15yearsfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkbox15yearsfilter" class="locationFiltercss">Filter on years of work experience more than 15</label>
<br />
<input id="checkboxphonenrfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxphonenrfilter" class="locationFiltercss">Has phone number</label>
<br />
<input id="checkboxextrainfoyfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxextrainfoyfilter" class="locationFiltercss">Has extra info</label>
<br />
<input id="checkboxextrainfonfilter" type="checkbox" name="levelFilter" class="locationFiltercss">
<label for="checkboxextrainfonfilter" class="locationFiltercss">doesn't have extra info</label>
</div>
<span>
#Html.Partial("_SearchSkills", ViewData.Model);
</span>
my controllermethod:
public PartialViewResult changeFilter()
{
List<Person> list = new List<Person>();
list = (from p in db.Persons where p.YearsOfWorkExperience > 5 select p).ToList();
return PartialView("_SearchSkills", list);
}
now i get returned the html code in the ajax call. i just need to know how i can render the table again with the new data because i really don't get how i can do that. I found some stuff on internet that says use $(MyPartialName).html(data) but that doesn't work for me so is there another way to do it or did i forget something(i did add the unobtrusive-ajax.js in the _Layout). Hope somebody can help me with this thank you very much in advance :D

Your jQuery selector is not valid. In your script tag change like following
$('#checkbox5yearsfilter').click(function () {
if ($('#checkbox5yearsfilter').is(':checked')) {
And replace this
<span>
#Html.Partial("_SearchSkills", ViewData.Model);
</span>
with this
<span id="_SearchSkills"></span>

Related

The model directive may only occur once per document (adding buttons to lists problem) ASP.NET MVC Core C#

I'm trying to display a button because I need to add new information but there is a list within the file and it is not working
I am using ASP.NET Core MVC and C#.
It is something like this:
HTML File:
#model IEnumerable<MyApplication.Models.Clients>
<table class="table" id="Tabla4">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.CODE)
</th>
<th>
#Html.DisplayNameFor(model => model.NAME)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CODE)
</td>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
</td>
</tr>
}
</tbody>
</table>
My controller method:
public ActionResult Create()
{
List<Clients> clients = dbContext.GetClients().ToList();
return View(clients);
}
I want to add this in my HTML file:
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CODE" class="control-label"></label>
<input asp-for="CODE" class="form-control" />
<span asp-validation-for="CODE" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="NAME" class="control-label"></label>
<input asp-for="NAME" class="form-control" />
<span asp-validation-for="NAME" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
I tried to add this:
#Model MyApplication.Models.Clients
I get this error:
The model directive may only occur once per document
How can I solve it?
EDIT:
My Client Model is this:
public class Clients{
public int CODE {get; set;}
public string NAME {get; set;}
}
If i put the button inside the HTML File it throws and error:
#model IEnumerable<MyApplication.Models.Clients>
<table class="table" id="Tabla4">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.CODE)
</th>
<th>
#Html.DisplayNameFor(model => model.NAME)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CODE)
</td>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
</td>
</tr>
}
</tbody>
</table>
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CODE" class="control-label"></label>
<input asp-for="CODE" class="form-control" />
<span asp-validation-for="CODE" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="NAME" class="control-label"></label>
<input asp-for="NAME" class="form-control" />
<span asp-validation-for="NAME" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
It says:
IEnumerable<MyApplication.Models.Clients> does not contain a
definition CODE and no accesible extension method CODE
IEnumerable<MyApplication.Models.Clients> does not contain a
definition NAME and no accesible extension method NAME
EDIT #2
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label for="CODE" class="control-label"></label>
<input name="CODE" class="form-control" />
</div>
<div class="form-group">
<label for="NAME" class="control-label"></label>
<input name="NAME" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
EDIT #3:
Now it is throwing this error: Object reference not set to an instance of an object, in the foreach part:
#model IEnumerable<MyApplication.Models.Clients>
<div class="row">
<div class="col-md-4">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label for="CODE" class="control-label">Code:</label>
<input name="CODE" class="form-control" />
</div>
<div class="form-group">
<label for="NAME" class="control-label">Name:</label>
<input name="NAME" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Insert" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<table class="table" id="Tabla4">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.CODE)
</th>
<th>
#Html.DisplayNameFor(model => model.NAME)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CODE)
</td>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
</td>
</tr>
}
</tbody>
</table>
Image:
[![image][1]][1]
This is my Controller Create HTTP METHOD:
public ActionResult Create([Bind] Clients clients)
{
try
{
if (ModelState.IsValid)
{
dbContext.InsertData(clients);
return RedirectToAction("Index");
}
return View(clients);
}
catch
{
return View();
}
}
You cannot use asp-for="..." when the model/value you are using does not have these properties. Your model is defined as IEnumerable<MyApplication.Models.Clients> as the value for the view is a List<MyApplication.Models.Clients> object. When you use <input asp-for="CODE"> it looks for a property CODE inside the IEnumerable<...> type. However, this interface does not have such a property.
In your case you don't need asp-for="". Instead you can use a "normal" <input> tag with the name="..." attribute you want, depending on the Create() action you have defined. The code can look like this:
<div class="form-group">
<label for="CODE" class="control-label">Code:</label>
<input name="CODE" class="form-control" />
</div>
That way the HTTP Request will have the field name CODE in the POST body or GET URL parameter list, depending on how you send the form. ASP.NET will automatically fill the values into the parameters of your Create() action for you.

Problem with pass data to the controller with view model ( two list )

I create a view and create two cards to show new skill and current skill.
The problem is TittleNewSkillEHS back to the controller cero data after I select a new skill.
Short description of my request
I will need to display two lists with information about New Skill (required checkbox to select and add current skill), Current skill (required update target).
One approached to solution the request I create a view model take EmployeeTitle id, Title name, and two list
• List Current skills
• List New skills
.
.
.
TitleSkillVM TitleSkillVMNew = new TitleSkillVM();
TitleSkillVMNew.TitleId = SelectTitle.TitleId;
TitleSkillVMNew.TitleDescription = SelectTitle.TitleName;
TitleSkillVMNew.TittleNewSkillEHS = _tempNewEHS; “New skill”
TitleSkillVMNew.TittleSkillEHS = _tempEHS; “List Current skill”
return View(TitleSkillVMNew);
}
#model WCMApps.Models.ViewModel.TitleSkillVM
<div class="row">
<div class="col-sm-6">
<form asp-controller="AdmTitles" asp-action="InsertNewSkillTarget" method="post">
<input type="hidden" asp-for="TitleId" />
<%: Html.HiddenIndexerInputForModel() %>
<input type="hidden" asp-for="TittleNewSkillEHS" />
<div class=" card">
<div class="card-header">
<div class="container">
<div class="row">
<div class="col-9">
<h4>New Skill Index</h4>
</div>
</div>
</div>
</div>
<div class="card-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th scope="col">
Skill Name
</th>
<th scope="col">
Current Target
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TittleNewSkillEHS)
{
if (item.TitleSkillTargetStatus == true)
{
<tr class="table-info">
<td>
#Html.CheckBoxFor(modelItem => item.IsSelectedNewSkillTitle, item.TitleSkillTargetId)
#Html.HiddenFor(modelItem => item.TitleSkillTargetId)
</td>
<td>
#Html.DisplayFor(modelItem => item.SkillLevelDDescription)
#Html.HiddenFor(modelItem => item.SkillLevelDDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.Target)
#Html.HiddenFor(modelItem => item.Target)
</td>
</tr>
}
}
</tbody>
</table>
</div>
<div class="card-footer">
<small class="text-muted">
<button type="submit" class="btn btn-outline-info" onclick="location.href='#Url.Action("InsertNewSkillTarget", "AdmTitles", Model.TittleNewSkillEHS)'">Save</button>
</small>
</div>
</div>
</form>
</div>
<div class="col-sm-6">
<form asp-controller="AdmTitles" asp-action="UpdateCurrentSkillTarget" method="post">
<div class="card">
<div class="card-header">
<div class="container">
<div class="row">
<div class="col-9">
<h4>Current Skill Index</h4>
</div>
</div>
</div>
</div>
<div class="card-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">
Skill Name
</th>
<th scope="col">
Current Target
</th>
<th scope="col">
Target
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TittleSkillEHS)
{
if (item.TitleSkillTargetStatus == true)
{
<tr class="table-success">
<td>
#Html.DisplayFor(modelItem => item.SkillLevelDDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.Target)
</td>
<td>
<div class="form-group">
<input asp-for="Target" class="form-control" />
<span asp-validation-for="Target" class="text-danger"></span>
</div>
</td>
</tr>
}
}
</tbody>
</table>
</div>
<div class="card-footer">
<small class="text-muted">
<button type="button" class="btn btn-outline-info" onclick="location.href='#Url.Action("UpdateCurrentSkillTarget", "AdmTitles", Model.TittleSkillEHS)'">Update</button>
</small>
</div>
</div>
</form>
</div>
</div>'
Here is a demo to pass TittleNewSkillEHS to Controller:
View:
<div class="card-header">
<div class="container">
<div class="row">
<div class="col-9">
<h4>New Skill Index</h4>
</div>
</div>
</div>
</div>
<div class="card-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th scope="col">
Skill Name
</th>
<th scope="col">
Current Target
</th>
</tr>
</thead>
<tbody>
#{ var count = 0;}
#foreach (var item in Model.TittleNewSkillEHS)
{
if (item.TitleSkillTargetStatus == true)
{
<tr class="table-info">
<td>
#*#Html.CheckBoxFor(modelItem => item.IsSelectedNewSkillTitle, new { #name = "TittleNewSkillEHS[#count].IsSelectedNewSkillTitle" })
#Html.CheckBox("IsChecked", new { #name = "TittleNewSkillEHS[#count].IsSelectedNewSkillTitle" })*#
<input asp-for=#item.IsSelectedNewSkillTitle name="TittleNewSkillEHS[#count].IsSelectedNewSkillTitle"/>
<input name="TittleNewSkillEHS[#count].TitleSkillTargetId" value=#item.TitleSkillTargetId hidden />
</td>
<td>
#Html.DisplayFor(modelItem => item.SkillLevelDDescription)
<input name="TittleNewSkillEHS[#count].SkillLevelDDescription" value=#item.SkillLevelDDescription hidden />
#*#Html.HiddenFor(modelItem => item.SkillLevelDDescription)*#
</td>
<td>
#Html.DisplayFor(modelItem => item.Target)
<input name="TittleNewSkillEHS[#count].Target" value=#item.Target hidden />
#*#Html.HiddenFor(modelItem => item.Target)*#
</td>
</tr>
count++;
}
}
</tbody>
</table>
</div>
<div class="card-footer">
<small class="text-muted">
<button type="submit" class="btn btn-outline-info">Save</button>
</small>
</div>
</div>
Controller:
public IActionResult InsertNewSkillTarget(TitleSkillVM t) {
return Ok();
}
result:

How do I pass a selected ID to my SQL Database?

I am having trouble with this last part of my project. I have all of my SQL Table columns filled up except for this last part. I have two tables WorkSchedule and WorkShiftBid.
In WorkShiftBid, I have WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID
I will be using Guid.NewGuid() for WorkShiftBidID, Datetime.now for WSBidDatetime, A hardcoded "pending" value for WSBidStatus, A viewbag for StaffID and I am trying to get the WorkScheduleID to work but to no avail.
For WorkSchedule, I am trying to get just the "WorkScheduleID" attribute just by using a button method asp-route-id="#item.WorkScheduleID" and it will redirect me to the Create page whereby I will select a Staff from the drop-down list and then save it to my WorkShiftBid table as it has a foreign key for "WorkScheduleID".
It would be helpful if someone could help me. Thank you.
Controller Code:
public IActionResult CreateWorkShift()
{
ViewData["StaffID"] = new SelectList(_context.Staff, "StaffID", "StaffName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateWorkShift(Guid? id, [Bind("WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID")] WorkShiftBidModel workShiftBidModel)
{
if (id != workShiftBidModel.WorkScheduleID)
{
return NotFound();
}
if (ModelState.IsValid)
{
workShiftBidModel.WSBidDateTime = DateTime.Now;
workShiftBidModel.WorkShiftBidID = Guid.NewGuid();
_context.Add(workShiftBidModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(DisplaySchedule));
}
ViewData["StaffID"] = new SelectList(_context.Staff, "StaffID", "StaffName", workShiftBidModel.StaffID);
return View(workShiftBidModel);
}
private bool WorkShiftBidModelExist(Guid id)
{
return _context.WorkSchedule.Any(e => e.WorkScheduleID == id);
}
Display WorkShift Page:
<h1 class="text-center"> Apply Workshifts</h1>
<hr />
<table class="table">
<thead>
<tr>
<th>
From (DateTime)
</th>
<th>
To (DateTime)
</th>
<th>
Day
</th>
<th>
Status
</th>
<th>
Work Descriptions
</th>
<th>
Branch
</th>
<th>
Manager
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleFromDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleToDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleFromDateTime.DayOfWeek)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkScheduleStatus)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkDescriptions.WorkDescriptionName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Branches.BranchName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Staff.StaffName)
</td>
<td>
<form method="post">
<input type="submit" class="btn btn-primary btn-block" value="Bid" asp-route-id="#item.WorkScheduleID" asp-action="DisplaySchedule" asp-controller="PartTimer" />
</form>
<div class="form-group col-md-6">
<a asp-action="CreateWorkShift" asp-route-id="#item.WorkScheduleID" class="btn btn-success">Create</a>
</div>
</td>
</tr>
}
</tbody>
</table>
Create view page code:
<h1>Create</h1>
<h4>Work Shifts</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="CreateWorkShift">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="WorkScheduleID"/>
<div class="form-group">
<label asp-for="WSBidStatus" class="control-label"></label>
<input readonly asp-for="WSBidStatus" value="Pending" class="form-control"/>
<span asp-validation-for="WSBidStatus" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StaffID" class="control-label"></label>
<select asp-for="StaffID" class="form-control" asp-items="ViewBag.StaffID"></select>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<input type="submit" value="Save" class="btn btn-primary btn-block" />
</div>
<div class="form-group col-md-6">
<a asp-action="ProfilePage" class="btn btn-secondary btn-block"><i class=" fa fa-table"></i>Back to List</a>
</div>
</div>
</form>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Do you mean you cannot get the WorkScheduleID in public async Task<IActionResult> CreateWorkShift(Guid? id, [Bind("WorkShiftBidID,WSBidDateTime,WSBidStatus,WorkScheduleID,StaffID")] WorkShiftBidModel workShiftBidModel).If so,you need to get and pass Id in public IActionResult CreateWorkShift.Here is a demo worked:
public IActionResult CreateWorkShift(int id)
{
List<Staff> list = new List<Staff> { new Staff { StaffID = 1, StaffName = "staff1" }, new Staff { StaffID = 2, StaffName = "staff2" } };
ViewData["StaffID"] = new SelectList(list, "StaffID", "StaffName");
WorkShiftBidModel w = new WorkShiftBidModel { WorkScheduleID = id };
return View(w);
}
result:

How to post data to razor page code behind asp.net core

I want to implement a bulk operation function, but I cannot post my data to the razor page code behind, anyone can help? Please check my code below
<form method="post" asp-page="./Index">
<div class="row">
<div class="col-md-12">
<table class="table table-hover table-bordered" style="margin-top:15px;">
<thead>
<tr class="info">
<th></th>
<th>
<a asp-page="./Index" asp-route-sortOrder="#Model.NumberSort">
#Html.DisplayNameFor(model => model.Products[0].Number)
</a>
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Products)
{
<tr>
<td>
#Html.CheckBoxFor(modelItem => item.Checked)
</td>
<td class="success">
#Html.DisplayFor(modelItem => item.Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a asp-page="./Details" asp-route-id="#item.ID" class="btn btn-info">details</a>
<a asp-page="./Edit" asp-route-id="#item.ID" class="btn btn-warning">edit</a>
<a asp-page="./Delete" asp-route-id="#item.ID" class="btn btn-danger">delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-10">
#{
var items = Model.Products.Where(x => x.Checked);
}
<input type="submit" name="bulkUpload" value="bulk upload" asp-route-data="#items"/>
</div>
</div>
</form>
public async Task OnPostAsync(List<Product> upload)
{
}
You need to render your products in such way that the Modelbinder will be able to pick them up on form submit and pass them into the codebehind.
Something like this (done by hand so it might not compile at first):
#{
for (int i = 0; i < Model.Products.Count; i++)
{
<input type="checkbox" asp-for="Model.Produtcs[i].Checked" />
#Model.Products[i].Number
#Model.Products[i].Name
}
}
This will render HTML like
<input type="checkbox" name="Products[0].Checked" />
<input type="checkbox" name="Products[1].Checked" />
<input type="checkbox" name="Products[2].Checked" />
And it should get back to your OnPostAsync. If not then try changing
public async Task OnPostAsync(List<Product> upload)
to
public async Task OnPostAsync(YourModel model)
What ever your full model is named.
This is then redundant:
#{
var items = Model.Products.Where(x => x.Checked);
}

Create a view inside a view on submit MVC4

I have a view with a form, when that form is submitted I want to show another view inside the first view. I have tried with partialview (not sure that is for my purpose?) but I cant get it to work because the model is null (its strongly-typed partialview). But I just want it to be created on the submitbutton and then it should be OK.
So, help my create a view/partialview inside a when submitting my form. Right now I get "Object reference not set to an instance of an object." on the foreach loop in my partial view, but it's not supposed to be created until the form is submitted.
My view:
<div class="calcInput">
#using (Html.BeginForm("ShowDetail", "Calculation"))
{
<div class="calculateBox">
<label for="calcOption">Choose value to calculate:</label>
<select form="anFormCalcInput" id="calcOption" title="Choose what value you want to calculate">
<option value="anPMT">Payment (PMT)</option>
<option value="anI">Interest (I)</option>
<option value="anFV">Future value (FV)</option>
<option value="anPV">Present value (PV)</option>
</select>
</div>
<div class="calculateBox" background-color="#777777">
#Html.Label("Present value (PV)")
#Html.TextBox("PresentValue")
#Html.Label("Future value")
#Html.TextBox("FutureValue")
#Html.Label("Interest rate")
#Html.TextBox("InterestRate") <br />
<input type="radio" name="advanceOrArrears" id="inAdvance" value="inAdvance" /> In advance<br />
<input type="radio" name="advanceOrArrears" id="inArrears" value="inArrears" /> In arrears
</div>
<div class="calculateBox">
<label for="startDate">Start date:</label>
<input type="date" id="anStartDate" name="startdate" title="Choose start date for your calculation" /><br />
#Html.Label("Payment frequency")
<select form="anFormCalcInput" id="anPmtFreq" title="Choose the payment frequency, for example: Every month">
<option value="Monthly">Monthly</option>
<option value="Quarterly">Quarterly</option>
<option value="Yearly">Yearly</option>
</select><br /><br />
#Html.Label("No of payment periods")
#Html.TextBox("PaymentPeriods")
#Html.Label("Date time convention")
<select form="anFormCalcInput" id="anDTC" title="Choose your Date time convention">
<option value="360360">360/360</option>
<option value="365365">365/365</option>
</select><br /><br />
<input type="submit" id="anCalcBtn" class="calcBtn" name="anSubmitBtn" value="Calculate" title="Calculate your calculation" />
</div>
}
</div>
<table cellspacing="0" width="80%">
<div class="calcGraph">
</div>
<div class="calcDetail" id="anCalcDetail">
#Html.Partial("ShowDetail") //This is where I want my view/partialview to show up
</div>
My partialview:
#model IEnumerable<CalcFactory.Models.Calculation>
<table cellspacing="0" width="80%">
<thead>
<tr>
<th>
Date
</th>
<th>
Invoice amount
</th>
<th>
Interest rate
</th>
<th>
Interest amount
</th>
<th>
Amortization
</th>
<th>
Capital balance
</th>
<th></th>
</tr>
</thead>
<tr>
<td align="center">
</td>
<td align="center">
</td>
<td align="center">
</td>
<td align="center">
</td>
<td align="center">
</td>
<td align="center" id="startValue">
</td>
</tr>
#foreach (var item in Model) { //this is where i get null exception, model is null. But it supposed to be created on submit button...
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.InvoiceAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.InterestRate)
</td>
<td>
#Html.DisplayFor(modelItem => item.InterestAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.Amortization)
</td>
<td>
#Html.DisplayFor(modelItem => item.PresentValue)
</td>
</tr>
}
My Controller:
public class CalculationController : Controller
{
public PartialViewResult ShowDetail(FormCollection form)
{
List<Calculation> cList = new List<Calculation>();
Calculation calc = new Calculation();
calc.Date = Convert.ToDateTime(form["startdate"]);
calc.InvoiceAmount = 2000;
calc.InterestRate = Convert.ToDouble(form["InterestRate"]);
calc.InterestAmount = (Convert.ToDouble(form["PresentValue"]) * Convert.ToDouble(form["InterestRate"]) / 360 * 30);
calc.Amortization = (2000 - (Convert.ToDouble(form["PresentValue"]) * Convert.ToDouble(form["InterestRate"]) / 360 * 30));
calc.PresentValue = Convert.ToDouble(form["PresentValue"]) - calc.Amortization;
cList.Add(calc);
for (int i = 0; i < Convert.ToInt32(form["PaymentPeriods"]); i++)
{
Calculation calcBefore = cList.Last();
calc = new Calculation();
calc.Date = calcBefore.Date.AddMonths(1);
calc.InvoiceAmount = 2000;
calc.InterestRate = Convert.ToDouble(form["InterestRate"]);
calc.InterestAmount = (calcBefore.PresentValue * Convert.ToDouble(form["InterestRate"]) / 360 * 30);
calc.Amortization = (calc.InvoiceAmount - (calcBefore.PresentValue * calc.InterestRate / 360 * 30));
calc.PresentValue = calcBefore.PresentValue - calc.Amortization;
cList.Add(calc);
}
return PartialView("ShowDetail", cList);
}
}

Categories