I have the following Mvc 4 razor code
#foreach (var item in Model.DealDetails) {
<tr>
<td>#Html.DisplayFor(m => item.DetailId)</td>
<td>#Html.DisplayFor(m => item.AppGuid)</td>
....
</tr>
I want to generate a link in another <td> column for each row. The link will look like
<a href="/Control/Action/{item.DetailId}?h={item.AppGuid}">
Link text
</a>
The control and action are in the same project. Is there any help function to do it? I want the link not to be created when item.AppGuid is null.
#foreach (var item in Model.DealDetails) {
<tr>
<td>#Html.DisplayFor(m => item.DetailId)</td>
<td>#Html.DisplayFor(m => item.AppGuid)</td>
#if(item.AppGuid != null){
<td>#Html.ActionLink("text", "action", "controller", new { id = item.DetailId , h = item.AppGuid}, null)</td>
}
</tr>
Related
I am new to ASP.NET Core development. I am looking for something like a built-in way to use loop iteration numbers inside the view of ASP.NET Core.
I did some research and found solutions like creating int variable outside the loop and then increment inside the loop.
I want to index each user.
Here is my code:
#foreach (var item in l_IEnumerableModUserQuery)
{
<tr>
<td>
<!-- Here I want to add Iteration No. here-->
</td>
<td>
<a href="#">
#item.Pr_FullName
</a>
</td>
<td>#item.Pr_Email</td>
<td>#item.Pr_ContactNo</td>
</tr>
}
You could use a simple for loop to get the index:
//use .Count if it is a List or .Count() with Linq to get the boundary.
#for(var i = 0; i < l_IEnumerableModUserQuery.Count; i++)
{
<tr>
<td>
#i.ToString();
</td>
<td>
<a href="#">
#l_IEnumerableModUserQuery[i].Pr_FullName
</a>
</td>
<td>#l_IEnumerableModUserQuery[i].Pr_Email</td>
<td>#l_IEnumerableModUserQuery[i].Pr_ContactNo</td>
</tr>
}
Thomas Levesque has a neat approach on his blog, using an extension method:
public static IEnumerable<(T item, int index)> WithIndex<T>(this IEnumerable<T> source)
{
return source.Select((item, index) => (item, index));
}
Which would result in:
#foreach (var (item, idx) in l_IEnumerableModUserQuery.WithIndex())
{
<tr>
<td>
#idx
</td>
<td>
<a href="#">
#item.Pr_FullName
</a>
</td>
<td>#item.Pr_Email</td>
<td>#item.Pr_ContactNo</td>
</tr>
}
With an eye on the extension methods approach, you could as well amend your views model and include the index as a property in your model inside your controller / handler or whereever your model is created:
var l_IEnumerableModUserQuery =
someSource.Where(x => ...)
.Select((x, index) => new MyModel {
Index = index,
Pr_Email = xxx,
Pr_Contact = xxy,
/* ... rest of model */
});
return l_IEnumerableModUserQuery;
After this you could access the index like any other property in your view:
<a href="#">
#item.Index
</a>
you can findout the index of the item
#{
int indx=0;}
#foreach (var item in l_IEnumerableModUserQuery)
{
<tr>
<td>
#l_IEnumerableModUserQuery.IndexOf(item)
</td>
<td>
<a href="#">
#item.Pr_FullName
</a>
</td>
<td>#item.Pr_Email</td>
<td>#item.Pr_ContactNo</td>
</tr>
}
I have a table with some column in a asp.net mvc core project.
My view file looks like this
<h1>Items</h1>
<div class="panel-body">
<table class="table table-bordered table-responsive table-hover">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Rating</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Items)
{
<tr onclick="location.href='#(Url.Action("ShowItemDetails", "Item", new {Id = item.FilmId}))'">
<td>#item.Id</td>
<td>#item.Title</td>
<td>#item.Rating</td>
<td>#Html.ActionLink("Edit", "Edit", "Show", new { id = item.Id }) | #Html.ActionLink("Rate this", "RateItem", new { id = item.Id }) </td>
</tr>
}
</tbody>
</table>
</div>
The problem is that when i click on a row, the controller method ShowItemDetails is called twice(!).
I can not see from the code above why this happens. Also, clicking on Edit or Rate this calls first ShowItemDetails and then immediately Edit or RateItem method in controller. Any suggestion how this can be solved?
Clicking on Edit or Rate this calls first ShowItemDetails and then immediately Edit or RateItem method because Edit is under a table row and on tablerow, you have called showitemdetails action.so, when you click on td , it gets first executed row action then td action.that's why it get called twice.
I hope, you want to show details and edit options with data of table and Edit is controller name.
Tweak your table code like below:
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td>#Html.ActionLink("Show Details","ShowItemDetails","Item",new {Id = item.FilmId})</td>
<td>#item.Id</td>
<td>#item.Title</td>
<td>#item.Rating</td>
<td>#Html.ActionLink("Edit", "Edit", "Show", new { id = item.Id }) | #Html.ActionLink("Rate this", "RateItem", new { id = item.Id }) </td>
</tr>
}
</tbody>
The problem seems to be caused be something i thought was irrelevant
having a null image cause the method to be called twice. Setting it to
solves this.
Need to add code to check for Model.Image != null
Very strange!!
/*
hallo, I am new in mvc and linq. I've 2 table in relation many to many: 1)employe 2)device
Selecting an employe I'd like to see his devices:
-Marco
-Franco
Selecting Marco should appear the devices associated to him.
My code (not work):
Controller:
*/
public ActionResult VediDevice(int id)
{
Impiegato impi = new Impiegato();
List<Device> ListDevice = new List<Device>();
using (DatabaseMVCCOntrolsEntities db = new DatabaseMVCCOntrolsEntities())
{
ListDevice= db.Devices.Where(u => db.ImpiegatiDevice.Any(m => m.impiegatiID == id)).ToList(); <---???
}
return View(ListDevice);
}
VediDevice.cshtml:
#model List<MVCControlToolkit.Models.Device>
#{
ViewBag.Title = "VediDevice";
}
<h2>VediDevice</h2>
<table class="table table-striped table-condensed">
<tr>
<th>
NOME
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.nome)
</td>
</tr>
}
</table>
Not work.
What should I do?
Thank you
Ale
Use Include before where
ListDevice= db.Devices.ToList().Where(u => u.item.Any(m => m.impiegatiID == id)).ToList();
and add your Device class
List<ImpiegatiDevice> item{get;set;}
I have taken over support of an MVC application, but unfortunately have pretty much zero experience or knowledge of MVC, so I apologise in advance if this is a stupid question.
We are placing every single result into a listed item in the HTML, then hiding all but one record, so you can filter through the different entries using First/Prev/Next/Last buttons, all via jQuery:
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
This is fine, and displays the records without any problem, however when you try to edit any record but the first, you get a "System.ArgumentNullException: Value cannot be null." error.
Here's the code in the controller for the edit function:
[HttpPost]
public ActionResult Edit(RecordsView rv)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.FirstOrDefault().DogIncident);
}
return RedirectToAction("Index");
}
This is defined at the start of the cshtml file:
#using (Html.BeginForm("Edit", "Home", FormMethod.Post,new {#class="record-view"}))
And finally, here is how the HTML is generated on the view:
<li class="first" id="record-1805">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1804">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1803">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
Does anyone please know why I can only edit the first record that is displayed and not the others? Even if I go through the records using the next/back buttons and back to the first record to submit it, it updates fine, but updating any other record generates an error.
Referencing Darin's post: Pass a parameter to a controller using jquery ajax takes you halfway. He's using an input val in jQuery and passing it to the Controller Action.
Typically you'd provide one input link or #Html.ActionLink per record to be clicked for editing and MVC will bind to the controls parameter to your action (ID or what ever you want) just use the same name on the action link as the parameter and it will be mapped during the post.
data: { input: $('#caption').val() },
Change the signature of your controller action , or add another that takes an 'int' as shown below.
[HttpPost]
public ActionResult Edit(int ID = 0)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.Where(r => r.ID == ID).DogIncident);
}
return RedirectToAction("Index");
}
Can you post the complete view so we can complete a solution ?
Was expecting the cshtml view. Here's an example:
#model IEnumerable<yourModelName>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.NID)
</th>
<th>
#Html.DisplayNameFor(model => model.CreatedOn)
</th>
<th>
#Html.DisplayNameFor(model => model.ExtensionAttribute15)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.yourElement1)
</td>
<td>
#Html.DisplayFor(modelItem => item.yourElement2)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
</td>
</tr>
}
</table>
#section Scripts{
<script type="text/javascript">
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
</script>
}
I have a View with a foreach loop for a list property of the model. Now, I want to be able to let the user set the value of each of the items in the list using a dropdownlist. But I'm not sure how to do that. I've used something like this when it is not in a foreach loop:
#Html.DropDownListFor(model => model.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, Model.Level))
But how do I do this when I need to reference item.Level in the loop instead? Here's my View code:
<div id="formDiv">
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Ny arbetserfarenhet</legend>
<table>
<tr>
#*<th></th>*#
<th>
Program
</th>
<th>
Nivå
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#item.Program.Name
</td>
<td>
#item.Level
</td>
</tr>
}
</table>
</fieldset>
}
</div>
I have a View with a foreach loop for a list property of the mode
I would recommend you to avoid writing loops in your views in favor of editor templates. So:
#model IEnumerable<AppName.Models.ModelName>
<div id="formDiv">
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Ny arbetserfarenhet</legend>
<table>
<tr>
<th>
Program
</th>
<th>
Nivå
</th>
</tr>
#Html.EditorForModel()
</table>
</fieldset>
}
</div>
and in the corresponding editor template (~/Views/Shared/EditorTemplate/ModelName.cshtml):
#model AppName.Models.ModelName
<tr>
<td>#Model.Program.Name</td>
<td>
#Html.DropDownListFor(
model => model.Level,
new SelectList(
Enumerable.Range(1, 5).Select(x => new { Value = x, Text = x }),
"Value",
"Text"
)
)
</td>
</tr>
So the editor template will be rendered for each element in your model (which is a collection of some type). The important part is that the editor template must be located in ~/Views/Shared/EditorTemplates and named XXX.cshtml where XXX is the type name used in your main view model collection.
Have you tried:
#Html.DropDownListFor(m => item.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, item.Level))
use this syntax:
#Html.DropDownListFor(model => model.Level, new SelectList(Model.level as System.Collections.IEnumerable, "VALUE_FIELD", "TEXT_FIELD", YOUR PROPERTY NAME)
MVC will create the loop. Just use an editor template, partial view in special folder, and the rest works like magic.
Editor Template
#model Models.AdditionalAccountingLine
#Html.HiddenFor(m => m.IsRequired)
#Html.DropDownListFor(m => m.FieldValue, new SelectList(#Model.FieldValueOptions, "Key", "Value"), "")
View
#Html.EditorFor(m => m.AdditionalAccountingLines);