Showing results on table data HTML - c#

In my ASP.NET MVC web application, there is a table I have created and loads the data to the table from model.
There is a column, the data I want to show I load separately like this.
<tbody> #foreach (var item in Model.OrderByDescending(i => i.Id)) { <tr>
<td> #Html.DisplayFor(modelItem => item.Id) </td>
<td> #Html.DisplayFor(modelItem => item.ReqestTypeDisplay) </td>
<td> #Html.DisplayFor(modelItem => item.Created_Date) </td>
<td> #Html.DisplayFor(modelItem => item.Req_Heading) </td>
<td> #Company.Find(x => x.Value == item.Company_Id.ToString()).Text </td>
<td id="department">
<span data-toggle="fetch" data-url="#Url.Action(" ReqFromDepartment", "PendingRequestM" , new { id=item.Id })">Loading...</span>
</td>
<td> #Html.ActionLink("View", "View", new { id = item.Id }, new { #class = "btn btn-warning pull-right" }) <button onclick="confirmDelete(#item.Id);" , class="btn btn-danger pull-right">Reject</button>
</td>
</tr> } </tbody></table>
The script I have used after the table
< script >
window.addEventListener('DOMContentLoaded', (event) => {
document.querySelectorAll("[data-toggle='fetch']").forEach(async (el) => {
const url = el.dataset.url;
const response = await fetch(url);
if (!response.ok) {
const errorMessage = await response.text();
console.error(response.status, response.statusText, errorMessage);
el.innerHTML = "Error loading department";
return;
}
const data = await response.text();
$('#department').html(data);
});
}); <
/script>
So the issue is it gets the data and shows it, but only in the 1st row of the table. If there is more than 1 row, it searches and replaces the value From Department. How can I assign row-by-row results?

Related

Show/hide jQuery datatable action link button based upon column value

My LINQ query for retrieving data:
public ActionResult GetRegFirmList()
{
try
{
var data = (from z in db.BusinessModels
select z).OrderByDescending(z => z.BusinessKey).ToList();
return View(data);
}
catch (Exception ex) { throw; }
}
I have two action link buttons in the jQuery datatable. I need to hide the button for Certificate if the value of Status is 1 in the particular row. The action link button for Application should not be hidden. How can I do that?
<link href="~/Content/DataTables/css/dataTables.bootstrap.min.css" rel="stylesheet" />
<table id="tblBusinessData">
<thead class="table-success">
<tr>
<th>generate</th>
<th style="visibility:hidden;">
#Html.DisplayNameFor(model => model.BusinessKey)
</th>
<th>
#Html.DisplayNameFor(model => model.BusinessName)
</th>
<th>
#Html.DisplayNameFor(model => model.PropName)
</th>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
#Html.ActionLink("Application", "GenerateApplication", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
</td>
<td style="visibility:hidden;">
#Html.DisplayFor(modelItem => item.BusinessKey)
</td>
<td>
#Html.DisplayFor(modelItem => item.BusinessName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PropName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
</tr>
}
</tbody>
</table>
<script src="~/Scripts/DataTables/jquery.dataTables.min.js"></script>
<script src="~/Scripts/DataTables/dataTables.bootstrap.min.js"></script>
<script type="text/javascript">
$('#tblBusinessData').DataTable({
"columnDefs": [{
"targets": [1],
"visible": false
}],
"order": [
[1, "desc"]
]
});
</script>
You can add condition like this
#if(item.Status!=1)
{
#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
}
So your foreach loop should be like below
#foreach (var item in Model)
{
<tr>
<td>
#(item.Status!=1){#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })}
#Html.ActionLink("Application", "GenerateApplication", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
</td>
<td style="visibility:hidden;">
#Html.DisplayFor(modelItem => item.BusinessKey)
</td>
<td>
#Html.DisplayFor(modelItem => item.BusinessName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PropName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
</tr>
}

how to display docx or pdf in browser using mvc5

I am working on project in which I want to display docx or pdf in browser, these documents are coming from database as binary data. Here is my code
Controller
private DiagnosticDetailModel GetFileList(int id)
{
var DetList = db.DiagnosticDetailModels.Where(p => p.Id == id).FirstOrDefault();
return DetList;
}
[HttpGet]
public ActionResult RetrieveFile(int id)
{
DiagnosticDetailModel diagnosticDetailModel = GetFileList(id);
byte[] img = diagnosticDetailModel.FileContent.ToArray();
string s = Encoding.UTF8.GetString(img);
Response.Buffer = true;
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(img);
Response.AppendHeader("Content-Disposition", "inline");
ViewData["myInnerHtml"] = s;
return View("test", ViewData["myInnerHtml"]);
}
test.cshtml
<div id="doc-viewer-id" style="width:500px; height:500px;">
#(new HtmlString(ViewData["myInnerHtml"].ToString()))
</div>
index.cshtml
<table>
<thead style="background-color:#5bc0de; color:white;font-size:14px;">
<tr>
<th>#</th>
<th>
Diagnostic Name
</th>
<th>
Registration Date
</th>
<th>View Report</th>
</tr>
</thead>
<tbody style="font-size:12px;">
#foreach (var item in Model)
{
<tr>
<td></td>
<td>
#Html.DisplayFor(modelItem => item.DiagnosticName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.ActionLink("View", "RetrieveFile", new { id = item.Id }, new { #class = "btn btn-primary btn-sm fa fa-eye", #style = "color:white;background-color:#5bc0de;",#target="_blank" })
</td>
</tr>
}
</tbody>
</table>
when I click on button to display document in browser I am getting data like this which is showing in below image
anyone know where I am doing wrong in code?

Asp.Net - EF - MVC - Indexing Rows

I am using Asp.Net , EF6 ( MVC ) and have some data stored in my view. What I need is some indexing for each row. Here is the view.
For every row I have 0 Index. I wanna know, if there is some Built in feature in EF, that will help to add indexes for each row, (1,2,3....) and which will be automatically be updated, when new rows are created or deleted.
This is the Code for creating the table and doing Paging in my View.
<div class="bs-example">
<div class="table-responsive">
<div class="panel panel-default">
<table class="table table-striped table-hover table-bordered" cellspacing="0" data-toggle="table" data-click-to-select="true">
<tr>
<th style="vertical-align:middle;" class="text-center">
Index
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("English", "Index", new { sortOrder = ViewBag.EnglishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Russian", "Index", new { sortOrder = ViewBag.RussianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Armenian", "Index", new { sortOrder = ViewBag.ArmenianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("French", "Index", new { sortOrder = ViewBag.FrenchSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Spanish", "Index", new { sortOrder = ViewBag.SpanishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Arabic", "Index", new { sortOrder = ViewBag.ArabicSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#{
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#ViewBag.IndexOfRow.ToInt32
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.English)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Russian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Armenian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.French)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Spanish)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Arabic)
</td>
<td style="vertical-align:middle;" class="text-center">
<span style="color:white;">
#Html.ActionLink("Edit", "Edit", new { id = item.Text, #style = "color:red;" })
#*#Html.ActionLink("Details", "Details", new { id = item.Text })*#
#Html.ActionLink("Delete", "Delete", new { id = item.Text })
</span>
</td>
</tr>
}
}
</table>
</div>
<br />
Page #(Model.Item1.PageCount < Model.Item1.PageNumber ? 0 : Model.Item1.PageNumber) of #Model.Item1.PageCount
#Html.PagedListPager(Model.Item1, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
</div>
And this is the code from my Controller
public ViewResult Index(int? page)
{
int pageSize = 15;
int pageNumber = (page ?? 1);
var allModels = new Tuple<IPagedList<Translation>, List<Translation>>
(translations.ToPagedList(pageNumber, pageSize), translations.ToList()) { };
return View(allModels);
}
I have removed the unnecessary code, only is left the code for paging.
I have not done anything so far, because I have not find any indexing question or article in Google or SO so far.
Thanks for help.
And if you want to put Index while creating table, you can loop like this in your table body:
<tbody>
#{
int counter = 1;// Index start value
foreach (var Item in Model.SomeList)
{
<tr>
<td> #counter </td>
</tr>
counter++;
}
}
</tbody>
Just set the start row index in the action method to ViewBag.
int pageSize = 15;
int pageNumber = (page ?? 1);
ViewBag.StartRowIndex = ((pageNumber - 1) * pageSize) + 1;
Then use it in the view.
#{
var rowIndex = (int)ViewBag.StartRowIndex;
}
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#(rowIndex++) //#ViewBag.IndexOfRow.ToInt32
</td>
When you dont know what to do, create a new class :))
Im kidding, but the idea remains valid.
Why dont you craete a new class that will represent your "ViewModel" that will have the exact EF model inside and an extra Index property that you will use to bind to an index in the view?
What you will pass from your controller to the view will be the new ViewModel class.
Note:
If you want to go fancy, you could go somewhere on the line of : ObservableCollection http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx which derrives from INotifyPropertyChanged
Basically it means that you have an event at your disposal that you can fire when the list has changed (add, delete) that will be used to update the index.

Repeater simulation issues

I'm migrating a webforms project to MVC and I've come across a repeater control. The repeater control allows for inline editing (by this I mean each line that can be edited (because there is a criteria to allow this) has input controls on it where you can change the values and an edit button that takes those values and updates the db) as well as display of records displayed in a table.
With the repeater control it's easy to tell which record got updated since when that records edit button is clicked it calls the ItemCommand function passing in the row that was edited allowing me to just get that control name value to get the values. How is this done in MVC? I know we have display templates and edit templates but I need to combine them into 1, which I'm able to do with the below code, but if I have more than 1 row that can be edited how do I get the correct row of input controls to get the values?
#foreach (var item in Model.Data)
{
if(item.User == "PIRA" || DateTime.Today != item.EntryDate.Value.Date)
{
<tr style="height: 25px;">
<td hidden="hidden">
#Html.DisplayFor(modelItem => item.TransactionID)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.EntryDate)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.User)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.EffectiveDate)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.RecordType)
</td>
<td align="right">
#Html.DisplayFor(modelItem => item.Value)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td align="center">
</td>
</tr>
}
else
{
<tr style="height: 25px;">
<td hidden="hidden">
#Html.DisplayFor(modelItem => item.TransactionID)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.EntryDate)
</td>
<td align="center">
#Html.DisplayFor(modelItem => item.User)
</td>
<td align="center">
#Html.EditorFor(modelItem => item.EffectiveDate)
</td>
<td align="center">
#Html.DropDownListFor(modelItem => item.RecordType, Model.RecordTypes)
</td>
<td align="center">
#Html.EditorFor(modelItem => item.Value, new { style = "text-align: right;" })
</td>
<td align="center">
#Html.EditorFor(modelItem => item.Comments, new { cols = 50, #rows = 3 })
</td>
<td align="center">
<div style="margin-bottom:10px;">
<input type="submit" value="Edit" name="action:Edit" />
</div>
<div>
#Html.ActionLinkWithList("Delete", "Delete", "Capacity", new { id = item.TransactionID }, null)
</div>
</td>
</tr>
}
}
I was able to get this by not using DisplayFor() but instead the control *For() function so I can set the id property (because DisplayFor() doesn't seem to allow this). I set the id to include that records transactionID so each input can be unique. Then each records edit link passes in the transactionID to a javascript function. Then inside there once I have the id I can build the id properties to get all the input values and make my controller call.
ie.
#Html.TextBoxFor(modelItem => item.EffectiveDate, new { id="effectiveDate_" + item.TransactionID, #class="datepicker", style="width: 150px;" })
#Html.ActionLink("Edit", "Edit", "Data", new { onclick = "EditRecord(" + item.TransactionID + ");" })
function EditRecord(id) {
// get the control values based off the passed in id
var effDate = $("#effectiveDate_" + id).val();
// make the call to our controller passing in the edited row data
$.post("/Data/Edit/", { effectiveDate: effDate });
}
Kind of a pain to do it manually like this but it works. In the web forms repeater control this is probably what it's doing behind the scenes so I wish MVC had something like this as well.

How to disable a submit form button given a certain condition

I would like to disable a cancel button if the the record field "Status" is already recorded as cancelled. I already know how to disable a button but the problem is how would the jquery know that the record field "Status" is Cancelled.
Here Are the Codes
#foreach (var rDetail in Model.Customers.ToList()) {
<tr>
<td>
#Html.DisplayFor(model => rDetail.DateEntry)
</td>
<td>
#Html.DisplayFor(model => rDetail.DateStart)
</td>
<td>
#Html.DisplayFor(model => rDetail.DateEnd)
</td>
<td>
#Html.DisplayFor(model => rDetail.Status.Name)
</td>
<td>
#Html.DisplayFor(model => rDetail.UserCode)
</td>
<td>
#Html.DisplayFor(model => rDetail.DateModified)
</td>
<td>
#Html.DisplayFor(model => rDetail.Remarks)
</td>
<td>
#Html.ActionLink("Details", "Details", "RoomReservation", new { id = rDetail.Id}, null) |
#using (Html.BeginForm("CancelReservation", "Rooms", new { roomId = Model.Id, reservationId = rDetail.Id, methodId = 0})) {
<input type="submit" value="Cancel" class ="cancelSubmit"/>
}
</td>
</tr>
Any help will be appreciated, thanks :)
If you know the status is cancelled you can disable it in the Razor itself.
<td>
#Html.ActionLink("Details", "Details", "RoomReservation", new { id = rDetail.Id}, null);
#if(rDetail.Status.Name.Equals("cancelled"))
{
<input type="submit" value="Cancel" class ="cancelSubmit" disabled/>
}
else
{
#using (Html.BeginForm("CancelReservation", "Rooms", new { roomId = Model.Id, reservationId = rDetail.Id, methodId = 0})) {
<input type="submit" value="Cancel" class ="cancelSubmit"/>
}
}
</td>
If you want to do it jquery way:-
$(function(){
$('.cancelSubmit').each(function(){
if($(this).closest('tr').find('#Status_Name').text() === 'cancelled')
{
$(this).prop('disabled',true);
}
});
});
or inside the function you could do :-
$(this).prop('disabled',
$(this).closest('tr')
.find('#Status_Name')
.text() === 'cancelled');
If I understand you, something like this should work:
$('#Status_Name').on('keypress', function(e) { //I think that's how the XFor handlers format ids
$('button_to_disable').prop('disabled', this.value === 'Cancelled');
});

Categories

Resources