Reputation: 97
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>
Upvotes: 0
Views: 143
Reputation: 321
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>
Upvotes: 1