Managing state in asp.net mvc C# - c#

On loading the application, table with list of items is displayed.
On clicking the save button, i want to write the list of items to excel.
When i click the save button, in the new request send to the controller,the list is empty.I do not prefer to write the list of table items to database.
Could anyone advice me on how to do handle this?
public IActionResult SaveReport(SalesParentViewModel salesParentViewModel)
{
if(salesParentViewModel.SalesDataModelItems != null)
{
var buffer = new StringBuilder();
buffer.AppendLine("#UserCode,SalesmanName,Date,ItemCode,ItemDescription,BrandCode,BrandName,ClientCode,Client,ClientBranchCode,Description, BranchSubChannel,TransactionAmount,Quantity");
salesParentViewModel.SalesDataModelItems.ToList().ForEach(item => buffer.AppendLine
(String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}", item.UserCode, item.SALESMANNAME, item.DATE, item.ItemCode, item.ITEMDESCRIPTION, item.BRANDCODE, item.BRANDNAME, item.ClientCode, item.Client, item.ClientBranchCode, item.Description, item.BRANCHSUBCHANNEL, item.TrxAmount, item.QTY
)));
System.IO.File.WriteAllText("c:\\temp\\file.csv", buffer.ToString());
}
return View();
}
View is as below:
#model MyStoreReports.ViewModels.SalesParentViewModel
#{
ViewBag.Title = "Sales Report";
}
#section scripts{
<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js"></script>
<link rel="stylesheet"
href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css">
<script type="text/javascript"
src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript"
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
}
<div class="container-fluid">
<div class="row">
<div class="col-sm-9">
<h1>Sales Report</h1>
</div>
</div>
<div>
<asp:Button id="btnFilter" class="btn btn-sm btn-info" runat="server" Text="Click Me!">
<i class="fa fa-filter"></i>Filter
</asp:Button>
#using (Html.BeginForm("SaveReport", "App", FormMethod.Post))
{
#Html.HiddenFor(model => model.SalesDataModelItems);
<asp:Button id="btnSave" class="btn btn-sm btn-info" onclick="location.href='#Url.Action("SaveReport","App")'" runat="server" Text="Click Me!">
<i class="fa fa-save"></i>Save
</asp:Button>
}
#*<a href="#" class="btn btn-sm btn-info">
<i class="fa fa-save"></i>Save
</a>*#
<a href="#" class="btn btn-sm btn-info">
<i class="fa fa-print"></i>Print
</a>
</div>
<div class="row">
<form method="post">
<asp:Panel id="pnlFilter" runat="server" GroupingText="This is a sample group text" HorizontalAlign="Center">
<div class="col-sm-10" style="background-color:lavenderblush;">
<div class="row">
<div class="col-sm-2">
<label asp-for="SalesViewModelInstance.StartDate">StartDate</label>
<div class="form-group">
<input asp-for="SalesViewModelInstance.StartDate" type="date" class="form-control" />
<span asp-validation-for="SalesViewModelInstance.StartDate" class="text-muted"></span>
</div>
</div>
<div class="col-sm-2">
<label asp-for="SalesViewModelInstance.EndDate">EndDate</label>
<div class="form-group">
<input asp-for="SalesViewModelInstance.EndDate" type="date" class="form-control" />
<span asp-validation-for="SalesViewModelInstance.EndDate" class="text-muted"></span>
</div>
</div>
<div class="row">
<div class="col-sm-1">
<input type="submit" value="Submit" class="btn btn-success" />
</div>
<div class="col-sm-1">
<a asp-controller="App" asp-action="Index" class="btn btn-default">Cancel</a>
</div>
</div>
</div>
</asp:Panel>
</form>
</div>
<div class="form-group">
#if (Model.SalesDataModelItems != null)
{
<div class="container" style="background-color:lavender;" >
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h2>Report</h2>
</div>
<div class="VScrollTable">
<table id="myTable" class="table table-fixed table-responsive" align="left" cellspacing="0">
<thead>
<tr>
<th>UserCode</th>
<th>SalesmanName</th>
<th>Date</th>
<th>ItemCode</th>
<th>ItemDescription</th>
<th>BrandCode</th>
<th>BrandName</th>
<th>ClientCode</th>
<th>Client</th>
<th>ClientBranchCode</th>
<th>Description</th>
<th>BranchSubChannel</th>
<th>TransactionAmount</th>
<th>Quantity</th>
</tr>
</thead>
#foreach (var item in Model.SalesDataModelItems)
{
<tbody>
<tr>
<td>#item.UserCode</td>
<td>#item.SALESMANNAME</td>
<td>#item.DATE</td>
<td>#item.ItemCode</td>
<td>#item.ITEMDESCRIPTION</td>
<td>#item.BRANDCODE</td>
<td>#item.BRANDNAME</td>
<td>#item.ClientCode</td>
<td>#item.Client</td>
<td>#item.ClientBranchCode</td>
<td>#item.Description</td>
<td>#item.BRANCHSUBCHANNEL</td>
<td>#item.TrxAmount</td>
<td>#item.QTY</td>
</tr>
</tbody>
}
</table>
</div>
</div>
</div>
</div>
}
</div>
</div>

If no change is done in the model, why would you want to pass the entire model from the view to the controller?
Just pass an identifier of some sort like id, and get the data again in the controller and save it in Excel.
If you must pass the model back to the controller it can be done, but the data needs to be hidden inputs or editable input controls (text box, check box)
Your view should look similar to the following :
#model MyStoreReports.ViewModels.SalesParentViewModel
#{
ViewBag.Title = "Sales Report";
}
#section scripts{
<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js"></script>
<link rel="stylesheet"
href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css">
<script type="text/javascript"
src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript"
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
}
<div class="container-fluid">
<div class="row">
<div class="col-sm-9">
<h1>Sales Report</h1>
</div>
</div>
<div>
#using (Html.BeginForm("SaveReport", "App", FormMethod.Post))
{
<input id="brnSave" type="submit" class="btn btn-sm btn-info" value="Save" />
<div class="form-group">
#if (Model.SalesDataModelItems != null)
{
<div class="container" style="background-color:lavender;">
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h2>Report</h2>
</div>
<div class="VScrollTable">
<table id="myTable" class="table table-fixed table-responsive" align="left" cellspacing="0">
<thead>
<tr>
<th>UserCode</th>
<th>SalesmanName</th>
<th>Date</th>
<th>ItemCode</th>
<th>ItemDescription</th>
<th>BrandCode</th>
<th>BrandName</th>
<th>ClientCode</th>
<th>Client</th>
<th>ClientBranchCode</th>
<th>Description</th>
<th>BranchSubChannel</th>
<th>TransactionAmount</th>
<th>Quantity</th>
</tr>
</thead>
#for (int i = 0; i < Model.SalesDataModelItems.Count; i++)
{
<tbody>
<tr>
<td>#Model.SalesDataModelItems[i].UserCode</td>
<td>#Model.SalesDataModelItems[i].SalesManName</td>
<td>#Model.SalesDataModelItems[i].SaleDate</td>
<td>#Model.SalesDataModelItems[i].ItemCode</td>
<td>#Model.SalesDataModelItems[i].ItemDescription</td>
<td>#Model.SalesDataModelItems[i].BrandCode</td>
<td>#Model.SalesDataModelItems[i].BrandName</td>
<td>#Model.SalesDataModelItems[i].ClientCode</td>
<td>#Model.SalesDataModelItems[i].ClientName</td>
<td>#Model.SalesDataModelItems[i].ClientBranchCode</td>
<td>#Model.SalesDataModelItems[i].Description</td>
<td>#Model.SalesDataModelItems[i].BranchSubChannel</td>
<td>#Model.SalesDataModelItems[i].TrxAmount</td>
<td>#Model.SalesDataModelItems[i].Quantity</td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].UserCode) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].SalesManName) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].SaleDate) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].ItemCode) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].ItemDescription) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].BrandCode) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].BrandName) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].ClientCode) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].ClientName) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].ClientBranchCode) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].Description) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].BranchSubChannel) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].TrxAmount) </td>
<td>#Html.HiddenFor(model => model.SalesDataModelItems[i].Quantity) </td>
</tr>
</tbody>
}
</table>
</div>
</div>
</div>
</div>
}
</div>
}
</div>
</div>
And like Tetsuya Yamamoto pointed out, avoid mixing asp web forms controls in asp.net MVC application
EDIT (After Maria comments) :
You can add an ajax call to save the data in excel on button press :
Controller Savereport method :
public ActionResult SaveReport()
{
try
{
// Get data from DB and save it in excel
return Json("Success save report");
}
catch (Exception ex)
{
return Json("Save report failure!" + ex.Message);
}
}
View :
#model MVCWebApplication.Controllers.SalesParentViewModel
#{
ViewBag.Title = "Sales Report";
}
#section scripts{
<link rel="stylesheet"
href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.min.css">
<script type="text/javascript"
src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript"
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
}
<div class="container-fluid">
<div class="row">
<div class="col-sm-9">
<h1>Sales Report</h1>
</div>
</div>
<div>
<input id="btnSave" type="button" class="btn btn-sm btn-info" data-url="#Url.Action("SaveReport","App")" value="Save" />
<div class="form-group">
#if (Model.SalesDataModelItems != null)
{
<div class="container" style="background-color:lavender;">
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h2>Report</h2>
</div>
<div class="VScrollTable">
<table id="myTable" class="table table-fixed table-responsive" align="left" cellspacing="0">
<thead>
<tr>
<th>UserCode</th>
<th>SalesmanName</th>
<th>Date</th>
<th>ItemCode</th>
<th>ItemDescription</th>
<th>BrandCode</th>
<th>BrandName</th>
<th>ClientCode</th>
<th>Client</th>
<th>ClientBranchCode</th>
<th>Description</th>
<th>BranchSubChannel</th>
<th>TransactionAmount</th>
<th>Quantity</th>
</tr>
</thead>
#foreach (var item in Model.SalesDataModelItems)
{
<tbody>
<tr>
<td>#item.UserCode</td>
<td>#item.SalesManName</td>
<td>#item.SaleDate</td>
<td>#item.ItemCode</td>
<td>#item.ItemDescription</td>
<td>#item.BrandCode</td>
<td>#item.BrandName</td>
<td>#item.ClientCode</td>
<td>#item.ClientName</td>
<td>#item.ClientBranchCode</td>
<td>#item.Description</td>
<td>#item.BranchSubChannel</td>
<td>#item.TrxAmount</td>
<td>#item.Quantity</td>
</tr>
</tbody>
}
</table>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
<script>
$(function () {
$('#btnSave').on('click', function () {
$.ajax({
url: $(this).data('url'),
type: 'post',
datatype: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
console.log(data);
},
error: function (xhr) {
console.log(JSON.parse(xhr.responseText));
}
});
});
});
</script>

Related

Add object to model list from a form ASP.NET Core Razor View

I hope some can help me with this.
I have a list within a model and I want to add objects to that list using a form in a razor view before I save it to a database
This is the model that I have:
public class ActivityForm
{
public string Name { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int Points { get; set; }
public List<Award> Awards { get; set; }
}
This is the code for my view:
#model ActivityForm
#{
ViewData["Title"] = "Activity Details";
}
<section class="my-sm-5">
<div class="container">
<div class="section-header d-flex mb-5">
<h1 class="h-02 flex-grow-1">Activity Details</h1>
</div>
<div class="row">
<div class="col-md-7">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Form</h1>
</div>
<form id="form" class="row g-3 w-90" asp-action="Create">
<div class="col-md-12">
<label asp-for="Name" class="form-label">#Html.DisplayNameFor(model => model.Name)</label>
<input asp-for="Name" type="text" class="form-control" id="inputEmail4"
placeholder="#Html.DisplayNameFor(model => model.Name)">
<span asp-validation-for="Name" class="invalid-feedback"></span>
</div>
<div class="col-12">
<label asp-for="Description" class="form-label">#Html.DisplayNameFor(model =>
model.Description)</label>
<textarea asp-for="Description" class="form-control" id="exampleFormControlTextarea1" rows="5"
placeholder="#Html.DisplayNameFor(model => model.Description)"></textarea>
<span asp-validation-for="Description" class="invalid-feedback"></span>
</div>
<div class="col-md-4">
<label asp-for="StartDate" class="form-label">#Html.DisplayNameFor(model =>
model.StartDate)</label>
<input asp-for="StartDate" type="date" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.StartDate)">
<span asp-validation-for="StartDate" class="invalid-feedback"></span>
</div>
<div class="col-md-4">
<label asp-for="EndDate" class="form-label">#Html.DisplayNameFor(model => model.EndDate)</label>
<input asp-for="EndDate" type="date" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.EndDate)">
<span asp-validation-for="EndDate" class="invalid-feedback"></span>
</div>
<div class="col-md-4 mb-6">
<label asp-for="Points" class="form-label">#Html.DisplayNameFor(model => model.Points)</label>
<input asp-for="Points" type="number" class="form-control"
placeholder="#Html.DisplayNameFor(model => model.Points)">
<span asp-validation-for="Points" class="invalid-feedback"></span>
</div>
<div class="col-8 d-grid gap-2">
<a class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#add-award">Add award</a>
<div class="row">
<div class="col-md-6">
<a class="btn btn-outline-primary w-100" data-bs-toggle="modal"
data-bs-target="#cancel-activity">Cancel</a>
</div>
<div class="col-md-6">
<a class="btn btn-outline-primary w-100" data-bs-toggle="modal"
data-bs-target="#post-activity">Post Activity</a>
</div>
</div>
</div>
</form>
</div>
<div class="col-md-5">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Awards</h1>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Award name</th>
<th scope="col">Description</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < 1; i++)
{
<tr>
<td>Award Name</td>
<td>Award Description</td>
<td>
<a class="btn btn-outline-primary btn-sm">Edit</a>
<a class="btn btn-outline-primary btn-sm">Remove</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</section>
<div class="modal" id="add-award" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content br-20 pd-20">
<div class="modal-header justify-content-center">
<h5 class="modal-title h-04 text-prim-color">Award details</h5>
</div>
<form class="row g-3">
<div class="modal-body">
<div class="row g-3">
<div class="col-md-12">
<label asp-for="Award.Name" class="form-label">Name</label>
<input asp-for="Award.Name" type="text" class="form-control" id="inputEmail4">
</div>
<div class="col-12">
<label asp-for="Award.Description" for="inputAddress" class="form-label">Description</label>
<textarea asp-for="Award.Description" class="form-control" id="exampleFormControlTextarea1" rows="5"></textarea>
</div>
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="button" class="btn btn-outline-primary w-100" data-bs-dismiss="modal">Close</button>
<input class="btn btn-primary w-100" type="submit" value="Confirm"></input>
</div>
</form>
</div>
</div>
</div>
My form is within a modal and when I click the submit button I want to create an Award object with the values from the form. After the object is created I want to add it to the Awards List and have the changes reflect on the view.
This is what the View looks like:
View with modal
And this is how it will look like after the object has been added:
View after object is added
You should first fix some issues:
Right now your form does not have a binding for the ActivityForm.Awards property. You should change:
<tbody>
#for (int i = 0; i < 1; i++)
{
<tr>
<td>Award Name</td>
<td>Award Description</td>
<td>
<a class="btn btn-outline-primary btn-sm">Edit</a>
<a class="btn btn-outline-primary btn-sm">Remove</a>
</td>
</tr>
}
</tbody>
To:
<tbody>
#for (var i = 0; i < Model.Awards.Count; i++)
{
<input type="hidden" asp-for="#Model.Awards[i].Name" />
<input type="hidden" asp-for="#Model.Awards[i].Description" />
<tr>
<td>#Model.Awards[i].Name</td>
<td>#Model.Awards[i].Description</td>
<td>
<a class="btn btn-outline-primary btn-sm">Edit</a>
<a class="btn btn-outline-primary btn-sm">Remove</a>
</td>
</tr>
}
</tbody>
Documentation for binding model to a collection: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#collections-1
Your form should wrap around both Form and Awards sections:
<form id="form" class="row g-3 w-90" asp-action="Create">
<div class="col-md-7">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Form</h1>
</div>
...
</div>
<div class="col-md-5">
<div class="section-header d-flex mb-5">
<h1 class="h-04 flex-grow-1">Awards</h1>
</div>
...
</div>
</form>
You should also change:
<a class="btn btn-outline-primary w-100" data-bs-toggle="modal" data-bs-target="#post-activity">Post Activity</a>
to an actual submit button:
<button type="submit" class="btn btn-outline-primary w-100">Post Activity</button>
Now if you manually add some awards to the Awards list from your Controller,
return View(new ActivityForm
{
Awards = new List<Award>
{
new Award { Name = "Name", Description = "Descr" },
new Award { Name = "Award 2", Description = "Descr 2" }
}
});
the awards will be displayed properly and also when you submit the form the ActivityForm.Awards list will be populated with the awards you added manually.
These issues need to be fixed before you go on and implement the add award form inside the modal.

FindAsync(id); doesn't update on screen, only when I refresh the URL

I started to learn some basic c# and im trying to find my way into ASP.net
I am running the following code with some help from this video: https://www.youtube.com/watch?v=C5cnZ-gZy2I (time stamp: 1 hour and 50min)
public class BestellenModel : PageModel
{
private ApplicationDbContext _db;
public BestellenModel(ApplicationDbContext db)
{
_db = db;
}
[BindProperty]
public Bedrijven Bedrijven { get; set; }
public async Task OnGet(int id)
{
Bedrijven = await _db.Bedrijven.FindAsync(id);
}
}
}
In the video whenever the edit button is pressed the right data from the data base appears on screen. For me nothing appears but whenever i click on my url and hit enter again the data appears.
I tried the debug option within VS and i saw that the line FindAsync doesn't run when hitting the button. But when i click enter on the url then it runs the code. My url looks like this: https://localhost:7005/Bedrijfslijst/Bestellen?id=32
Can anyone tell me what i am missing here? because i am a bit stuck.
Edit:
Now whenever the client Clicks on the "kopen" button it needs to render the data from the db to the fields.
This is a screenshot from the yt video, its supposed to show the data when the page is loaded. For me its not loading but whenever i click on the url and hit enter then the db data will load in.
cshtml script:
#page
#model test1v1.Pages.Bedrijfslijst.BestellenModel
<br />
<h2 class="text-primary">Rapport bestellen</h2>
<br />
<div class="border container" style="padding:120px;">
<form method="post">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<div class="form-group row" style="padding:10px;">
<div class="col-4">
<label asp-for="Bedrijven.Kvk"></label>
</div>
<div class="col-4">
<input asp-for="Bedrijven.Kvk" class="form-control" />
</div>
<span asp-validation-for="Bedrijven.Kvk" class="text-danger"></span>
</div>
<div class="form-group row" style="padding:10px;">
<div class="col-4">
<label asp-for="Bedrijven.Bedrijfsnaam"></label>
</div>
<div class="col-4">
<input asp-for="Bedrijven.Bedrijfsnaam" class="form-control" />
</div>
<span asp-validation-for="Bedrijven.Bedrijfsnaam" class="text-danger"></span>
</div>
<div class="form-group row" style="padding:10px;">
<div class="col-4">
<label asp-for="Bedrijven.Adres"></label>
</div>
<div class="col-4">
<input asp-for="Bedrijven.Adres" class="form-control" />
</div>
<span asp-validation-for="Bedrijven.Adres" class="text-danger"></span>
</div>
<div class="form-group row" style="padding:10px;">
<div class="col-3 offset-4">
<input type ="submit" value="Bestellen" class="btn btn-success form-control" />
</div>
<div class="col-3">
<a asp-page="index" class="btn btn-primary form-control">Terug</a>
</div>
</div>
</form>
</div>
#section Scripts{
<partial name ="_ValidationScriptsPartial"/>
}
Edit2:
#page
#model test1v1.Pages.Bedrijfslijst.IndexModel
<br />
<div class="container row p-0 m-0">
<div class="col-9">
<h2 class="text-primary">Bedrijf Lijst</h2>
</div>
<div class="col-3">
<a asp-page="Zoeken" class="btn btn-primary form-control text-white">Bedrijf Zoeken</a>
</div>
<div class= "col-10 border p-4 mt-4">
<form method="post">
#if (Model.Bedrijven.Count() > 0)
{
<table class="table table-striped border">
<tr class="table-secondary">
<th>
<label asp-for="Bedrijven.FirstOrDefault().Kvk"></label>
</th>
<th>
#*#Html.DisplayNameFor(m=>m.Books.FirstOrDefault().Author)*#
<label asp-for="Bedrijven.FirstOrDefault().Bedrijfsnaam"></label>
</th>
<th>
<label asp-for="Bedrijven.FirstOrDefault().Adres"></label>
</th>
<th>
</th>
</tr>
#foreach (var item in Model.Bedrijven)
{
<tr>
<td>
#Html.DisplayFor(m=>item.Bedrijfsnaam)
</td>
<td>
#Html.DisplayFor(m=>item.Kvk)
</td>
<td>
#Html.DisplayFor(m=>item.Adres)
</td>
<td>
<button asp-page="Bestellen" asp-route-id="#item.Id" class="btn btn-primary btn-sm">Kopen</button>
</td>
</tr>
}
</table>
}
else
{
<p>Geen Bedrijven Gevonden.</p>
}
</form>
</div>
</div>

Checkbox always show False either it is True

I am try to understand what happened with checkbox status. So I have Create Page where I insert Patient
and when I click Emergency to True in Index Page I always get False
IndexPage.cshtml
#if (Model.Count() > 0)
{
<table class="table table-bordered table-striped" style="width:100%">
<thead>
<tr>
<th>
Doctor Full Name - CODE
</th>
<th>
Patient Full Name
</th>
<th>
Date and Time
</th>
<th>
Emergency
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var obj in Model)
{
<tr>
<td width="25%">#obj.Doctor.Firstname #obj.Doctor.Lastname #obj.Doctor.Code</td>
<td width="25%">#obj.Patient.FirstName #obj.Patient.LastName</td>
<td width="25%">#obj.DateAndTime</td>
<td width="25%" class="blink_me">#obj.Emergency</td>
<td class="text-center">
<div class="w-75 btn-group" role="group">
<a asp-route-Id="#obj.Id" asp-action="Upsert" class="btn btn-primary mx-2">
<i class="fas fa-edit"></i>
</a>
<a asp-route-Id="#obj.Id" asp-action="Delete" class="btn btn-danger mx-2">
<i class="far fa-trash-alt"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p> No Admission Patient exists.</p>
}
Create
#model BergClinics.Models.ViewModel.AdmisionVM
#{
ViewData["Title"] = "Upsert";
var title = "Create Admission Patient";
}
<form method="post" enctype="multipart/form-data">
#if (Model.AdmissionPatient.Id != 0)
{
<input asp-for="AdmissionPatient.Id" hidden />
title = "Edit Admission Patient";
}
<div class="border p-3">
<div class="form-group row">
<h2 class="text-info pl-3">#title</h2>
</div>
<div class="row">
<div class="col-8">
<div class="form-group row py-2">
<div class="col-4">
<label>Doctor Full Name : </label>
</div>
<div class="col-8">
<select asp-for="AdmissionPatient.DoctorId" asp-items="#Model.DoctorSelectList" class="form-control">
<option disabled selected>--Select Docotor--</option>
</select>
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Patient Full Name: </label>
</div>
<div class="col-8">
<select asp-for="AdmissionPatient.PatientId" asp-items="#Model.PatientSelectList" class="form-control">
<option disabled selected>--Select Patient--</option>
</select>
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Date and Time :</label>
</div>
<div class="col-8">
<input asp-for="AdmissionPatient.DateAndTime" asp-format="{0:dd/MM/yyyy}" type="text" name="date" class="form-control datepicker" autocomplete="off">
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Patient Image :</label>
</div>
<div class="col-3">
<input type="file" name="files" id="imageBox" multiple class="form-control" />
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Emergency reception :</label>
</div>
<div class="col-8">
<input type="checkbox" class="form-control" id="emergencyId">
<label class="form-check-label" for="exampleCheck1"></label>
</div>
</div>
<div class="form-group row py-2">
<div class="col-8 offset-4 row">
<div class="col">
#if (Model.AdmissionPatient.Id != 0)
{
//update
<input type="submit" class="btn btn-info w-100" value="Update" />
}
else
{
//create
<input type="submit" onclick="return validateInput()" class="btn btn-primary w-100" value="Create" />
}
</div>
</div>
</div>
</div>
<div class="col-4">
#if (Model.AdmissionPatient.Id != 0)
{
<img src="#Constans.imagePath#Model.AdmissionPatient.Image" width="100%" style="border-radius:5px; border:1px solid #bbb" />
}
</div>
</div>
</div>
</form>
#section Scripts{
#{
<partial name="_ValidationScriptsPartial" />
}
<script>
function validateInput() {
if (document.getElementById("imageBox").value == "") {
Swal.fire(
'Error!',
'Please upload an Image!',
'error'
)
return false;
}
return true;
}
</script>
<script>
$('.datepicker').datepicker({
startDate: new Date()
});
</script>
}
Controller Post Action
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(AdmisionVM admissionVM)
{
if (ModelState.IsValid)
{
var files = HttpContext.Request.Form.Files;
string webRootPath = _webHostEnvironment.WebRootPath;
if (admissionVM.AdmissionPatient.Id == 0)
{
//Creating
string upload = webRootPath + Constans.imagePath;
string fileName = Guid.NewGuid().ToString();
string extension = Path.GetExtension(files[0].FileName);
using (var fileStream = new FileStream(Path.Combine(upload, fileName + extension), FileMode.Create))
{
files[0].CopyTo(fileStream);
}
admissionVM.AdmissionPatient.Image = fileName + extension;
_db.AdmissionPacients.Add(admissionVM.AdmissionPatient);
}
else
{
//Updating
var objFromDb = _db.AdmissionPacients.AsNoTracking().FirstOrDefault(u => u.Id == admissionVM.AdmissionPatient.Id);
if (files.Count > 0)
{
string upload = webRootPath + Constans.imagePath;
string fileName = Guid.NewGuid().ToString();
string extension = Path.GetExtension(files[0].FileName);
var oldFile = Path.Combine(upload, objFromDb.Image);
if (System.IO.File.Exists(oldFile))
{
System.IO.File.Delete(oldFile);
}
using (var fileStream = new FileStream(Path.Combine(upload, fileName + extension), FileMode.Create))
{
files[0].CopyTo(fileStream);
}
admissionVM.AdmissionPatient.Image = fileName + extension;
}
else
{
admissionVM.AdmissionPatient.Image = objFromDb.Image;
}
_db.AdmissionPacients.Update(admissionVM.AdmissionPatient);
}
_db.SaveChanges();
return RedirectToAction("Index");
}
admissionVM.PatientSelectList = _db.Patients.Select(i => new SelectListItem
{
Text = i.FirstName + i.LastName,
Value = i.Id.ToString()
});
admissionVM.DoctorSelectList = _db.Doctors.Select(i => new SelectListItem
{
Text = i.Firstname + i.Lastname,
Value = i.Id.ToString()
});
return View(admissionVM);
}
try add name to this line:
<input type="checkbox" class="form-control" id="emergencyId">
to
<input name="Emergency" type="checkbox" class="form-control" id="emergencyId">

Partial view button submit not call httpost, call a action to view

view :
<div id="ReportChange">
#{
ViewDataDictionary vDataDictonary = new ViewDataDictionary();
vDataDictonary.Add(new KeyValuePair<string, object>("ReportType", ViewData["ReportType"]));
vDataDictonary.Add(new KeyValuePair<string,object>("Agencias", ViewData["Agencias"]));
vDataDictonary.Add(new KeyValuePair<string, object>("SendType", ViewData["SendType"]));
vDataDictonary.Add(new KeyValuePair<string, object>("OrderStatus", ViewData["OrderStatus"]));
vDataDictonary.Add(new KeyValuePair<string, object>("User", ViewData["User"]));
vDataDictonary.Add(new KeyValuePair<string, object>("ServicesType", ViewData["ServicesType"]));
if (Model.report == null){
Html.RenderPartial("getReport", new ReportSchedule() { StartDate = DateTime.Now, EndDate=DateTime.Now}, vDataDictonary);
}
else {
Html.RenderPartial("getReport", Model.report, vDataDictonary);
}
}
#if (Model.lReport.Count() == 0)
{
<h4 class="alert alert-danger text-center">Error.</h4>
}
else
{
<div class="container-fluid container-fixed-lg bg-white" id="viewform">
<div class="panel panel-transparent">
<div class="panel-heading">
<div class="panel-title"></div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<table class="table table-hover demo-table-search" id="tableWithSearch">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.lReport)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.ReportType.Description)</td>
<td>#(item.EndDate.HasValue ? String.Concat(item.StartDate.ToString("dd/MM/yyyy"), " - ", item.EndDate.Value.ToString("dd/MM/yyyy")) : item.StartDate.ToString("dd/MM/yyyy"))</td>
<td>#item.StartDate - #item.EndTime </td>
<td>#Html.DisplayFor(modelItem=> item.Agency.CorporateName) </td>
<td>#Html.DisplayFor(modelItem=> item.CostCenter.Description)</td>
<td>#Html.DisplayFor(modelItem=> item.User.Name )</td>
<td>#Html.DisplayFor(modelItem=>item.OrderStatus.Description ) </td>
<td>#Html.DisplayFor(modelItem=> item.ServiceType.Description ) </td>
<td>#Html.CheckBox("A", #item.Live.Equals(0) ? false : true, new {disabled="readonly" })</td>
<td class="v-align-middle">
<div class="btn-group">
<input type="button" class="btn btn-info btn-sm" id="#item.ReportScheduleID" onclick="getReport(this.id)" />
#Html.ActionLink(item.Live ? "D" : "A", "Live", new { id = item.CostCenterID }, new { #class ="btn btn-danger btn-sm buttonLive" })
</div>
</td>
</tr>
}
</tbody>
</table>
<div class="row"> </div>
</div>
</div>
</div>
}
My partial view :
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<form id="frm" class="form-horizontal well">
#if (Model.AgencyID.Equals(0))
{
using (Html.BeginForm("getReport", "ReportSchedules"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(_ => _.ReportScheduleID)
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-md-1">Relatório</label>
#Html.DropDownListFor(m=>m.ReportTypeID,(SelectList) ViewData["ReportType"],"Atendimento por Agência")
#Html.ValidationMessageFor(m=>m.ReportTypeID)
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-md-1">Início</label>
<input type="text" id="date" name="date" class="col-md-2 smallDate" value="#Model.StartDate.ToShortDateString()"/>
#Html.ValidationMessageFor(m=>m.StartDate)
#Html.TextBoxFor(m=>m.StartTime,new {#class="col-md-1 smallDateMargin"})
#Html.ValidationMessageFor(m => m.StartTime)
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-md-1">Periodicidade</label>
#Html.DropDownListFor(m=>m.SendTypeID,(SelectList) ViewData["SendType"],"Selecione")
#Html.ValidationMessageFor(m=>m.SendTypeID)
</div>
</div>
<div class="col-md-10">
<h6>Configurações avançadas<a data-toggle="tooltip" class="tooltipLink" data-original-title="Data até quando o relatório será enviado.">
<span class="glyphicon glyphicon-question-sign"></span>
</a></h6>
<div class="form-group" style="border: 1px dashed #ccc;">
<div class="form-group">
<label class="control-label col-md-1">
<input type="checkbox" name="dateEndSelected" id="dateEndSelected" value="#Model.Live"/> Fim</label>
<input type="text" id="dataFinalSelected" name="dataFinalSelected" style="display:none;" value="false"/>
<input type="text" id="dateFinal" name="dateFinal" style="display:none;"class="col-md-2 smallDate" value="#Model.EndDate.Value.ToShortDateString()"/>
#Html.TextBoxFor(m=>m.EndTime,new {#class="col-md-1 smallDateMargin"})
#Html.ValidationMessageFor(m=>m.EndTime)
</div>
</div>
</div>
<div class="col-md-10">
<h6>Filtrar por:</h6>
<div class="form-group" style="border: 1px dashed #ccc;">
<div class="col-md-10">
#Html.DropDownListFor(m=>m.AgencyID, (SelectList) ViewData["Agencias"],"Agências",new {#class="col-md-1",id="agencia",name="agencia"})
#Html.ValidationMessageFor(m => m.AgencyID)
#Html.DropDownListFor(m=>m.OrderStatusID, (SelectList) ViewData["OrderStatus"],"Status",new {#class="col-md-2"})
#Html.ValidationMessageFor(m=>m.OrderStatusID)
#Html.DropDownListFor(m=>m.UserID, (SelectList) ViewData["User"],"Usuários",new {#class="col-md-3"})
#Html.ValidationMessageFor(m=>m.UserID)
</div>
<div class="col-md-10">
#Html.DropDownList("dpdCostCenter", new List<SelectListItem>(), "Selecione", new { #class = "col-md-1" })
#Html.DropDownListFor(m=>m.ServiceTypeID,(SelectList) ViewData["ServicesType"],"Tipos de atendimento",new {#class="col-md-2"})
#Html.ValidationMessageFor(m=>m.ServiceTypeID)
</div>
</div>
</div>
<div class="col-md-10">
<div class="form-group">
<div class="input-group pull-right marginTopBot-sm input-group-sm" style="padding-left: 5px;">
<input type="submit" value="Agendar o envio" class="btn btn-success" onclick="$('#getResponse').submit()" />
</div>
</div>
</div>
</div>
}
}
else
But if i click in button submit it goes to the index action of view
public ActionResult Index()
And not to :
[HTTPPOST]
public ActionResult getReport(ReportSchedule model)
{
if (ModelState.IsValid)
{
db.ReportSchedule.Add(model);
db.SaveChanges();
}
else
{
return PartialView(model);
}
return RedirectToAction("Index");
}
But i need submit button call getReport to validate a model and save in db
You have nested forms which are invalid html and not supported. Remove the outer form tag from the partial (including the AntiForgeryToken and ValidationSummary above it
<form id="frm" class="form-horizontal well"> // remove this and its corresponding closing tag

Multiple forms on a single MVC page

Below is a screenshot of my page. It has 3 tabs - Details, Users and Rights. Each tab has its own submit button which I need to fire different code within the controller (of which there is no code as of yet).
My question is, how to I have 3 separate forms on a single MVC page and how do I get each Submit button to run the respective code?
View
<div class="row-fluid">
<div class="span12">
<!-- BEGIN INLINE TABS PORTLET-->
<div class="widget">
<div class="widget-title">
<h4><i class="icon-user"></i></h4>
</div>
<div class="widget-body">
<div class="row-fluid">
<div class="span8">
<!--BEGIN TABS-->
<div class="tabbable custom-tab">
<ul class="nav nav-tabs">
<li class="active">Role Details</li>
<li>Users</li>
<li>Rights</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1_1">
#using (Html.BeginForm("Details", "RoleController", FormMethod.Get, new { }))
{
#Html.ValidationSummary(true)
<div class="row-fluid">
<div class="span3">
#Html.HiddenFor(model => model.Id)
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.RoleName)</label>
<div class="controls controls-row">
#Html.EditorFor(model => model.RoleName)
#Html.ValidationMessageFor(model => model.RoleName)
</div>
</div>
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.Description)</label>
<div class="controls controls-row">
#Html.TextArea("Description", Model.Description, new { #cols = 400, #rows = 10 })
</div>
</div>
</div>
</div>
<input type="submit" class="btn btn-success" value="Save" />
}
</div>
<div class="tab-pane" id="tab_1_2">
#using (Html.BeginForm("UsersForRole", "RoleController", FormMethod.Post, new { }))
{
<!-- BEGIN DUAL SELECT-->
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTk5MjI0ODUwOWRkJySmk0TGHOhSY+d9BU9NHeCKW6o=" />
</div>
<div>
<table style="width: 100%;" class="">
<tr>
<td style="width: 35%">
<div class="d-sel-filter">
<span>Filter:</span>
<input type="text" id="box1Filter" />
<button type="button" class="btn" id="box1Clear">X</button>
</div>
<select id="box1View" multiple="multiple" style="height: 300px; width: 75%" runat="server">
</select><br />
<span id="box1Counter" class="countLabel"></span>
<select id="box1Storage">
</select>
</td>
<td style="width: 21%; vertical-align: middle">
<button id="to2" class="btn" type="button"> > </button>
<button id="allTo2" class="btn" type="button"> >> </button>
<button id="allTo1" class="btn" type="button"> << </button>
<button id="to1" class="btn" type="button"> < </button>
</td>
<td style="width: 35%">
<div class="d-sel-filter">
<span>Filter:</span>
<input type="text" id="box2Filter" />
<button type="button" class="btn" id="box2Clear">X</button>
</div>
<select id="box2View" multiple="multiple" style="height: 300px; width: 75%;">
#foreach (var user in Model.Users)
{
<option>#Html.DisplayFor(model => user.SurnameFirstName)</option>
}
</select><br />
<span id="box2Counter" class="countLabel"></span>
<select id="box2Storage">
</select>
</td>
</tr>
</table>
</div>
<div class="mtop20">
<input type="submit" value="Submit" class="btn" />
</div>
<!-- END DUAL SELECT-->
}
</div>
<div class="tab-pane" id="tab_1_3">
#using (Html.BeginForm("RightsForRole", "RoleController", FormMethod.Post, new { }))
{
<table class="table table-striped">
<thead>
<tr>
<th>Right Name</th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var right in Model.Rights)
{
<tr>
<td>#Html.DisplayFor(model => right.RightName)</td>
<td>#Html.DisplayFor(model => right.Description)</td>
<td>
<div class="success-toggle-button">
#Html.CheckBoxFor(model => right.Assigned, new { #class = "toggle" })
</div>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
</div>
<!--END TABS-->
</div>
<div class="span4">
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.DateCreated)</label>
<div class="controls controls-row">
#Html.EditorFor(model => model.DateCreated, new { #readonly = "readonly" })
</div>
</div>
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.CreatedBy)</label>
<div class="controls controls-row">
#Html.EditorFor(model => model.CreatedBy, new { #readonly = "readonly" })
</div>
</div>
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.LastUpdated)</label>
<div class="controls controls-row">
#Html.EditorFor(model => model.LastUpdated)
</div>
</div>
<div class="control-group">
<label class="control-label">#Html.DisplayNameFor(model => model.LastUpdateBy)</label>
<div class="controls controls-row">
#Html.EditorFor(model => model.LastUpdateBy)
</div>
</div>
</div>
</div>
</div>
</div>
</div>
UsersForRole controller
[HttpPost]
public ActionResult UsersForRole(RoleModel model)
{
if (ModelState.IsValid)
{
}
return View(model);
}
I think that you may have something wrong in this line:
#using (Html.BeginForm("UsersForRole", "RoleController", FormMethod.Post, new { }))
Controler name in the Html.BeginForm shoudl be only Role unless your controller name is`RoleControllerController?
What you are doing looks fine, you just need to add the other Actions in your controller...
Details
RightsForRole
I think you should use Partial Views.
You can achieved the multiple form inside one form by only using three different Pages(Actions) and use tab as Actionlink. On the Actionlink you call the respective Action.
In your case there will be problem when you will post the form.
Otherwise you should use JQuery to achieve this situation.

Categories

Resources