My view contains the following table definition:
<table>
<thead>
<th>Title</th>
<th>Artist</th>
<th>Genre</th>
<th>Price</th>
</thead>
#foreach (var album in Model)
{
<tr>
<td>#album.Title</td>
<td>
#{
foreach (var artist in ViewBag.Artists)
{
if (artist.ArtistID == album.ArtistID)
{ #artist.Name }
}
}
</td>
<td>
#{
foreach (var genre in ViewBag.Genres)
{
if (genre.GenreID == album.GenreID)
{ #genre.Name }
}
}
</td>
<td>#album.Price</td>
<td>
<a asp-action="Details" asp-controller="Albums">Details </a>
<a asp-action="Edit" asp-controller="Albums">Edit </a>
<a asp-action="Delete" asp-controller="Albums">Delete</a>
</td>
</tr>
}
</table>
The Details, Edit, and Delete options in the final column need to be keyed to the AlbumID property of the album variable, in order to ensure that the redirect operates on the proper album. I had thought the parameter for this might be asp-parameter, much like the action is set by asp-action, but this does not appear to exist.
What is the proper method to pass a variable as a URL parameter (for instance, /Albums/Details/var), and what name is used to retrieve this on the other side?
Shyju's answer deals with passing the parameter; my attempts at retrieving the parameter thus far have been as follows:
<%=Url.RequestContext.RouteData.Values["id"]%> - Fails to load, invalid character <.
ViewContext.RouteData.Values["id"] - Fails to load, cannot compare int and object using ==.
RouteData.Values["id"] - Compilation error, name does not exist in current context.
When using link tag helper, You can pass additional information to the action method using the asp-route-[paramName] attribute. For example, if you want to pass the album id to the id parameter of your details action method, you can do this
<a asp-action="Details" asp-controller="Albums" asp-route-id="#album.ID">Details </a>
This will generate the markup like below
<a href='/Albums/Details/101'>Details</a>
Where 101 will be replaced by an actual Album Id value.
Assuming your Details action method has a parameter named id
public ActionResult Details(int id)
{
// to do : Get the album using the id and send something to the view
}
Related
I'm trying to create a web page using a thymeleaf template to present a table of Orders with a field that provided a list of products associated with a specific order.
My controller class:
#Controller
public class WebPage {
#Autowired
private OrderRepository orderRepository;
#Autowired
private ProductRepository productRepository;
#RequestMapping("/test")
public String index(Model model) {
model.addAttribute("ordertable", orderRepository.findAll());
model.addAttribute("producttable", productRepository.findAll());
return "tablepage";
}
}
Relevant part of thymeleaf template:
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>stuff</th>
<th>Stuuff</th>
<th>stuff</th>
<th>products</th>
</tr>
</thead>
<tbody>
<tr th:each="ordertbl: ${ordertable}">
<td th:text="${ordertbl.stuffId}"/>
<td th:text="${ordertbl.stuffname}"/>
<td th:text="${ordertbl.stuffname}"/>
<td th:text="${ordertbl.stuff}"/>
<td>
<span th:each="producttbl: ${producttable}"><span th:text="${ordertbl.products}"/></span>
</td>
</tr>
</tbody>
</table>
What this does is creates a table of orders but in the final field, it lists all the products contained in the order several times depending how many products are in the product table.
How would I change this so that the the order field lists the products belonging to each row just once. I am aware that this is most likely a nested for loop error, or a problem with my use of findall() method but I'm not sure how to fix it.
I would prefer to use the nested product table rather than fetching the products from the order jpa entity class.
Thanks.
If you're trying to display products of each order, then this line is wrong:
<span th:each="producttbl: ${producttable}"> <span th:text="${ordertbl.products}" /> </span>
You're iterating against the producttable list you have in your model, not of the current ordertbl's products in the loop. It should be
<span th:each="producttbl: ${ordertbl.products}"> <span th:text="${producttbl}" /></span>
When I click on the column values in a table, it should redirect me to another table which has a common id, but a different view.
#foreach (var item in Model.Vendor)
{
<tr>
<td>
#Html.ActionLink(item.VendorName, "#item.Site Name", new { Id = item.VendorName})
</td>
<td>
#item.SiteCount
</td>
<td>
#item.LastReviewType
</td>
<td>
#item.LastReviewDate
</td>
<td>
#item.TeamLead
</td>
...
When I click on the vendorname values in the table, it should take me to the table which shows the sites which are assigned to the vendor.
Assuming you would have a controller by the name VendorController which has an action SiteList which would take argument venderId to generate the view, you could use
#Html.ActionLink(item.VendorName, “SiteList” /*Name of the action*/, “Vendor” /* Name of the controller */, new { venderId = item.VendorId } /* parameter */)
If the action is on the same controller which generated the first table, you may ignore /* Name of the controller argument */, thus
#Html.ActionLink(item.VendorName, “SiteList” /*Name of the action*/, new { venderId = item.VendorId } /* parameter */)
Hope this will help you
So I'm working on an MVC 3 project that pulls from multiple (10) tables from a legacy data source to a Master View with 6 partials. There is one table that has data on every child view, so we decided to store that in session data and then populate the rest of the child views with whatever other data is needed.
When we originally tried to do this, we were getting null reference exceptions to the session data. I've come up with a solution, but it seems very clunky and I don't think it's best practices/introducing unnecessary state.
Relevant code to follow:
This is what we have on the main controller:
public ActionResult PolicyView(string PolicyID)
{
IPolicyHolder phdata = new PolicyHolderData();
Polmast policy = phdata.GetPolicyFromUV(PolicyID);
ViewBag.FullName = policy.FULLNAME;
ViewBag.PolicyID = PolicyID;
Session["polmast"] = policy;
return View("PolicyView");
}
And then in our main view, one of the links to the partial child views:
<div id="Billing">
#{ Html.RenderAction("Billing", Session["polmast"] ); }
</div>
In the child controller:
public ActionResult Billing(object sessiondata)
{
return PartialView("_Billing", sessiondata);
}
And in the child view:
#{var polmast = (Polmast)Session["polmast"];}
**snip**
<table id="premiumsgrid" class="display" border="1"
cellpadding="0" cellspacing="0" width="50%">
<thead>
<tr>
<th>Annual</th>
<th>Semi-Annual</th>
<th>Quarterly</th>
<th>Monthly</th>
</tr>
</thead>
<tbody>
<tr>
<td>#polmast.PAN</td>
<td>#polmast.PSA</td>
<td>#polmast.PQT</td>
<td>#polmast.PMO</td>
</tr>
</tbody>
</table>
I would recommend starting to use models and returning those to your views instead of passing around the session object and casting it within your view. It would make this code much more clean.
This is how I would structure my code:
public ActionResult PolicyView(string PolicyID)
{
IPolicyHolder phdata = new PolicyHolderData();
Polmast policy = phdata.GetPolicyFromUV(PolicyID);
PolicyModel model = new PoliceModel() {
FullName = policy.FULLNAME,
PolicyID = PolicyID
//Populate other properties here.
};
Session["polmast"] = policy;
return View("PolicyView", model);
}
Then I would set up your main view (there's no need to wrap this call in curly braces and you shouldn't need to pass any route values):
<div id="Billing">
#Html.RenderAction("Billing")
</div>
The child controller:
public ActionResult Billing()
{
//Get the data out of session; it should already exist since your parent controller took care of it.
var policyData = (Polmast)Session["polmast"];
PolicyModel model = new PoliceModel() {
FullName = policy.FULLNAME,
PolicyID = PolicyID
//Populate other properties here.
};
return PartialView("_Billing", model);
}
And your child view:
#model Polmast
snip
<table id="premiumsgrid" class="display" border="1"
cellpadding="0" cellspacing="0" width="50%">
<thead>
<tr>
<th>Annual</th>
<th>Semi-Annual</th>
<th>Quarterly</th>
<th>Monthly</th>
</tr>
</thead>
<tbody>
<tr>
<td>#Model.PAN</td>
<td>#Model.PSA</td>
<td>#Model.PQT</td>
<td>#Model.PMO</td>
</tr>
</tbody>
</table>
I'm trying to access the values a user introduces in a table from my controller.
This table is NOT part of the model, and the view source code is something like:
<table id="tableSeriales" summary="Seriales" class="servicesT" cellspacing="0" style="width: 100%">
<tr>
<td class="servHd">Seriales</td>
</tr>
<tr id="t0">
<td class="servBodL">
<input id="0" type="text" value="1234" onkeypress = "return handleKeyPress(event, this.id);"/>
<input id="1" type="text" value="578" onkeypress = "return handleKeyPress(event, this.id);"/>
.
.
.
</td>
</tr>
</table>
How can I get those values (1234, 578) from the controller?
Receiving a formcollection doesn't work since it does not get the table...
Thank you.
Using the FormCollection should work unless your table is not inside of a <form> tag
On top of Lazarus's comment, you can try this, but you have to set the name attribute for each:
<input id="seriales[0]" name="seriales[0]" type="text" value="1234" onkeypress="return handleKeyPress(event, this.id);"/>
<input id="seriales[1]" name="seriales[1]" type="text" value="578" onkeypress="return handleKeyPress(event, this.id);"/>
Now in your Action method you can make your method look like this:
[HttpPost]
public ActionResult MyMethod(IList<int> seriales)
{
// seriales.Count() == 2
// seriales[0] == 1234
// seriales[1] == 578
return View();
}
and seriales will be wired up to those values.
First Option:
Using FormCollection is the simplest way to access dynamic data. It is strange that you cannot get those values from it, can you check the following?
Is the table inside the
element?
Can you add name attribute
to the input elements? Note that
form items are bound by their names,
not id.
Second Option:
The second option is to add a collection in your model, and name everything accordingly. i.e.
public class MyModel
{
...
public IList<string> MyTableItems { get; set; }
}
and in your view use following names:
<input name="MyTableItems[]" value="" />
This is somewhat related to another question I've asked but I figure why not ask it seperately.
If I were to place something like the following in a view
<td><img src='<%= Url.Action( "DisplayImage" , "User" , new { id = item.id} ) %>' alt="" /></td>
Is it supposed to display this?
<td>
<img src='/User.mvc/DisplayImage?id=U00915441' alt="" />
</td>
Or would the value of the src-attribute actually be replaced with the results of the UserController GetImage Action?
It will construct the path to the action, returning a url, not the results of executing the action.
The results will be:
<td>
<img src='/User.mvc/DisplayImage?id=U00915441' alt="" />
</td>
Example code. assumes your user model has the image stored in a byte array. If you are using LINQ and the property is a Binary, then use the ToArray() method to convert it to a byte array. Note the attributes which will require that the user be logged in and using a GET request.
[Authorize]
[AcceptVerbs( HttpVerbs.Get )]
public ActionResult DisplayImage( string id )
{
var user = ...get user from database...
return File( user.Image, "image/jpeg" );
}
}