PagedListPager page always null - asp.net-mvc

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>

Related

Partial View replaces Parent view

I'm working on web app developed in ASP.Net MVC, having a partial view which should be rendered inside its parent view.
Parent view has a HTML Dropdown, on-change event should bind respective data to partial view. But on selection change, the complete parent view is replaced with partial view (child view).
Parent View (Index.cshtml)
<h3>Please Select Group</h3>
#using (Html.BeginForm("EmployeeDeptHistory", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
if (ViewBag.DepartmentList != null)
{
#Html.DropDownList("DepartmentName", ViewBag.DepartmentList as SelectList, "-- Select --", new { Class = "form-control", onchange = "this.form.submit();" })
}
}
<div>
#{Html.RenderPartial("_EmployeeDeptHistory");}
</div>
Partial View (_EmployeeDeptHistory.cshtml)
#model IEnumerable<PartialViewApplSol.Models.EmployeeDepartmentHistory>
#if (Model != null)
{
<h3>Employees Department History : #Model.Count()</h3>
foreach (var item in Model)
{
<div style="border:solid 1px #808080; margin-bottom:2%;">
<div class="row">
<div class="col-md-2">
<strong>Name</strong>
</div>
<div class="col-md-5">
<span>#item.Name</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Shift</strong>
</div>
<div class="col-md-5">
<span>#item.Shift</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Department</strong>
</div>
<div class="col-md-5">
<span>#item.Department</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Group Name</strong>
</div>
<div class="col-md-5">
<span>#item.GroupName</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Start Date</strong>
</div>
<div class="col-md-5">
<span>#item.StartDate</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>End Date</strong>
</div>
<div class="col-md-5">
<span>#item.EndDate</span>
</div>
</div>
</div>
}
}
I think the possible mistake is returning partial-view on drop down selection changed.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EmployeeDeptHistory(FormCollection form)
{
IEnumerable<EmployeeDepartmentHistory> empHistList;
using (IDbConnection con = new SqlConnection(connectionString))
{
empHistList = con.Query<EmployeeDepartmentHistory>("sp_StoredProc", new { DeptId = form["DepartmentName"] }, commandType: CommandType.StoredProcedure);
}
return View("_EmployeeDeptHistory", empHistList);
}
Instead of standard form submit, you need to use jQuery.ajax() function to load partial view inside HTML element without replacing parent view. Here are those steps:
1) Remove onchange event from DropDownList helper, and assign AJAX callback bound to change event:
View
#Html.DropDownList("DepartmentName", ViewBag.DepartmentList as SelectList, "-- Select --", new { #class = "form-control" })
jQuery (inside$(document).ready())
$('#DepartmentName').change(function () {
var selectedValue = $(this).val();
if (selectedValue && selectedValue != '')
{
$.ajax({
type: 'POST',
url: '#Url.Action("EmployeeDeptHistory", "ControllerName")',
data: { departmentName: selectedValue };
success: function (result) {
$('#targetElement').html(result); // assign rendered output to target element's ID
}
});
}
});
2) Remove FormCollection and use a string argument which has same name as AJAX callback argument, also make sure the action method returns PartialView:
Controller
[HttpPost]
public ActionResult EmployeeDeptHistory(string departmentName)
{
IEnumerable<EmployeeDepartmentHistory> empHistList;
using (IDbConnection con = new SqlConnection(connectionString))
{
empHistList = con.Query<EmployeeDepartmentHistory>("sp_StoredProc", new { DeptId = departmentName }, commandType: CommandType.StoredProcedure);
}
return PartialView("_EmployeeDeptHistory", empHistList);
}
3) Finally, don't forget to add ID for target element specified by AJAX callback's success part to load partial view:
View
<div id="targetElement">
#Html.Partial("_EmployeeDeptHistory")
</div>

Ajax.BeginForm on submit click not work and HTML.BeginForm returns partial view as view page

i have a view in which there is a section and in section there are some links; section and one link are like this:
<section id="tabs-section">
<ul id="myTab" class="my-nav nav nav-tabs nav-justified responsive-tabs col-sm-12" style="padding:0;">
<li class="active">A</li>
</ul>
<div class="tab-content col-sm-12" style="border:1px solid #000000;"#*margin-top:-20px;padding-top:20px;*#>
<div class="tab-pane fade in active" id="RegisterEditUsers">#Html.Partial("RegisterEditUsers")</div>
</div>
when i click on A a partial view in this view is shown under links. partial view is like this:
<div class="panel" style="border:1px solid #ff6a00;margin:10px 10px 0
10px;padding:10px;">
<div class="row ">
<div id="register" class="col-sm-6 col-sm-offset-0 col-sm-pull-0
col-sm-push-6 col-xs-offset-3 col-xs-pull-1 btn btn-circle ">
#Ajax.ActionLink("AA", "Register", "Account", new AjaxOptions {
HttpMethod = "Get", UpdateTargetId = "Result", InsertionMode =
InsertionMode.Replace, OnComplete = "regClick" })
</div>
<div id="edit" class="col-sm-6 col-sm-offset-3 col-xs-offset-0 btn
btn-circle">
#Ajax.ActionLink("BB", "GetUsers", "UsersAdmin", new AjaxOptions
{ HttpMethod = "Get", UpdateTargetId = "Result", InsertionMode =
InsertionMode.Replace, OnComplete = "edClick" })
</div>
</div>
</div>
<div class="panel" style="border:1px solid #ff6a00;margin:0px 10px 10px
10px;">
<div id="Result" dir="rtl"></div>
</div>
and finally when i choose AA a new partial view is loaded bellow the former partial view, that is this:
#using (Ajax.BeginForm(
"Register",
"Account",
null,
new AjaxOptions
{
HttpMethod = "Post",
UpdateTargetId = "IdentifyPerson",
InsertionMode = InsertionMode.Replace
}))
{
#Html.AntiForgeryToken();
#Html.ValidationSummary(true, "", new { #class = "text-danger" });
<div id="IdentifyPerson" style="padding:10px">
<div class="panel" style="padding:10px; direction:rtl">
<div class="row">
<div class="form-group col-md-2">
<label class="sr-only" for="LastName">:</label>
#*<input type="text" class="form-control" id="LastName"
placeholder="" name="LastName">*#
#Html.TextBoxFor(c => c.LastName, new { #class = "form-
control", placeholder = "" })
#Html.ValidationMessageFor(model => model.LastName, "",
new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="pull-left">
<button type="submit" id="RegisterBtn"
name="RegisterBtn" class="btn btn-info" style="padding:10px">AAA</button>
</div>
</div>
</div>
</div>
}
everything goes Good until i click on submit button (AAA), nothing is happened. i also use this line in my pages:
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
if i use HTML.BeginForm instead of Ajax.BeginForm submit button works fine but in return part, when i want to load the second partial view, it is loaded as a view!!
Question: what i want is: when i click on submit button Ajax.BeginForm or HTML.beginForm works and returned page shows as partial view not a view.
any one can help me?
thanks to Stephen Muecke, it seems that bundle not work properly. i don't know why really, i just added these four lines directly to partial view and it work fine :)
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-
3.1.1.min.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.validate.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>

Partial View MVC 4 in foreach loop

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>

dropdownlist in partial view not expanding

I am developing an asp.net MVC4 web app where I need to show StateList and CountryList. I am having a dropdownlist for Countries and on changing i am getting a partial view to display the corresponding States through an ajax request. The partial view has the dropdownlist for States. But once rendered, the dropdownlist for States is not expanding. Here is the code.
First View:
<div class="row" style="margin-left: 12%">
<div class="col-md-12 control-group">
<label class="col-md-4 control-label" style="margin-top :1%;"><b>Country:</b></label>
<div class="col-md-4" style="">
#Html.DropDownListFor(Function(model) model.SelectedCountryId, Model.CountryList, New With {.style = "width:100px", .type = "text", .id = "country"})
#Html.ValidationMessageFor(Function(model) model.SelectedCountryId)
</div>
</div>
</div>
<div id="stateDiv"></div>
Script:
$(document).ready(function () {
var rootUrl = $('#rootUrl').val();
$('#country').change(function () {
var countryCode = $(this).val();
$.get(rootUrl + 'GetStateList', { countryCodeId: countryCode }, function (data) {
$('#stateDiv').html(data);
}, 'html');
var isUSCAN = false;
if ($(this).val() == 1 || $(this).val() == 2) {
isUSCAN = true;
}
$('#stateSelect').toggle(isUSCAN);
$('#stateText').toggle(!isUSCAN);
var isCAN = $(this).val() == 2;
$('#provinceLabel').toggle(isCAN);
$('#stateLabel').toggle(!isCAN);
}).change();
});
Controller:
Function GetStateList(countryCodeId As Integer) As ActionResult
Return PartialView("PartialStateList", Defendant)
End Function
PartialStateList View
<div class="row" style="margin-left: 12%">
<div class="col-md-12 control-group">
<label id="stateLabel" class="col-md-4 control-label" style="margin-top :1%;"><b>State:</b></label>
<label id="provinceLabel" class="col-md-4 control-label" style="margin-top :1%;"><b>Province:</b></label>
<div class="col-md-4" style="">
#Html.DropDownListFor(Function(model) model.SelectedStateId, Model.StateList, New With {.style = "width:100px", .type = "text", .id = "stateSelect"})
#Html.TextBoxFor(Function(model) model.SelectedStateId, New With {.style = "width:100px", .value = "", .type = "text", .id = "stateText"})
#Html.ValidationMessageFor(Function(model) model.SelectedStateId)
</div>
</div>
</div>
The html that is rendered when i check in browser has the entire list of states, but when i click on the dropdownlist, it is not expanding and showing the list. Please let me know if there is something I am missing.

Model properties null on Ajax post from list box change event

I have a view which contains a list box. when users click on an item in the list box I have to post to a controller action method to see the value of the items selected/de-selected in the list box.
So it is posting to the controller action but the model is posted as null. When I post to the controller, I do serialize the form.
In other pages of my application when I serialize the form and post to the controller, the model is never null. I am not sure whats going on in this page but here is the code.
JS File
var serviceEntryURL = '#Url.Action("ServiceSystemSelection", "ServiceEntry")';
$('#systemlstbox').change(function () {
// alert('x');
var overlay = $('<div>loading errorcodes and parts..</div>').prependTo('body').attr('id', 'overlay');
$.post(serviceEntryURL,
$("#form").serialize(),
function (data) {
// $("#runDatestreeview").remove();
// $("#testExceptiontreeview").remove();
// $("#treeview").remove();
// $("#main").html(data);
// $("#ErrorCodeDisplay").empty();
}, "html");
overlay.remove();
});
View
#model RunLog.Domain.Entities.ServiceEntry
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm(new { id = "form", enctype = "multipart/form-data" }))
{
<fieldset>
<legend>Enter a new Service Log Entry</legend>
<h3>
</h3>
#Html.ValidationSummary(true)
<div class="exception">#(ViewBag.ErrorMessage)</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Service Request Number")
</span><span class="rightContent">[Generated] </span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Service Request Date / Time")
</span><span class="rightContent">
#Html.EditorFor(model => model.ServiceDateTime)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("Technician")
</span><span class="rightContent">
#Html.DropDownList("TechnicianID", String.Empty)
</span>
</div>
<div class="bodyContent">
<span class="leftContent">
#Html.Label("System")
</span><span class="rightContent">
#Html.ListBoxFor(model => model.SelectedSystemIDs, new
MultiSelectList(ViewBag.SystemID, "Text", "Value",
Model.SelectedSystemIDs), new { id = "systemlstbox", name = "listbox" })
</span>
</div>
}
Controller Action
[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ServiceSystemSelection(ServiceEntry serviceEntry)
{
}
I fixed it, the form serialization line was wrong.
$('#systemlstbox').change(function () {
// alert('x');
$.post(serviceEntryURL,
$('form').serialize(),
function (data) {
}, "html");
});

Resources