How to make a list item clickable in asp.net - asp.net-mvc

I am dynamically building a list based on data that is coming from my database
I am trying to make every list item clickable such that when one list item is clicked I can redirect to my controller "requistion" and enter the action in that controller "Details"
The list builds and displays successfully the only issue is that the list item itself is not clickable so I am not able to redirect to my controller and proceed with the rest of the logic
here is my code below)Please not that the code below is inside the _Layout.cshtml page
<div id="notifications">
<h3 class="notify"><b>Notifications</b></h3>
<div style="height:300px;">
<ul id="notiContent">
#if (ViewData["MessageList"] != null)
{
var viewDataProd = ViewData["MessageList"] as List<Notification>;
#for (var i = 0; i < viewDataProd.Count; i++)
{
#*<li class="notiContentLi"> <a asp-controller="Requisition" asp-action="Details" asp-route-id="#viewDataProd[i].RequisitionId"></a> #viewDataProd[i].Action</li>*#
#*<li class="notiContentLi"> <a asp-controller="Requisition" asp-action="Details" asp-route-id="#viewDataProd[i].RequisitionId"></a> #viewDataProd[i].Action</li>*#
<li class="notiContentLi"><a href='#Url.ActionLink("Details","Requisition",new{#viewDataProd[i].RequisitionId})'>click me </a>#viewDataProd[i].Action</li>
}
}
#if (GlobalVariables.messageList != null)
{
var viewDataProd = GlobalVariables.messageList as List<Notification>;
#for (var i = 0; i < viewDataProd.Count; i++)
{
#*<li class="notiContentLi">#c.Action<br /> </li>*#
#*<li class="notiContentLi" asp action>#viewDataProd[i].Action</li>*#
<li class="notiContentLi"><a href='#Url.ActionLink("Details","Requisition",new{#viewDataProd[i].RequisitionId})'> click me </a>#viewDataProd[i].Action</li>
}
}
</ul>
</div>
<div class="seeAll">See All</div>
</div>

You can add the onclick event to the <li> tag:
#for (var i = 0; i < viewDataProd.Count; i++)
{
<li class="notiContentLi" onclick="location.href = '#(Url.Action("Details", "Requistion", new { id = viewDataProd[i].RequisitionId }))'" >#viewDataProd[i].Action</li>
}
And the Details action method declaration in the Requistion controller is:
public ActionResult Details(int id)
{
// Add your action code here...
}

Adding route values and html attributes does the trick
var viewDataProd = GlobalVariables.messageList as List<Notification>;
#for (var i = 0; i < viewDataProd.Count; i++)
{
<li class="notiContentLi">#Html.ActionLink(#viewDataProd[i].Action, "Details", "Requisition", routeValues: new { #viewDataProd[i].RequisitionId }, htmlAttributes: new { target = "_blank" })</li>
}

Index.cshtml
...
<div class="card-columns">
#foreach (var yourElement in Model.YourElements)
{
<div class="card">
<div class="card-body"
onclick="location.href =
'/AnotherElementsPage/ByID/?ID=#yourElement.AnotherElement.ID'" >
<h6 class="card-title">#yourElement.Name</h6>
<h7 class="card-text">#yourElement.Description</h7>
</div>
</div>
}
</div>
AnotherElementsPage.cshtml
#page "{handler?}"
AnotherElementsPage.cshtml.cs
public AnotherElementsService AnotherElementsService;
[BindProperty(SupportsGet = true)]
public IEnumerable<AnotherElement> AnotherElements { get; private set; }
public void OnGet()
{
AnotherElements = AnotherElementsService.GetAnotherElements().ToList();
}
public void OnGetByID(Guid ID)
{
AnotherElements = AnotherElementsService.GetAnotherElement(ID).ToList();
}

Related

Passing object from View to Controller ASP.NET MVC

so my intention is to make a button that allow a user to add an item to his Cart, in the db.savechanges method it catch these exceptions :
Property: Item_Name Error: The Item_Name field is required.
iisexpress.exe Information: 0 : Property: Item_Description Error:
The Item_Description field is required. s
i checked from my db and every single item has all their properties filled up, since i am new to asp.net i am surely missing something obvious that is messing with my data.
this is the view(trying to pass the item object in actionlink
#foreach (var item in Model)
{
if (index > 6)
{
index = 0;
}
var newrow = 0;
if (index == 0)
{
newrow = 1;
}
if (newrow == 1)
{
index++;
<div class="product-one">
<div class="col-md-2 product-left">
<div class="p-one simpleCart_shelfItem jwe">
<a href="single.html">
<!-- go to product single view page-->
#{ if (item.Image.Image1 != null)
{
string imageBase64 = Convert.ToBase64String(item.Image.Image1);
string imageSrc = string.Format("data:image/png;base64,{0}", imageBase64);
<img src="#imageSrc" width="100" height="100" />
}
}
#Html.ActionLink("Add to Cart", "AddToCart", "Carts", new { itemdata = item }, new { #class = "btn btn-primary btn-large" })
</a>
<br />
</div>
</div>
</div>
this is the controller:
public ActionResult AddToCart(Item item)
{
//var query = from itemsel in db.Items where item.Item_ID == item.Item_ID select item;
var newcart = new Cart();
newcart.Account_ID = 1;
newcart.Cart_ID = 3;
newcart.Item_ID = item.Item_ID;
newcart.Item = item;
var itemsgroup = db.Items;
try
{
db.Carts.Add(newcart);
db.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}",
validationError.PropertyName,
validationError.ErrorMessage);
}
}
}
return View(itemsgroup.ToList());
}
and this is the cart model:
public partial class Cart
{
public int Cart_ID { get; set; }
public int Account_ID { get; set; }
public int Item_ID { get; set; }
public virtual Item Item { get; set; }
}
}
p.s i know my view is tricky but i am desperate to finish this project very soon, any suggestion for a better way of doing it would be welcomed
Since you are missing too many pieces, I could only point you to right direction.
Download the sample source code of Pro ASP.NET MVC 5 book By Adam Freeman.
Extract Chapter 9 - SportsStore, and look at those two files-
SportsStore.WebUI > Views > Product > List.cshtml
#foreach (var p in Model.Products) {
#Html.Partial("ProductSummary", p)
}
SportsStore.WebUI > Views > Shared > ProductSummary.cshtml
Notice that it uses BeginForm to add individual item to shopping cart.
#using (Html.BeginForm("AddToCart", "Cart")) {
<div class="pull-right">
#Html.HiddenFor(x => x.ProductID)
#Html.Hidden("returnUrl", Request.Url.PathAndQuery)
<input type="submit" class="btn btn-success" value="Add to cart" />
</div>
}

using an accordion for each record

I'm passing a list of files along with their directories to my Razor view. I have successfully managed to list them all to facilitate downloading however I have now been asked to organise them in an accordion style.
I am trying to use JqueryUi's accordion however it is proving difficult to implement it whilst using a for each to populate the links.
this is what I have thus far:
#foreach (var fullPath in Model)
{
var fileName = Path.GetFileName(fullPath);
var parent = System.IO.Directory.GetParent(fullPath);
string parentString = parent.ToString();
var downloadPath = #Path.GetDirectoryName(fullPath) + "\\" + #fileName;
string yearOne = Server.MapPath("~/Pdfs/YearOne");
string yearTwo = Server.MapPath("~/Pdfs/YearTwo");
<div id="accordion">
#*<h3>Year One</h3>*#
#if (parentString == yearOne)
{
<div>
<p>
<ul>
<li>#Html.ActionLink(fileName, "Download", new { path = downloadPath }) </li>
</ul>
</p>
</div>
}
#*<h3>Year Two</h3>*#
#if (parentString == yearTwo)
{
<div>
<p>
<ul>
<li>#Html.ActionLink(fileName, "Download", new { path = downloadPath }) </li>
</ul>
</p>
</div>
}
</div>
}
What's happening is, its placing the first record in the appropriate accordion section, then the rest are just listed below. Can anyone suggest how I might achieve this requirement within a for each?
The logic of finding which path is for year one and which is for year two could be moved into the controller. The corresponding model could be:
public class AccordionModel
{
public List<string> YearOne { get; set; }
public List<string> YearTwo { get; set; }
}
The view could be changed to:
#model AccordionModel
#functions {
string GetFileName(string path)
{
var fileName = Path.GetFileName(path);
return fileName;
}
string GetDownloadPath(string path)
{
var fileName = Path.GetFileName(path);
var parent = System.IO.Directory.GetParent(path);
string parentString = parent.ToString();
var downloadPath = Path.GetDirectoryName(path) + "\\" + fileName;
return downloadPath;
}
}
<div id="accordion">
#*<h3>Year One</h3>*#
<div>
<p>
<ul>
#foreach(var path in Model.YearOne)
{
<li>#Html.ActionLink(GetFileName(path), "Download", new { path = GetDownloadPath(path) }) </li>
}
</ul>
</p>
</div>
#*<h3>Year Two</h3>*#
<div>
<p>
<ul>
#foreach(var path in Model.YearTwo)
{
<li>#Html.ActionLink(GetFileName(path), "Download", new { path = GetDownloadPath(path) }) </li>
}
</ul>
</p>
</div>
</div>

Pass id value from view which is receiving IEnemerable List

I want to pass id value from my view . I am using Html.ActionLink attribute.
I am performing like this
#foreach (var item in Model)
{
<div class="grid_1_of_4 images_1_of_4">
<img src="/#item.p_imageUrl" alt="" />
<h2>#item.p_name </h2>
<div class="price-details">
<div class="price-number">
<p><span class="rupees">#item.p_price</span></p>
</div>
#Html.ActionLink("Add to Cart", "Mobiles", new { id = item.ProductId }, new { #class = "add" })
<div class="clear"></div>
</div>
</div>
}
but this doesnot posting it instead get action is calling in controller.How to fix that
You can use the one action for both things using optional parameter feature, no need of making another action:
public ActionResult Mobiles(int id=0)
{
// id will be initialized 0 when no id passed to action
if(id > 0)
{
// if id is coming do something here
var q = from n in db.Mobiles
where n.ProductId == id
select n;
return View(q);
}
else
{
var q = from n in db.Mobiles
select n; // id is not passed
return View(q);
}
}

How to create Paging in PartialView

I want in Home/Index Load Partial View I Write This Code:
NewsPagingViewModel class:
public class NewsPagingViewModel
{
public IList<DommainCalsses.Models.News> News { get; set; }
public int CurrentPage { get; set; }
public int Count { get; set; }
public int Term { get; set; }
public int Page { get; set; }
public int TotalRecords { get; set; }
}
In Controller
public virtual ActionResult ShowNews(int page=0)
{
return PartialView(Views._News, new Posc.Model.News.NewsPagingViewModel() { CurrentPage = page, Count = 3, News = _newsService.GetList(page, 3), Term = 0, Page = page, TotalRecords = _newsService.GetCount() });
}
In _News partialView
#model Posc.Model.News.NewsPagingViewModel
#{
int currentPage = Model.CurrentPage + 1;
int count = Model.Count;
int max = (Model.TotalRecords % count == 0) ? Model.TotalRecords / count : (Model.TotalRecords / count) + 1;
const int size = 8;
int firstPage = ((currentPage - size) <= 0) ? 0 : currentPage - size;
int lastPage = ((currentPage + size) >= max) ? max : currentPage + size;
}
<div id="label-table">
#foreach (var item in Model.News)
{
<div class="row">
<div class="col-sm-1" style="padding-left: 5px;margin-left: 5px;">
<img src="#item.Image" />
</div>
<div class="col-sm-5">
#Html.ActionLink(item.Abstract, MVC.Admin.News.Index())
</div>
</div>
}
#* Page Navigation *#
<div class="pagination pagination-centered">
<ul>
#if (currentPage - 1 == firstPage)
{
<li class="active"><a>First</a></li>
}
else
{
<li>
#Ajax.ActionLink("First", MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = 0, count = Model.Count }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "label-table", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
}
#for (int i = firstPage; i < lastPage; i++)
{
#*if (i + 1 == currentPage)
{
<li class="active"><a>#i+1</a></li>
#*Html.ConvertToPersianString(i + 1)
}
else
{*#
<li>
#*Html.ConvertToPersianString(i + 1).ToString()*#
#Ajax.ActionLink((#i + 1).ToString(), MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = #i }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "News", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
#*}*#
}
#if (currentPage == lastPage)
{
<li class="active"><a>Last</a></li>
}
else
{
<li>
#Ajax.ActionLink("Last", MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = 0, count = Model.Count }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "News", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
}
</ul>
</div>
</div>
And In Home/Index
<div id="News">
#Html.Action(MVC.Admin.News.ShowNews())
</div>
In the First Run Good Like This:
but when click in pagging Redirect to partial view Like this:
But I Want Refresh Partial View In Home/Index.
I would suggest you use the PagedList library. Its so awesome that Microsoft decided to use the library in their official tutorials (full tutorial here)
It provides a very clean code while doing pagination. See sample codes below.
Step 1
Add the PagedList.Mvc library using Nuget. https://www.nuget.org/packages/PagedList.Mvc/
Step 2
Integrate PagedList in your action method. Here is an example on how you could do it.
using PagedList;
public ActionResult ShowNews(int? page)
{
int currentPage = (page ?? 1);
// Fix negative page
currentPage = currentPage < 0 ? 1 : currentPage;
int pageSize = 3;
IEnumerable<Models.News> newsModels = newsService.GetList(currentPage, pageSize);
return View(newsModels.ToPagedList(currentPage, pageSize));
}
Step 3
Integrate PagedList in your View
#model PagedList.IPagedList<Models.News>
#using PagedList.Mvc;
#foreach (var item in Model.News)
{
<div class="row">
<div class="col-sm-1" style="padding-left: 5px;margin-left: 5px;">
<img src="#item.Image" />
</div>
<div class="col-sm-5">
#Html.ActionLink(item.Abstract, MVC.Admin.News.Index())
</div>
</div>
}
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action(MVC.Admin.News.ActionNames.ShowNews))
See complete tutorial here http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application

How do I call a partial view that expects a IEnumerable collection in a view that gets a model object?

I am trying to build a version of WordPress in MVC4. Currently I am working on the page view.
I've decided that in this view I should also include a menu of all the other pages that have been created.
This is my method for the showPage view:
public ActionResult showPage(string myTitle)
{
var query = from a in db.Pages
where a.title == myTitle
select a;
PageModels item = new PageModels();
item = query.FirstOrDefault<PageModels>();
if (item != null)
{
return View(item);
}
else
{
item.content = "No page with title :" + myTitle + " found.";
return View(item);
}
}
This is my method for the partial I am trying to render:
public ActionResult List()
{
return View(db.Pages.ToList());
}
This is how my view looks like:
#model Dynamic_Web_Pages.Models.PageModels
#{
ViewBag.Title = "Page Preview";
}
#Html.Partial("_ListPartial", new IEnumerable<Dynamic_Web_Pages.Models.PageModels>)
<div class="content">#Html.Raw(Model.content)</div>
Finally this is my partial:
#model IEnumerable<Dynamic_Web_Pages.Models.PageModels>
<div class="dropdown">
#foreach (var page in Model)
{
if(page.parent == 0)
{
<div class="btn-group">
<a class="btn dropdown-toggle" id="#Html.DisplayFor(modelItem => page.id)" role="button" data-toggle="dropdown" data-target="#" href="/#Html.DisplayFor(modelItem => page.title)" >#Html.DisplayFor(modelItem => page.title)
<b class="caret"></b>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="#Html.DisplayFor(modelItem => page.id)">
#foreach (var child in Model)
{
if (child.parent == page.id)
{
<li><a class="child" href="/#Html.DisplayFor(modelItem => child.title)" >#Html.DisplayFor(modelItem => child.title)</a></li>
}
}
</ul>
</div>
}
}
</div>
I get the following error in my view:
Cannot create an instance of the abstract class or interface 'System.Collections.Generic.IEnumerable<Dynamic_Web_Pages.Models.PageModels>'
What should be the second argument of the #Html.Partial be?
Your view accepted a single instance of PageModels
#model Dynamic_Web_Pages.Models.PageModels
#{
ViewBag.Title = "Page Preview";
}
and yet you are passing that in your partial that accepts an IEnumerable and so you got that exception.
Now based on our conversation in your comments, you can load the partial using jquery:
<script>
$("#navmenu").load('#Url.Action("List")');
</script>
where you replace this code:
#Html.Partial("_ListPartial", new IEnumerable<Dynamic_Web_Pages.Models.PageModels>)
// with this
<div id="navmenu"></div>
remove new IEnumerable
and just keep it as
Html.Partial("_ListPartial") in the view
So you should return PartialView instead of view see below code
public ActionResult List()
{
return PartialView (db.Pages.ToList());
}

Resources