MVC3 Ajax ChildAction - ajax

I am having a difficult time figuring out how to get AJAX working with child actions in MVC3. I have a View that contains a section rendered by a child action. That child action renders a partial view which has a paged list on it. I need to make it so that when a user clicks on another page number on the page list pager only the bottem part of the view containing a list of videos will be updated. I have included my code and would really appreciate some help as I am still confused on some of the ways MVC3 works with AJAX. Thanks in advance.
My View:
#model UltimateGameDB.Domain.Entities.Video
#{
ViewBag.Title = "Video Home";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using PagedList
#using PagedList.Mvc
#section MainBanner {
<section id="videos-featured">
#Html.Partial("_Video", Model)
<div id="videos-featured-detail">
#Html.Partial("_VideoDetail", Model)
#Html.Action("MiniFeaturedVideo", "Video")
</div>
</section>
}
#Html.Action("RecentVideos", "Video", new { page = ViewBag.page })
My Controller Methods:
public ActionResult VideoHome(Guid? selectedVideoId, int? page)
{
var pageIndex = page ?? 1;
ViewBag.page = pageIndex;
if (selectedVideoId == null)
{
selectedVideoId = ugdb.Videos.Where(v => v.IsFeatured == true).OrderBy(v => v.Timestamp).FirstOrDefault().VideoID;
ViewBag.Autoplay = 0;
}
else
{
ViewBag.Autoplay = 1;
}
return View(ugdb.Videos.Find(selectedVideoId));
}
[ChildActionOnly]
public ActionResult RecentVideos(int? page)
{
IQueryable<Video> videoList = ugdb.Videos.OrderBy(v => v.Timestamp);
var pageIndex = page ?? 1;
var onePageOfVideos = videoList.ToPagedList(pageIndex, 8);
ViewBag.OnePageOfVideos = onePageOfVideos;
return PartialView("_RecentVideos");
}
My Partial View:
#using PagedList
#using PagedList.Mvc
<div id="main-content" class="videos">
<section>
<a class="body-title"><span>RECENT VIDEOS</span><span class="title-arrow"></span></a>
<div class="main-hr"></div>
#foreach (var video in ViewBag.OnePageOfVideos)
{
<a class="video-entry" href="#Url.Action("VideoHome", "Video", new { selectedVideoId = video.VideoID })">
<img src="http://img.youtube.com/vi/#video.YouTubeID/default.jpg" alt="#video.VideoName" />
<div class="video-details">
<h2>#video.VideoName</h2>
<p>#video.VideoType</p>
</div>
</a>
}
</section>
<div class="pagination">
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfVideos, page => Url.Action("VideoHome", "Video", new { page = page }), PagedListRenderOptions.OnlyShowFivePagesAtATime)
</div>
</div>

What you're probably gonna want to do is insert an AjaxForm after the main-content div and end it before the main-content div closes.
Then the PagedListPager can submit to a Json Method in your controller which will return the content (e.g. list of videos) for the Ajax form to update.

Related

MVC: Can't make fancybox work

I am trying to update an existing application and wants to display modal using fancybox. On other functionalities, I was able to display the fancybox but for some reason cannot do it on a particular view.
Here is my main view declaration:
#Html.ActionLink(Strings.Link_ViewFullList, "OrganisationFullList", new { id = 1 }, new { #class = "fancybox fancybox.ajax" })
Then here is my "organisationFullList" cshtml file.
#model ProjectOrganisationModel
#{
ViewBag.Title = Strings.PageTitles_Organisations;
}
<div class="row">
<div class="col-lg-10">
#if (Model.Organisation != null && Model.Organisation.Any())
{
<ul class="list-unstyled">
#foreach (var organisation in Model.Organisation)
{
<li>
#Html.RadioButton("organisationList", organisation.Name)
#Html.Label(organisation.Name, new { style = "font-weight: normal" })
</li>
}
</ul>
}
</div>
</div>
Here is my controller code:
public ActionResult OrganisationFullList(int id)
{
var organisationList = new ProjectOrganisationModel();
organisationList.Organisation = GetOrganisations();
return View(organisationList);
}
When I click on the link, it displays a new screen instead of the modal. It redirects to this URl:
https://localhost:44300/project/1/organisationfulllist
#Html.ActionLink causes you to redirect to another page.
Rather than using #Html.ActionLink use #Ajax.ActionLink
#Ajax.ActionLink(
"View Full List Ajax",
"OrganisationFullList", //Action
"YourController", //Controller
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "showFancyBox" //call back
}
)
Call back function:
function showFancyBox(data) {
$.fancybox.open({ "content": data });
}
Dont forget to include jquery.unobtrusive-ajax.min.js you need it to use #Ajax helpers
<script type="text/javascript" src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>

MVC 4 Updating a partial view from another partial view using Ajax.BeginForm()

I have a comment section set up on one of my pages. The parent view has a partial view which shows the comments for that ID and gives the option to display another partial view to post a comment. When someone post a comment I want the first partial view within the parent to refresh displaying the new comment.
Currently when you click Post Comment, the AddComment method is called and added to the database. I get an error saying that I am passing the wrong type of model to the view. It seems to be trying to pass the return value to my AddComment partial view instead of injecting it into Partent View Div.
Parent View
#model QIEducationWebApp.Models.Course
#{
ViewBag.Title = "Course Details";
}
<h1 class="page-header">#ViewBag.Title</h1>
Javascript is here
.
.
.
<table class="table">
DETAILS HERE
</table>
<ul id="view-options">
<li>#Html.ActionLink("Back to Courses", "Index", "Course")</li>
</ul>
<input type="button" id="View" class="ShowComment" value="Show Comments"/>
<div id="CommentSection"/>
Partial View to view comments
Javascript is here
.
.
.
<div class="CommentSection">
#foreach (var item in Model)
{
<div class="Comment">
<div class="CommentText">
#Html.DisplayFor(modelItem => item.CommentText)
</div>
<div class="CommentSep">
<span class="Commenter">#Html.DisplayFor(modelItem => item.UserName)</span> - <span class="CommentDate">#Html.DisplayFor(modelItem => item.CommentDate)</span>
</div>
</div>
}
<input type="button" id="Post" class="AddComment" value="Add a Comment"/>
<br />
<br />
</div>
<div id="AddComment" />
<br />
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("ViewComments",
new { courseID = #ViewBag.courseID, page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new PagedListRenderOptions { MaximumPageNumbersToDisplay = 5, DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,
DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded },
new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "CommentSection" }))
Method behind the is partial view
public PartialViewResult ViewComments(int courseID, int? page = 1)
{
ViewBag.courseID = courseID;
var coursecomments = db.CourseComments.Where(cc => cc.CourseID == courseID);
int pageSize = 10;
int pageNumber = (page ?? 1);
return PartialView(coursecomments.OrderByDescending(cc => cc.CommentDate).ToPagedList(pageNumber, pageSize));
}
Partial to Post Comment
Javascript is here
.
.
.
#using (Ajax.BeginForm("AddComment", "CourseComment", new { courseID = #ViewBag.courseID, userName = #User.Identity.Name },
new AjaxOptions { UpdateTargetId = "CommentSection" }))
{
#Html.ValidationSummary(true)
<div class="NewComment">
<div class="editor-field">
#Html.TextAreaFor(model => model.CommentText, new { maxLength = 500 })
#Html.ValidationMessageFor(model => model.CommentText)
</div>
<input type="submit" class="PostComment" value="Post Comment" />
<div id="Counter" class="CommentCounter"/>
</div>
}
Controller method linked to the Post Comment Ajax.BeginForm()
public PartialViewResult AddComment(CourseComment coursecomment, int courseID, String userName)
{
coursecomment.CommentDate = System.DateTime.Now;
coursecomment.CourseID = courseID;
coursecomment.UserName = userName;
if (ModelState.IsValid)
{
db.CourseComments.AddObject(coursecomment);
db.SaveChanges();
}
ViewBag.courseID = courseID;
return ViewComments(courseID);
}
Adding pictures
Details
After selecting View Comments button
After selecting Add Comment
After Posting the the comment I want the list of Comments to refresh displaying the newly added Comment. Like So
For now I have it changed. I wanted to the comments section to be hidden until the show comments was clicked. Then after posting a comment on the comments section was refreshed, but I couldn't get that to work. So just reloading the whole page will refresh the comments section, but make it hidden at that time. I made it so that the comments section shows by default without the option to hide it. So unless anyone can figure out a way to get it to work how I wanted, this works for now.

Client side paging for Asp.Net MVC3

this is my MVC action that returns a list of posts:
public ActionResult Posts()
{
var blogPost = _blogRepository.GetAllPost();
var blogPostViewModel = blogPost.ConvertToPostViewModelList();
return View("Posts", blogPostViewModel);
}
and also this is my View
#model IEnumerable<Blog.Web.UI.ViewModels.PostViewModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
#foreach (var item in Model)
{
<div>
<h3>
#Html.ActionLink(item.Title, "Post", "Blog", new { postId = item.Id, postSlug = item.UrlSlug }, null)
</h3>
</div>
<div>
<span>Category: </span>#item.Category.Name
</div>
<div>
<span>Tag: </span>#item.Tag.Name
</div>
<div>
#item.CreationDate.ToLongDateString()
</div>
<div>
#Html.DisplayTextFor(p => item.Body)
</div>
}
</div>
I want to implement a Client Side paging for this page that render all of the post by date , is it possible ?? or I should change my code to make it server side ??
http://haacked.com/archive/2009/04/13/using-jquery-grid-with-asp.net-mvc.aspx
It's old but relevant and should help you achieve what your looking for.

Ajax not working with MvcPaging

Currently I am using the MvcPaging nuget package that I retrieved from here: https://github.com/martijnboland/MvcPaging
My problem is that instead of replacing my element when I use the #Html.Pager helper. It opens up the partialview in a new tab.
My goal is to have my QuickLinks section update via Ajax without a full page refresh.
This is my controller:
private CasuallyProDb db = new CasuallyProDb();
private const int DefaultPageSize = 7;
//
// GET: /Home/
public ActionResult Index()
{
int currentPageIndex = 0;
var news = db.PostedNews.OrderBy(a=>a.NewsId).ToPagedList(currentPageIndex, DefaultPageSize);
return View(news);
}
public ActionResult AjaxPage(int? page)
{
int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
var news = db.PostedNews.OrderBy(a => a.NewsId).ToPagedList(currentPageIndex, DefaultPageSize);
return PartialView("_QuickLinks", news);
}
This is my index view that renders the partial view:
#model IPagedList<CasuallyPro.Models.News>
#using MvcPaging
<div id="quickLinksWrapper" class="float-right">
#Html.Partial("_QuickLinks", Model)
</div>
And this is my _QuickLinks.cshtml partial view:
#model IPagedList<CasuallyPro.Models.News>
#using MvcPaging
<div id="quickLinksDisplay">
<ul>
#foreach (var news in Model)
{
<li>
<img alt="" src="#Html.DisplayFor(modelItem => news.CategoryIcon)"/>
<div class="quickLinksTitle">#Html.DisplayFor(modelItem => news.Title)<br/>
<span class="quickLinksDetails">
<span class="quickLinksUsername"> Posted by #Html.DisplayFor(modelItem => news.PostedUserName)</span>
<span class="quickLinksDate"> on #Html.DisplayFor(modelItem => news.PostedDate)</span>
</span>
</div>
</li>
}
</ul>
<div id="quickLinksPagedList">
#Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, new AjaxOptions
{
UpdateTargetId = "quickLinksWrapper"
}).Options(o => o.Action("AjaxPage"))
</div>
I am looking at the sample project they provided and it looks like this should do it but unfortunately it just isn't working appropriately. I have the script referenced in the head section of my _Layout.cshtml for unobtrusive ajax:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
Any guidance would be appreciated.

Using Jquery to collect data, use data to get a Partial View from the controller, and append the passed information to the end of a page

I am attempting to append a partial view to the end of my 'currently displayed page' when a selection from a dropdown menu is chosen.
This is the dropdown from my view:
<div>
#Html.DropDownListFor(x => x.DropDownInfo, Model.Info, "DefaultSelection")
#Html.ValidationMessageFor(model => model.Courses)
</div>
I am in most need here in my Jquery. What do I need to do to append the PartialView that is returned by my controller (pasted below)? My current Jquery:
$(document).ready(function() {
$("#DropDownInfo").change(function() {
var strSelected = "";
$("#DropDownInfo option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Controller/PreFillMethod/?MethodString=" + strSelected;
$.post(url, function(data) {
//*****
// Assuming everything else is correct,
// what do I do here to have my partial view returned
// at the end of the currently displayed page?
//*****
});
});
});
This is the part of my controller that replies with a PartialView (I want the string from the dropdown selection to be passed into this controller to ultimately be used to fill in a field in the PartialView's form) :
public PartialViewResult PreFillCourse(string selectedFromDropDown)
{
ViewBag.selectedString = selectedFromDropDown;
MyViewModel preFill = new MyViewModel
{
Title = selectedFromDropDown, // I am using this to pre-fill a field in a form
};
return PartialView("_PartialViewForm", preFill);
}
The Partial View (in the case that it matters):
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>CourseTemplates</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
I am open to suggestions if I am approaching the situation entirely incorrectly.
My goal is to have a user select a 'template' from the drop-down menu and have that template's data autopopulate into a form below the drop-down.
My Jquery is very rough - I am using this post as a guide
you should have a div in your view
<div id ="divToAppend">
</div>
then append the partial view to your div
$(document).ready(function() {
$("#DropDownInfo").change(function() {
var strSelected = "";
$("#DropDownInfo option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Controller/PreFillMethod/?MethodString=" + strSelected;
$.post(url, function(data) {
$('#divToAppend').html(data);
//*****
// Assuming everything else is correct,
// what do I do here to have my partial view returned
// at the end of the currently displayed page?
//*****
});
});
});

Resources