iTextSharp generate pdf, data is not picked up from - asp.net-mvc

I am requesting data from Azure SQL to be grouped by item and description,then count the quantity.
It is showing correctly on the website with check boxes, but when generate PDF button is pressed it is showing me full list, instead individual items.
This is where I got just to show me group list. I have tried with individual checkbox items, but it is coming back with blank PDF. So, somewhere in code I need to add code where generate pdf understand the group items, instead of individual IDs.
This is my index view and controller:
#model IEnumerable<InventorBOMDelete.Models.InventorBOM1>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.JOB)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Qty)
</th>
<th>
#Html.DisplayNameFor(model => model.StockNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.JOB)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Qty)
</td>
<td>
#Html.DisplayFor(modelItem => item.StockNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
<input type="checkbox" name="selectedIds" value="#item.ID" />
</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-primary" id="generatePdfBtn">GeneratePDF</button>
#section Scripts {
<script>
$(document).ready(function () {
$('#generatePdfBtn').click(function () {
var selectedIds = [];
$('input[name="selectedIds"]:checked').each(function () {
selectedIds.push($(this).val());
});
if (selectedIds.length === 0) {
alert('Please select at least one item to generate the PDF.');
return;
}
// window.location.href = "/InventorBOM1/GeneratePdf?selectedIds=" + selectedIds.join(',');
window.location.href = "/Customer/GeneratePdf?selectedIds=" + selectedIds.join(', ');
});
});
</script>
}
using InventorBOMDelete.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using static InventorBOM.Controllers.CustomerController;
namespace InventorBOM.Controllers
{
public class CustomerController : Controller
{
private Aspire302Entities1 db = new Aspire302Entities1();
public ActionResult Index()
{
List<InventorBOM1> inventorBOMList = new List<InventorBOM1>();
using (Aspire302Entities1 dc = new Aspire302Entities1())
{
var inventorBOM = dc.InventorBOM1.Where(i => i.Qty == i.Qty)
.GroupBy(i => new { i.JOB, i.Description })
.Select(g => new { JOB = g.Key.JOB, Description = g.Key.Description, Qty = g.Count() });
foreach (var item in inventorBOM)
{
inventorBOMList.Add(new InventorBOM1()
{
JOB = item.JOB,
Description = item.Description,
Qty = item.Qty
});
}
}
return View(inventorBOMList);
}
public ActionResult GeneratePDF(string[] selectedIds)
{
List<InventorBOM1> inventorBOMList = new List<InventorBOM1>();
using (Aspire302Entities1 dc = new Aspire302Entities1())
{
var inventorBOM = dc.InventorBOM1.Where(i => i.Qty == i.Qty)
.GroupBy(i => new { i.JOB, i.Description })
.Select(g => new { JOB = g.Key.JOB, Description = g.Key.Description, Qty = g.Count() });
foreach (var item in inventorBOM)
{
inventorBOMList.Add(new InventorBOM1()
{
JOB = item.JOB,
Description = item.Description,
Qty = item.Qty
});
}
}
// Create the PDF document
using (MemoryStream stream = new MemoryStream())
{
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
PdfWriter.GetInstance(pdfDoc, stream);
pdfDoc.Open();
// Add the table to the PDF document
PdfPTable table = new PdfPTable(3);
table.WidthPercentage = 100;
table.SetWidths(new float[] { 20f, 60f, 20f });
table.AddCell("JOB");
table.AddCell("Description");
table.AddCell("Qty");
foreach (var inventor in inventorBOMList)
{
table.AddCell(inventor.JOB);
table.AddCell(inventor.Description);
table.AddCell(inventor.Qty.ToString());
}
pdfDoc.Add(table);
pdfDoc.Close();
return File(stream.ToArray(), "application/pdf", "InventorBOM.pdf");
}
}
}
}

Related

.NET MVC JQuery function is not getting fired in table row click event

I have table data in UI. I want to display data in a div in the same page when I click the Details link in the row. The JQuery function is not getting fired in when I click on details link in any row.
Below is my code:
Model view class:
public class ItemViewModel
{
public Item item { get; set; }
public IEnumerable<Item> items { get; set; }
}
UI Code:
#model Medhub.Models.ItemViewModel
#{
ViewBag.Title = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View</h2>
<p>
#Html.ActionLink("Create New", "CreateEdit", new { controller = "Item" }, new { #class = "btn btn-primary" })
</p>
<table align="center" height="10%" width="90%">
<tr>
<td>
<div id="Items">
<table style="vertical-align:top; height:200px" width="100%">
<tr style="height:20px">
<th>
#Html.DisplayName("Name")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th>
#Html.DisplayName("Item Type")
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.items)
{
<tr style="height:15px">
<td>
#Html.HiddenFor(model => item.ItemId)
#Html.DisplayFor(model => item.Name)
</td>
<td>
#Html.DisplayFor(model => item.Description)
</td>
<td>
#Html.DisplayFor(model => item.Type)
</td>
<td>
#Html.ActionLink("Edit", "CreateEdit", new { id = item.ItemId }) |
#Html.ActionLink("Details", "Item", new { id = item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ItemId })
</td>
</tr>
}
}
</table>
</div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="ItemDetails">
#if (Model.item != null)
{
Html.RenderPartial("Details", Model.item);
}
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function () {
$("div.Items a").click(function (e) {
//e.preventDefault();
var url = this.ref;
$("#ItemDetails").load(url);
});
});
</script>
Controller code:
List<Item> items = new List<Item>();
// GET: Item
public ActionResult Item(int id = 0)
{
ItemViewModel itemVM = new ItemViewModel();
itemVM.items = GetItems();
if (id > 0)
itemVM.item = itemVM.items.FirstOrDefault(u => u.ItemId == id);
return View(itemVM);
}
Any clues?
First of all, you are waiting for clicks on a class called Items. This is the reason the jquery code is not being fired. You should have
$("div#Items a").click(function (e) {
Secondly, you need to check the attribut href, not ref. Also, prevent default needs to be there, otherwise you just reload your page
e.preventDefault();
var url = this.href;
You don't need the renderpartial in the page, just leave it empty:
<div id="ItemDetails">
</div>
While your logic kind of works, the way the url is loaded causes the entire page to be loaded into the ItemDetails section. I'd suggest that in your controller, you'd create a separate method for the details:
public ActionResult Details(int id) {
Item item = GetItem(id);
return View(item);
}
private Item GetItem(int id) {
return new Item() { Details = "details here" };
}

How i can send list of data from two tables to view?

I'm work in asp mvc application database first a broach So i have two tables Employee and Branch and i need to send list to view with Employee name and branch name that's my controller code
public PartialViewResult List()
{
List<Employee> emp;
using (var contxt = new EnglisCenterEntities())
{
var query = contxt.Employee.ToList();
emp = query;
}
return PartialView(emp);
}
and my view code is
#model IEnumerable<Insert.Models.Employee>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.EmpName)
</th>
<th>
#Html.DisplayNameFor(model => model.Phone)
</th>
<th>
#Html.DisplayNameFor(model => model.Username)
</th>
<th>
#Html.DisplayNameFor(model => model.Branches.BranchName)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.EmpName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.DisplayFor(modelItem => item.Username)
</td>
<td>
#Html.DisplayFor(modelItem => item.Branches.BranchName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.IdEmp }) |
#Html.ActionLink("Details", "Details", new { id=item.IdEmp }) |
#Html.ActionLink("Delete", "Delete", new { id=item.IdEmp })
</td>
</tr>
}
But it doesn't work so how i can send branch name with employee data
Here is :
public PartialViewResult List()
{
List<Employee> emp;
using (var contxt = new EnglisCenterEntities())
{
var brands = contxt.Employee.Include("Branches").ToList();
// var query = contxt.Employee.ToList();
emp = brands;
}
return PartialView(emp);
}
Thanks guys :)

Modifying the text color and background color of a table

I no longer have a question as I figured out how to do it
Index.cshtml
#model IEnumerable<ContactManager.Models.Contacts>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2></h2>
#using (Html.BeginForm()) {
<p>#Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.Address)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.State)
</th>
<th>
#Html.DisplayNameFor(model => model.Zip)
</th>
<th>
#Html.DisplayNameFor(model => model.Phone)
</th>
<th>
Modify
</th>
</tr>
#foreach (var item in Model) {
var lncolor = "white" ;
var zipcolor = "black";
switch (item.LastName) {
case "Whited":
lncolor = "yellow";
break;
default:
lncolor = "white";
break;
}
if (item.ID % 2 == 0) {
zipcolor = "red";
} else {
zipcolor = "black";
}
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td bgcolor="#lncolor">
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td>
<font color="#txtcolor">
#Html.DisplayFor(modelItem => item.Zip)
</font>
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
Relative part of my Controller
private ContactsDBContext db = new ContactsDBContext();
// GET: Contacts
public ActionResult Index(string searchString)
{
var contacts = from c in db.Contact
select c;
if (!String.IsNullOrEmpty(searchString)) {
contacts = contacts.Where(s => s.FirstName.Contains(searchString) || s.LastName.Contains(searchString) || s.Address.Contains(searchString)
|| s.City.Contains(searchString) || s.State.Contains(searchString) || s.Zip.Contains(searchString) || s.Phone.Contains(searchString));
}
//return View(db.Contact.ToList());
return View(contacts);
}
I managed to figured out a way to accomplish what I wanted to do with this. I have updated the code as well to refelct on what I have done. I am not sure it is the most elegant way to accomplish this so if anyone has any better suggestions I am all ears.
Writing any kind of logic in view page is highly depreciated in MVC pattern. You can do it by using viewmodel. Here is the steps.
First create an appropriate view model for model contact.
public class ContactViewModel
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
public string Address{ get; set; }
public string City{ get; set; }
public string State{ get; set; }
public string Zip{ get; set; }
public string Phone{ get; set; }
public string LastNameBgcolor{ get; set; }
public string FontColor{ get; set; }
}
In controller:
private ContactsDBContext db = new ContactsDBContext();
// GET: Contacts
public ActionResult Index(string searchString)
{
var contacts = from c in db.Contact
select c;
if (!String.IsNullOrEmpty(searchString)) {
contacts = contacts.Where(s => s.FirstName.Contains(searchString) || s.LastName.Contains(searchString) || s.Address.Contains(searchString)
|| s.City.Contains(searchString) || s.State.Contains(searchString) || s.Zip.Contains(searchString) || s.Phone.Contains(searchString));
}
//return View(db.Contact.ToList());
List<ContactViewModel> ContactViewModels= new List<ContactViewModel>();
foreach(var contact in contacts){
ContactViewModel cvm= new ContactViewModel();
cvm.FirstName=contact.FirstName;
cvm.LastName=contact.LastName;
if(contact.LastName=="Whited"){
cvm.LastNameBgcolor="yellow";
}
else{
cvm.LastNameBgcolor="white";
}
cvm.Address=contact.Address;
cvm.City=contact.City;
cvm.State=contact.State;
cvm.Zip=contact.Zip;
cvm.Phone=contact.Phone;
if (contact.ID % 2 == 0) {
cvm.FontColor = "red";
} else {
cvm.FontColor = "black";
}
ContactViewModels.Add(cvm);
}
return View(ContactViewModels);
}
In view page:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td bgcolor="#model.LastNameBgcolor">
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.State)
</td>
<td>
<font color="#model.FontColor">
#Html.DisplayFor(modelItem => item.Zip)
</font>
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
Hope this will help.

Add Search Engine into MVC Music Store

i'm trying to add search the title plus genre drop down list inside store in mvc music store. here's the procedure i've done
firstly i'v added the below code into the StoreManagere controller
public ActionResult SearchIndex(string musicGenre, string searchString)
{
var GenreLST = new List<string>();
var GenreQry = from d in db.Genres
orderby d.Name
select d.Name;
GenreLST.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLST);
var musics = from m in db.Albums.Include(a => a.Genre).Include(a => a.Artist)
select m;
if (!string.IsNullOrEmpty(searchString))
{
musics = musics.Where(s => s.Title.Contains(searchString));
}
if (string.IsNullOrEmpty(musicGenre))
return View(musics);
else
{
return View(musics.Where(x => x.Genre.Name == musicGenre));
}
}
and the below code inside search index view page
#model IEnumerable<MvcMusicStore.Models.Album>
#{
ViewBag.Title = "SearchIndex";
}
<h2>SearchIndex</h2>
<p>
#Html.ActionLink("Create New", "Create")
#using (Html.BeginForm()) {
<p>Genre : #Html.DropDownList("musicGenre", "All")
Title : #Html.TextBox("searchString")
<input type="submit" value="Filetr" /></p>
}
</p>
<table>
<tr>
<th>
Genre
</th>
<th>
Artist
</th>
<th>
Title
</th>
<th>
Price
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Genre.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Artist.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
#Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
</td>
</tr>
}
</table>
but i get this error
There is no ViewData item of type 'IEnumerable' that has the key 'musicGenre'.
You saved your genre list in ViewBag.movieGenre not musicGenre. That's why it is not working.

how to get data using #Ajax.ActionLink() in ASP.net MVC

i want get data using #Ajax.ActionLink() method. i have tried in the following way
Create.chtml
function UpdatePoDetails() {
document.getElementById("poSearchbtn").href = "/MaterialReceivePO/SearchPO?searchID=" + document.getElementById('POID').value
}
#using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "searchData",
LoadingElementId = "loading"
}
))
{
<input id="POName" type="text" />
#Ajax.ActionLink("Search", "SearchPO", null, new AjaxOptions
{
UpdateTargetId = "PoDetailsDiv",
HttpMethod = "GET"
},
new
{
onclick = "UpdatePoDetails()" ,
id = "poSearchbtn"
}
)
}
#using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "MainBody",
LoadingElementId = "loading"
}))
{
<div id="PoDetailsDiv">
</div>
}
Controller method
public ActionResult SearchPO(string searchID)
{
int id = int.Parse(searchID);
List<PurchaseOrderDetailsModel> podetails = (
from c in po.GetPoListDetails(id)
select new PurchaseOrderDetailsModel()
{
PoDetailsID = c.PoDetailsID,
ItemID = c.ItemID.Value,
Quantity = c.Quantity,
UnitPrice = c.UnitPrice,
TotalPrice = c.TotalPrice,
DiscountPer = c.DiscountPer,
FinalPrice = c.FinalPrice,
CurrencyID = c.CurrencyID,
ProductID = c.ItemID.Value,
ProductName = c.ProductName,
ProductCode = c.ProductCode,
Description = c.Description
}
).ToList();
return View("SearchPO",podetails);
}
SearchPO.chtml
#model IEnumerable<ERP_Web.Areas.Inventory.Models.PurchaseOrderDetailsModel>
<table class="grid-table">
<tr>
<th>
Product Name
</th>
<th>
Code
</th>
<th>
Quantity
</th>
<th>
Unit price
</th>
<th>
Total
</th>
<th>
Discount
</th>
<th>
Final price
</th>
<th>
Receive Quantity
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ProductName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProductCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.Quantity)
</td>
<td>
#Html.DisplayFor(modelItem => item.UnitPrice)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotalPrice)
</td>
<td>
#Html.DisplayFor(modelItem => item.DiscountPer)
</td>
<td>
#Html.DisplayFor(modelItem => item.FinalPrice)
</td>
<td>
#Html.TextBox("reQuantity");
</td>
</tr>
}
</table>
the poblem is when click on the Ajax link the it goes to the Controller. the controller code executes well but at the end to does not Call the SearchPO View when returning. What is wrong in my Code or what i missing. Any help??
#Ajax.ActionLink("Search", "SearchPO", null,
new AjaxOptions{UpdateTargetId = "PoDetailsDiv",HttpMethod = "GET" },new {id = "poSearchbtn"})
I don't understand why you need this onclick = "UpdatePoDetails()"
public ActionResult SearchPO(string searchID)
{
//Do your logic here
//Build Mark-up of the result
string GeneratedMarkUp = BuildMarkUpFOrtheResult();
return Json(GeneratedMarkUp);
}

Resources