Local variable in MVC View - c#

I have an MVC view that displays a list of items. The table that was automatically generated with the view has this action link on every row:
#Html.ActionLink("Delete", "Delete", new { id = item.section_detail_id }).
This works fine but my requirement is to allow the user to highlight a row and click on a delete button at the bottom of the list. I need a way for the button to know which row is currently highlighted. So I created this local variable:
#{int sectionDetailId = 0; }
Then I added an onclick event on the table rows to store the the id of the row that is clicked:
tr id="#item.section_detail_id" onclick="addClass(this.id); sectionDetailId = #item.section_detail_id">
Here is the button that is supposed to bring up the delete view:
input type="button" value="Delete Employee" onclick="location.href='#Url.Action("Delete", "EmployeeList", new { id = sectionDetailId })'; alert(sectionDetailId)" />
The value that is passed to the view is always zero no matter what row is clicked. I added the alert function to the button to show that the variable has the correct value.
Is there a way to get the Action method to use the variable or to get the value from the table in some other way? The Action method works correctly if I hard code an ID.
Here is the complete view:
#model IEnumerable<VCPDS2.Models.EmployeeListViewModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
tr.highlight {
background-color: blue !important;
}
</style>
#{int sectionDetailId = 0; }
<h2>Index</h2>
#*<p>
#Html.ActionLink("Create New", "Create")
</p>*#
#if (Model != null)
{
<table id="employeeTable" class="table table-responsive table-striped">
<tr>
<th>
Last Name
</th>
<th>
First Name
</th>
<th>
Employee ID
</th>
<th>
Phone
</th>
<th>
Budget Unit
</th>
<th>
Division
</th>
</tr>
<tbody id="employeeList">
#foreach (var item in Model)
{
<tr id="#item.section_detail_id" onclick="addClass(this.id); sectionDetailId = #item.section_detail_id">
<td>
#Html.DisplayFor(modelItem => item.last_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.first_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.employee_id)
</td>
<td>
#item.phone_nbr
#* #Html.DisplayFor(modelItem => item.phone.area_code) #Html.DisplayFor(modelItem => item.phone.phone_nbr)*#
</td>
<td>
#item.BU
#*#Html.DisplayFor(modelItem => item.phone.BU)*#
</td>
<td>
#item.description
#*#Html.DisplayFor(modelItem => item.department.description)*#
</td>
<td>
#*#Html.ActionLink("Edit", "Edit", new { id = item.section_detail_id }) |
#Html.ActionLink("Details", "Details", new { id = item.section_detail_id }) |*#
#Html.ActionLink("Delete", "Delete", new { id = item.section_detail_id })
</td>
</tr>
}
</tbody>
</table>
<p>
#*#Html.ActionLink("Create New", "Create")*#
<input type="button" value="Add Employee"
onclick="location.href='#Url.Action("Create", "EmployeeList")'" />
<input type="button" value="Delete Employee"
onclick="location.href='#Url.Action("Delete", "EmployeeList", new { id =
#sectionDetailId })'; alert(sectionDetailId)" />
</p>
}
<script src="jquery-3.4.1.min.js"></script>
<script>
function addClass(row) {
//alert(row);
$('#employeeList').children().removeClass('highlight');
var element = document.getElementById(row);
element.classList.add("highlight");
}
</script>
#*#Html.ActionLink("Edit", "Edit", new { id = item.section_detail_id }) |
#Html.ActionLink("Details", "Details", new { id = item.section_detail_id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.section_detail_id
})*#
This is the rendered HTML for the delete button:
<input type="button" value="Delete Employee" onclick="location.href='/EmployeeList/Delete/0'; alert(sectionDetailId)">

Related

Create a button in MVC to hide labels and replace it with '******'

brief background, my application is a password manager and has a page where it displays labels,a services e.g. gmail and the password saved associated to it. I am trying to find a way to have a button or checkbox to show or hide the passwords so the user can see their passwords and then press a button to hide the passwords and mask them with a series of asterisks. I was hoping someone might have a jquery or razor idea to help em out?
<div class="panel-body">
<table class="table table-bordered table-responsive table-hover">
<tr>
<th>
#Html.DisplayNameFor(model => model.Website)
</th>
<th>
#Html.DisplayNameFor(model => model.Password)
</th>
<th>
#Html.DisplayNameFor(model => model.DateSaved)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Website)
</td>
<td>
#Html.DisplayFor(modelItem => item.Password)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateSaved)
</td>
<td>
#Html.ActionLink(" Edit", "Edit", new { id = item.Id }, new { #class = "btn btn-primary btn-sm glyphicon glyphicon-pencil" })
#Html.ActionLink(" Details", "Details", new { id = item.Id }, new { #class = "btn btn-info btn-sm glyphicon glyphicon-eye-open" })
#Html.ActionLink(" Delete", "Delete", new { id = item.Id }, new { #class = "btn btn-danger btn-sm glyphicon glyphicon-trash" })
#Html.ActionLink(" Strength Check", "Index", "StrengthCheck", new { id = item.Id }, new { #class = "btn btn-warning btn-sm" })
</td>
</tr>
}
</table>
You could use a simple JQuery function to toggle the field between asterisks and the real password value. The trick will be making sure each password field is uniquely identifiable so you only show that one password when you click the button (I'm assuming there will be multiple passwords on the screen since it's in a table)
Change the foreach loop to this so you have access to the index. This gives you easy access to a unique value for each row:
foreach (var item in Model.Select((value, i) => new { i, value }))
{
// You access the values like this now
var value = item.value;
var index = item.i;
}
See this answer for reference (the answer beneath the approved answer): How do you get the index of the current iteration of a foreach loop?
In the html table put:
<td>
<span id="password-#item.i" style="display: none;">#item.value.Password</span>
<span id="hidden-password-#item.i">*******</span>
<button onclick="showHidePassword('#item.i')">Toggle</button>
</td>
And somewhere on the page add the following javascript:
function showHidePassword(i) {
if ($('#password-' + i).is(':visible')) {
$('#password-' + i).hide();
$('#hidden-password-' + i).show();
} else {
$('#password-' + i).show();
$('#hidden-password-' + i).hide();
}
}
Hope this helps. To make reusability easier you could move this to a html extension method depending on how you're building out the rest of the page

ASP.NET MVC Paging Table with only one datasource refresh?

If you would do this Paging approach everything works finde. My problem is that i don't want get the dataset each time. I only want to do it once. How can i do that?
Table:
#model PagedList.IPagedList<ViewModel.QuestionViewModel>
#using PagedList.Mvc;
<table class="table">
<tr class="table-head">
<th>
<p>Sender</p>
</th>
<th>
<p>Subject</p>
</th>
<th>
<p>Received</p>
</th>
<th>
<p>HasAttachment</p>
</th>
<th></th>
</tr>
#foreach (var item in Model.Inbox) {
<tr class="mail-row" onclick="location.href = '#Url.Action("Index", "MailContent", new { id = item.Id })'">
<td>
#Html.DisplayFor(modelItem => item.From)
</td>
<td>
#Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
#Html.DisplayFor(modelItem => item.Received)
</td>
<td>
#Html.DisplayFor(modelItem => item.HasAttachments)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssetClass)
</td>
<td>
#Html.DisplayFor(modelItem => item.InProgressBy)
</td>
#*<td>
#html.actionlink("edit", "edit", new { /* id=item.primarykey */ }) |
#html.actionlink("details", "details", new { /* id=item.primarykey */ }) |
#html.actionlink("delete", "delete", new { /* id=item.primarykey */ })
</td>*#
</tr>
}
</table>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager( Model, page => Url.Action("MailList", new { page }) )
So this is the table, but each time i click on the next button it will go back to the controller which gets all mails again. due to a larger set of data its inefficent to load it every time.
Controller:
MailboxController
public ActionResult MailList(string id, int? page) {
//TODO: get list
//get Maillist for mailbox
context = new InboxToolContext();
context.Mails.MailboxType = id;
Console.Write(i);
i = 2;
int pageSize = 20;
int pageNumber = (page ?? 1);
return View(context.Mails.All().ToPagedList(pageNumber,pageSize));
}

MVC replacing Edit/Details/Delete with Icons

I want to replace those three fields Edit/Details/Delete with icons I just downloaded. The icons are with size 512x512, will this be a problem? Can I resize them in the code (how), or I should resize them using some program.
I've been searching through the net and I found some very long pieces of C# code but I have no idea where to put it in order to replace the text of those properties with the icons.
Here is my HTML:
#using PagedList.Mvc;
#model PagedList.IPagedList<Rating_System.Models.tblTeacher>
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Teachers List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Teachers</h2>
<p>
#Html.ActionLink("Add new", "Create")
</p>
#using (Html.BeginForm("Index", "Teachers", FormMethod.Get))
{
<p>
Търсене: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
</th>
<th>
#Html.DisplayNameFor(model => model.First().FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.First().SecondName)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Title)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
<img src="#Url.Action("GetImage", "Teachers", new {item.ID})" width="45" height="45" />
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.SecondName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.ActionLink("Редактирай", "Edit", new { id = item.ID }) |
#Html.ActionLink("Детайли", "Details", new { id = item.ID }) |
#Html.ActionLink("Изтрий", "Delete", new { id = item.ID })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, pageSize = Model.PageSize }))
Results #Model.FirstItemOnPage - #Model.LastItemOnPage от общо #Model.TotalItemCount Teachers
try with this code
<a href="#Url.Action("ActionName", "ControllerName", new { id = item.ID })">
<img src="#Url.Content("~/Content/imgname.jpg")" />
</a>
If you want to use an icon (Image) use the following code:
#Html.ActionLink("Редактирай", "Edit", new { id = item.ID }, new { #class="class" })
Then write you css class to include a background image
a.class
{
background: url(../Images/image.gif) no-repeat top left;
width: 50px;
height: 50px;
display: block;
text-indent: -9999px; /* hides the link text */
}
However, I would suggest using bootstrap glyphicons for example
<a href="#Url.Action("Action", "Controller")" class="btn btn-info">
Your link text
<span class="glyphicon glyphicon-time" aria-hidden="true"></span>
</a>
Or
<span class="glyphicon glyphicon-ok" style="cursor:pointer" onclick="JavascriptFunction()"></span>
And in Javascript
function JavascriptFunction() {
window.location.href = encodeURI("/Controller/Action/");
}
You can pass the ID through the javascript function

DateTime destroys View

I have a pretty basic/standard MVC project I'm building up. Everything in it works fine (Fig 1) until I add a DateTime object to my Model (Fig 2), at which point the View for that Model gets very distorted, and won't display any information (Fig 3). See the entry in my SQL Database for the related DateTime object (Fig 4).
I am left to assume it's something to do specifically with the DateTime data type, but I'm not sure What might be causing this or what could I try for troubleshooting.
Fig 1:
Fig 2:
Fig 3:
Fig 4:
Code from my View as asked:
#model TKOPOC.Models.SubmitEIDs
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#* Model Update Alert *#
#if(Model.isVerify){ <h1><span style="color: red;">VERIFY YOUR CHANGES, THEN CLICK SUBMIT</span></h1> }
#*Search Box*#
#if(!Model.isVerify)
{
using (Html.BeginForm("Index", "EightID", FormMethod.Get))
{
<p>
Find by name or EID: #Html.TextBox("searchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<p>
#Html.ActionLink("Create New", "Create")
</p>
}
<table>
<tr>
<th>
#Html.ActionLink("EID", "Index", new { sortOrder=ViewBag.EIDSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Email", "Index", new { sortOrder=ViewBag.EmailSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Physical", "Index", new { sortOrder=ViewBag.PhysicalSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Admin", "Index", new { sortOrder=ViewBag.AdminSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink(" Maint", "Index", new { sortOrder=ViewBag.MaintSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink(" Cab", "Index", new { sortOrder=ViewBag.CabSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink(" Mills", "Index", new { sortOrder=ViewBag.MillSortParam, currentFilter=ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#foreach (var item in Model.EightIDsPagedList) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.EID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Physical)
</td>
<td>
#Html.DisplayFor(modelItem => item.Admin)
</td>
<td>
#Html.DisplayFor(modelItem => item.Maint)
</td>
<td>
#Html.DisplayFor(modelItem => item.Cab)
</td>
<td>
#if (item.Admin | item.Maint)
{
<text>All</text>
}
else
{
#Html.DisplayFor(modelItem => item.Mills.Count)
}
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.EightIDID }) |
#Html.ActionLink("Details", "Details", new { id=item.EightIDID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.EightIDID })
</td>
</tr>
}
</table>
<p>&nbsp</p>
#* Paging *#
<div>
Page #(Model.EightIDsPagedList.PageCount < Model.EightIDsPagedList.PageNumber ? 0 : Model.EightIDsPagedList.PageNumber)
of #Model.EightIDsPagedList.PageCount
#if (Model.EightIDsPagedList.HasPreviousPage)
{
#Html.ActionLink("<<", "Index", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink("< Prev", "Index", new { page = Model.EightIDsPagedList.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:<<
#Html.Raw(" ");
#:< Prev
}
#for (var x = 1; x < Model.EightIDsPagedList.PageCount; x++)
{
if (Model.EightIDsPagedList.PageNumber == x)
{
#x;
}
else
{
#Html.ActionLink(Convert.ToString(x), "Index", new { page = x, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter });
}
}
#if (Model.EightIDsPagedList.HasNextPage)
{
#Html.ActionLink("Next >", "Index", new { page = Model.EightIDsPagedList.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
#Html.Raw(" ");
#Html.ActionLink(">>", "Index", new { page = Model.EightIDsPagedList.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
<p>&nbsp</p>
<table border="0">
<tr>
#if (!Model.isVerify)
{
using (Html.BeginForm("Index", "EightID", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<td>
<input type="file" name="file" required />
<input type="submit" name="Verify" value="Verify" />
</td>
}
}
else
{
using (Html.BeginForm("Submit", "EightID", FormMethod.Post, new { NewEIDs = Model.EightIDs }))
{
<td>
<input type="submit" name="Submit Changes" value="Submit" />
</td>
}
using (Html.BeginForm("Cancel", "EightID", FormMethod.Post))
{
<td>
<input type="submit" name="Cancel" value="Cancel" />
</td>
}
}
</td>
</tr>
</table>
Edit:
After some more debugging through the view, I've found where the issue occurs, just not why - after the table headers, we come down to the foreach() loop where the DisplayFor happens. Here, the program hits foreach. Then Model.EightIDsPagedList. Then "in". But then it never comes into var or item and just skips the loop entirely. When I removed the DateTime items in question, the program enters the loop as you would expect it to and continues execution all the way down.
Do you get a null reference exception anywhere? Do you have a value in the DateTime column when you run the example? Your SQL seems to be nullable but your property is not. You could try these options:
Making that a DateTime? (nullable DateTime) in the code.
Make sure you have a value in SQL
Making the SQL column not nullable (which will guarantee option 2).
Let us know if that helps.

Why my button in MVC doesn't work?

I've got this code:
#model IEnumerable<PamelaFundacionFinal.Models.Escuela>
#{
ViewBag.Title = "Index";
}
<h2>Escuelas registradas</h2>
<p>
<button name="Edit" class="btn btn-default"><b>
#Html.ActionLink("Create New", "Create")</b></button></p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Nombre)
</th>
<th>
#Html.DisplayNameFor(model => model.Direccion)
</th>
<th>
#Html.DisplayNameFor(model => model.Telefono)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Nombre)
</td>
<td>
#Html.DisplayFor(modelItem => item.Direccion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Telefono)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Escuela_ID })
<button name="Edit" class="btn btn-default">
#Html.ActionLink("Details", "Details", new { id = item.Escuela_ID })</button>
<button name="Edit" class="btn btn-default">
#Html.ActionLink("Delete", "Delete", new { id = item.Escuela_ID })</button>
</td>
</tr>
}
</table>
Don't worry, everything is referenced to their own controller to make the opperations, my issue is that I've got two cases:
I'm writing in #Html.ActionLink("Edit", "Edit", new { id = item.Escuela_ID }) a reference to another controller, so I can create a new one, but it's simple text
Then, I'm trying to put that reference into a button, so it looks nice: <button name="Edit" class="btn btn-default">#Html.ActionLink("Delete", "Delete", new { id = item.Escuela_ID })</button> but it doesn't work.
I know that I'm not writing this correctly, but I need help because I'm new with this language and I don't really know exactly how is the syntax. I'm using Visual Studio 2013 and SQL Server to run the database (The connection with database is running perfectly, it's not an issue with the database).
You can style your <a> tag that is generated by the Html helper.
#Html.ActionLink("Edit", "Edit", new { id = item.Escuela_ID },
new { #class = "btn btn-default" })

Categories