Partial View MVC 4 in foreach loop - asp.net-mvc

I'm using MVC 4 Ajax.BeginForm to update but it updates only the first element <div>
the View:
#model List<CSP1225.Models.Item>
#{
ViewBag.Title = "RecentItems";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<link href="~/CSS/jobs.css" rel="stylesheet" />
#{ var convert = ViewBag.convert;
}
<div>
#foreach (var item in Model)
{
<div class="job-item">
<div class="inner">
<div class="span8 job-span">
<!--start of job list container div-->
<div id="ja-joblist">
<ol id="ja-searchjoblist">
<li class="job-item">#{ var PriceLE = #item.Price * convert;}
#using (#Ajax.BeginForm("_AddToCart", "Home", item, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "cart" }, null))
{
<!-- job item right section-->
<div class="inner">
<div class="ja-job-meta clearfix">
<span class="ja-job-category">#item.ItemName</span>
<span class="ja-job-category">#item.Price $</span>
<span class="ja-job-category">#PriceLE LE</span>
<div id="cart"></div>
<button type="submit">Add to Cart</button>
</div>
</div>
} </li>
<!-- end of job item right section-->
<!-- end of job item -->
</ol>
</div>
</div>
</div>
</div>
}
#Html.ActionLink("Go Back", "Index", "Home", new { #class = "makeneworder" })
</div>
and Controller:
public ActionResult _AddToCart(Item model)
{
ItemModel it = new ItemModel();
it.itemName = model.ItemName;
it.itemUrl = model.ItemURL;
it.quantity = 1;
it.unitprice = model.Price;
it.weight = (int)model.Weight;
it.ItemCategory =(int)model.CategoryID;
CartList.Add(it);
ViewBag.convert = (decimal)_db.Currencies.Where(x => x.Name == "Dollar").FirstOrDefault().Value;
ViewBag.list = CartList;
return PartialView();
}
Partial view :
<p>Added to Cart</p>
but the view returns multiple elements (as long as the list contains elements) when i click Add to Cart it updates the first element.. i understand that because u can not give another <div> the same id but how can i fix it?

you can create a dynamic ID like
#{ var divID = 1; }
then use it like
UpdateTargetId = "cart" + divID }
and
<div id="cart#divID" ></div>

Related

ERROR:The model item passed into the dictionary is of type...but this dictionary requires a model item of type..."

I'm quite new to programming and I'm having some issues when i'm trying to run the program. I keep on getting this error:"The model item passed into the dictionary is of type 'DCMS.Models.Projects.Project', but this dictionary requires a model item of type 'DCMS.ViewModels.ProjectDetailsViewModel'".
This is my Controller:
public ActionResult GetProjectView(int id)
{
var projectDataAccess = new ProjectDataAccess();
var project = projectDataAccess.GetProject(id);
if (project == null) return PartialView("Error");
return View("ProjectView", project);
}
This is part of my View:
#model DCMS.ViewModels.ProjectListViewModel
#if (Model != null)
{
foreach (var project in Model.ProjectList)
{
<div class="accordion-container">
<h3 class="accordion-header">
#Html.ActionLink(project.Client.ClientName + " / " + project.ProjectName + " / " + project.ProjectNum ?? "<null>", "GetProjectView", new {id = project.Id})<span class="right">#Html.ActionLink("View Details", "GetProjectView", new {id = project.Id})</span>
</h3>
<div class="accordion-body">
<table class="accordion-details">
<tr class="accordion-evenrow">
<td class="accordion-header-column">
#Html.LabelFor(m => project.ProjectStatus)
</td>
<td class="accordion-value-column">
#project.ProjectStatus
</td>
This is the ProjectView:
#model DCMS.ViewModels.ProjectDetailsViewModel
#{
ViewBag.Title = "Project Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2 id="breadcrumbs">#Html.ActionLink("Projects", "Index", "Project") > #(Model.Project.ProjectName ?? "<null>")/#Model.Project.ProjectNum </h2>
<div id="tabs">
<ul id="projectTabs" style="display:none;">
<li>Project Details</li>
<li>Client Pricing</li>
<li>Vendor Pricing</li>
<li>Status</li>
</ul>
<h2 style="margin:1px; font-size:20px;">#Model.Project.ProjectName /#Model.Project.ProjectNum</h2>
<div id="projectdetails">
#Html.Partial("Partial/EditProject")
</div>
<div id="pricing">
#Html.Partial("Partial/Pricing")
</div>
<div id="status">
#Html.Partial("Partial/ProjectStatus")
</div>
<div id="vendor">
#Html.Partial("Partial/VendorPricing")
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$("#projectTabs").show();
$("#tabs").tabs();
});
</script>
How can i pass the project which is of type Project to the View which is of type ProjectDetailsViewModel?
I would appreciate any help on this. Thanks.
As the Error States,
The model item passed into the dictionary is of type
'DCMS.Models.Projects.Project', but this dictionary requires a model
item of type 'DCMS.ViewModels.ProjectDetailsViewModel'
ViewModel and the Model passed should be same.
public ActionResult GetProjectView(int id)
{
ProjectDetailsViewModel _projectModel = new ProjectDetailsViewModel();
var projectDataAccess = new ProjectDataAccess();
var project = projectDataAccess.GetProject(id);
_projectModel.Project = project ;
if (project == null) return PartialView("Error");
return View("ProjectView", _projectModel );
}

DOT Exception When Trying To Open/Call a Funtion

I have a problem with calling my function that show the books for same author, for example I have a these authors :
Author Name : Jeremy McPeak; Joe Fawcett; Nicholas C. Zakas;
When I click on "Jeremy McPeak" and "Joe Fawcett" the new page opened well and show all the books for those authors .
But when click on this author "Nicholas C. Zakas" and since he has a DOT in his name , I got exception
Object reference not set to an instance of an object.
This problem only when I click on any author that have a DOT In his name ..
also here is my function :
public ActionResult Author(string AuthorName, int? page)
{
if (AuthorName != null)
{
ViewBag.AuthorName = AuthorName;
int pageSize = 6;
int pageNumber = page ?? 1;
var result = db.Books.Where(s => s.Author_name.Contains(AuthorName)).OrderByDescending(x => x.Book_id).ToList();
return View(result.ToPagedList(pageNumber, pageSize));
}
return RedirectToAction("Index", "Home");
}
Author View Code:
#using PagedList.Mvc
#using System.Text.RegularExpressions;
#model PagedList.IPagedList<SmartBookLibrary.Models.Book>
#{
ViewBag.Title = "Books For " + ViewBag.AuthorName+ "- Smart Books Library";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section AdditionalMeta
{
<meta name="robots" content="index,follow">
}
<div class="container">
<!-- Page Header -->
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">
<span class="fa fa-pencil"></span>#ViewBag.AuthorName
</h1>
</div>
</div>
<!-- /.row -->
<!-- Projects Row -->
<div class="row">
#foreach (var item in Model)
{
<div class="col-md-4 portfolio-item" style="margin-bottom:10px;height:450px">
<div class="ih-item square effect3 bottom_to_top">
<a href="~/book/#item.Book_id/#item.UrlSlug">
<div class="img"><img itemprop="image" class="img-responsive" src="~/Images/#item.Book_Image" alt="#item.Book_name" title="#item.Book_name"></div>
<div class="info">
<h3>#item.Book_name</h3>
</div>
</a>
</div>
<h3 itemprop="name">
<a href="~/book/#item.Book_id/#item.UrlSlug">
#item.Book_name
#if (item.Edition != 0)
{
switch (item.Edition)
{
case 1:<small class="btn btn-default btn-xs">#item.Edition'St Edition</small> break;
case 2:<small class="btn btn-default btn-xs">#item.Edition'nd Edition</small> break;
case 3:<small class="btn btn-default btn-xs">#item.Edition'rd Edition</small> break;
case 4 - 10:<small class="btn btn-default btn-xs">#item.Edition'th Edition</small> break;
default:<small class="btn btn-default btn-xs">#item.Edition'th Edition</small> break;
}
}
</a>
</h3>
<p itemprop="description">
#*#Html.Raw(item.Book_Description)*#
</p>
</div>
}
</div>
<!-- /.row -->
<hr>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Author", new { AuthorName = ViewBag.AuthorName, page }))
</div>
Calling Area :
#{
var s = Model.Book.Author_name.ToString();
string[] Auth = s.Split(',');
ViewBag.Author = Auth;
}
<p itemprop="author">
<i class="glyphicon glyphicon-pencil"></i> <b>Author Name :</b>
#for (int i = 0; i < Auth.Length; i++)
{
<a style="color:#777777" href="~/Author/#Auth[i]">#Auth[i];</a>
}
</p>
Any one know how to fix that ?
I test code in Author action without return View(result.ToPagedList(pageNumber, pageSize));
There is no problem.I think, ToPagedList has caused an error. result.ToPagedList(pageNumber, pageSize) is null.
You trace it.

ASP.Net MVC Show/Hide Content

Ok I have the following View
#model IEnumerable<WebApplication3.Models.user>
#{
ViewBag.Title = "Password Management";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section title {<h1>#ViewBag.Title</h1>}
<div id="page-block" class="page-block-three row">
<div style="margin-top: 30px;" class="col-lg-offset-2 col-lg-8">
#using (Html.BeginForm())
{
<div class="input-group">
#Html.TextBox("SearchString", null, new { #class = "form-control ccl-form", #style = "z-index: 10", #placeholder = "Enter Username"})
<div class="input-group-btn">
<button class="btn ccl-btn ccl-btn-red ccl-btn-search" type="submit"><i class="fa fa-search"></i></button>
</div>
</div>
}
</div>
<div class="col-lg-offset-3 col-lg-6">
#foreach (var item in Model)
{
<div class="details-block">
#Html.DisplayFor(modelItem => item.UserName)
<button type="button" class="btn ccl-btn ccl-btn-green ccl-btn-search pull-right">Select User</button>
</div>
}
</div>
</div>
What I want to be able to do is hide the following div
<div class="col-lg-offset-3 col-lg-6">
#foreach (var item in Model)
{
<div class="details-block">
#Html.DisplayFor(modelItem => item.UserName)
<button type="button" class="btn ccl-btn ccl-btn-green ccl-btn-search pull-right">Select User</button>
</div>
}
</div>
Then show that Div when the submit button is clicked
My Controller looks like the following
public class PasswordController : Controller
{
private CCLPasswordManagementDBEntities db = new CCLPasswordManagementDBEntities();
public ActionResult Search(string searchString)
{
var users = from x in db.users select x;
if (!String.IsNullOrEmpty(searchString))
{
users = users.Where(x => x.UserName.ToUpper().Contains(searchString.ToUpper()));
}
return View(users);
}
}
At the moment the div is constantly shown and updates when the submit button is pressed but I want to hide that div until someone presses the submit button then it can show.
Thanks in advance for the help.
Change your code in the controller to this:
public ActionResult Search(string searchString)
{
var users = from x in db.users select x;
ViewBag.ShowList = false;
if (!String.IsNullOrEmpty(searchString))
{
ViewBag.ShowList = true;
users = users.Where(x => x.UserName.ToUpper().Contains(searchString.ToUpper()));
}
return View(users);
}
And change your view to this:
#model IEnumerable<WebApplication3.Models.user>
#{
ViewBag.Title = "Password Management";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section title {<h1>#ViewBag.Title</h1>}
<div id="page-block" class="page-block-three row">
<div style="margin-top: 30px;" class="col-lg-offset-2 col-lg-8">
#using (Html.BeginForm())
{
<div class="input-group">
#Html.TextBox("SearchString", null, new { #class = "form-control ccl-form", #style = "z-index: 10", #placeholder = "Enter Username"})
<div class="input-group-btn">
<button class="btn ccl-btn ccl-btn-red ccl-btn-search" type="submit"><i class="fa fa-search"></i></button>
</div>
</div>
}
</div>
#if(ViewBag.ShowList){
<div class="col-lg-offset-3 col-lg-6">
#foreach (var item in Model)
{
<div class="details-block">
#Html.DisplayFor(modelItem => item.UserName)
<button type="button" class="btn ccl-btn ccl-btn-green ccl-btn-search pull-right">Select User</button>
</div>
}
</div>
}
</div>
You can try having a flag (ViewBag.isShown = false;)
When the page refreshes, it will show your div.
Code should be like below:
if (ViewBag.isShown == true)
{
..your for each block..
}

PagedListPager page always null

This used to work... but now the >> anchor tag of the PagedListPager always passes null to the controller for the page value required...
VS 2013 Web Express & MVC 4 with latest package updates for all.
Just like in Scot Allen's MVC 4 intro, I have a partial view with a PagedListPager
The Controller:
public ActionResult Catalog(string Id= "0", int page=1)
{
var CurrentItemsPage = (get-data-blaw-blaw-blaw).ToPagedList(page,18);
var model = new ShowRoomCatalogPackage(){ CurrentItems = CurrentItemsPage};
return View(model);
}
The catalog page
#model craftstore.Models.ShowRoomCatalogPackage
#{
ViewBag.Title = "Catalog";
Layout = "~/Views/Shared/_Details.cshtml";
}
#using (Ajax.BeginForm("Catalog", "Home", new { category = #Model.SelectedCategoryId, page = 1 },
new AjaxOptions
{
UpdateTargetId = "products",
InsertionMode = InsertionMode.Replace,
HttpMethod = "post"
}
)
)
{
<div class="container" >
<div class="row">
<div class="col-lg-10 col-md-5 col-sm-4 dropdown-menu">
#Html.LabelFor(m => m.SelectedCategoryId)
#Html.DropDownList("id", Model.CategoryItems, new { #id = "ddlCategories", onchange = "this.form.submit();" })
</div>
<div class="col-lg-2 col-md-2 col-sm-1">
#Html.ActionLink("Your Cart", "Index", "ShoppingCart", "", new { #class = "btn btn-green btn-lg" })
</div>
</div>
<div class="row">
#Html.Partial("_CatalogPartial", Model.CurrentItems)
</div><!-- row -->
</div><!-- container -->
}
<br />
<br />
#section Scripts
{
<script type="text/javascript">
new AnimOnScroll(document.getElementById('grid'), {
minDuration: 0.4,
maxDuration: 0.7,
viewportFactor: 0.2
});
</script>
}
The partial view:
#model IPagedList<ShowroomCatalog>
<div id="productList">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="pagedList" data-cs-target="#productList">
#Html.PagedListPager(Model, page => Url.Action("Index", new { category = ViewBag.SelectedCategoryId, page }), PagedListRenderOptions.MinimalWithItemCountText)
</div>
<ul class="grid effect-2" id="grid">
#foreach(var item in Model)
{
var path = String.Format("~/Content/Images/catalog/{0}/{1}", item.OfferType, item.ImagePath);
<li>
<div class="itembox">
<div class="imagebox">
<a href="#Url.Action("Detail", "Home", new { id = item.Id })" title="Detail for #item.CatalogName">
<img class="catalogimg" src="#Url.Content(path)" />
</a>
</div>
<p>#item.CatalogName</p>
</div>
</li>
}
</ul>
</div>
</div><!-- productlist -->
Now the rendered partialview in the browser doesn't have anything in the anchors which may or may not be normal...
<div class="pagedList" data-cs-target="#productList">
<div class="pagination-container"><ul class="pagination"><li class="disabled PagedList-skipToPrevious"><a rel="prev">«</a></li><li class="disabled PagedList-pageCountAndLocation"><a>Showing items 1 through 18 of 65.</a></li><li class="PagedList-skipToNext">»</li></ul></div>
</div>
And when you hover on the >> it doesn't show the page parameter in the URL:
Again, back in the Controller - I get the category (15) but no page parameter or Request.URL parameter is passed to the controller - it's not hiding because of some routing mistake...I think...
How do I get the paging control to work again...???
[EDIT: one more note - the url path on the pager is /controller/action/category/page rather than what shows up on Scot Allen's OdeToFood example where it's equivalent would be /controller/action/category?page=n (like /Home/Catalog/15?page=1 ]
I was missing the JS for the PagedList class anchor element.
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
data: $("form").serialize(),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-otf-target");
$(target).replaceWith(data);
});
return false;
};
And this is fired off by :
$(".main-content").on("click", ".pagedList a", getPage);
BUT, this means you need to have your #RenderBody() call in your _Layout.cshtml file wrapped in something with a class of main-content. An example:
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>

Partial View with self updating

I'm learning ASP.NET MVC and I've encountered a problem in my practice project (MVC Music Store). I have made a partial view to search for an artist. I expect the partial view to take no arguments and work on its own.
Partial view in the right half part
I have a view specific model for the Artist Search Partial View. The model is as follows:
public class ArtistSearch
{
public string SearchString { get; set; }
public List<Artist> SearchResult { get; set; }
public ArtistSearch()
{
SearchResult=new List<Artist>();
}
}
Controller code is as follows:
public ActionResult Search(string query)
{
ArtistSearch asResult = new ArtistSearch();
if (query != null)
{
var temp = from a in db.Artists
where a.Name.Contains(query)
select a;
asResult.SearchResult = temp.ToList();
asResult.SearchString = query;
}
return PartialView(asResult);
}
The Partial View is as follows:
#model MvcMusicStore.Models.ArtistSearch
<div class="big-search-box">
<form action="#Url.Action("Search","Artist")" method="post" role="form">
<div class="input-group">
#Html.TextBox("query", #Model.SearchString, new { #class = "form-control nrb input-lg", placeholder = "Input your search query..." })
<div class="input-group-btn">
<input type="submit" name="Send" value="Search" class="btn btn-primary btn-iconed btn-lg" />
</div>
</div>
</form>
</div>
<div class="big-search-result-info clearfix">
<div class="pull-left">Showing results for <strong>#Model.SearchString</strong>.</div>
<div class="pull-right"><strong>#Model.SearchResult.Count</strong> artist(s) found.</div>
</div>
<table>
#foreach (var item in #Model.SearchResult)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a href="#item.Id" >
<img src=#item.PhotoURL alt=#item.Name style="width:100px;height:70px;">
</a>
</td>
</tr>
}
</table>
I wish to place this partial view anywhere on the site. Lets say i placed it(using RenderAction) on Artist/Index Controllers View page.
The simple functionality that I'm trying to achieve is that when i click on search it should self update the partial view with search results. Right now it is transferring me to Artist/Search page.
Thanks for the patience.
Try to use Ajax.BeginForm, below is an example:
Action
public ActionResult Search(string query)
{
ArtistSearch asResult = new ArtistSearch();
if (query != null)
{
var temp = from a in db.Artists
where a.Name.Contains(query)
select a;
asResult.SearchResult = temp.ToList();
asResult.SearchString = query;
}
return PartialView("MyParitalView",asResult);
}
View
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("Search", "Home", new AjaxOptions { UpdateTargetId = "result" }))
{
<div class="input-group">
#Html.TextBox("query", #Model.SearchString, new { #class = "form-control nrb input-lg", placeholder = "Input your search query..." })
<div class="input-group-btn">
<input type="submit" name="Send" value="Search" class="btn btn-primary btn-iconed btn-lg" />
</div>
</div>
}
<div id="result"></div>
Parital View : MyParitalView
#model MvcMusicStore.Models.ArtistSearch
<div class="big-search-result-info clearfix">
<div class="pull-left">Showing results for <strong>#Model.SearchString</strong>.</div>
<div class="pull-right"><strong>#Model.SearchResult.Count</strong> artist(s) found.</div>
</div>
<table>
#foreach (var item in #Model.SearchResult)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a href="#item.Id">
<img src=#item.PhotoURL alt=#item.Name style="width:100px;height:70px;">
</a>
</td>
</tr>
}
</table>

Resources