In my ASP.NET MVC 3 application I want to use Jquery's pagination
plugin to make my forum...
So I want, to do all page changes with Ajax, and want to use history
plugin for working browser's back and next buttons...
What the most efficient javascript/jquery code for that?
I wrote this code month ago, but now it seems me ugly..Check that
$(document).ready(function () {
$.history.init(function (hash) {
if (hash != "") {
NavigateToPage(hash.substring(0,hash.indexOf("page")),hash.substring(hash.lastIndexOf("_")+1));
} else {
if(firstTimeOpen==true){
firstTimeOpen=false;
}
else
{
window.location.replace("/Forum");
}
}
});
$(".more-button").click(function () {
currentForumId=$("#pagination-td").parent().prev().attr("id").substring(5);
$.history.load($(this).parents("tr").attr("id").substring(5)+"page_1");
});
});
function NavigateToPage(forumId,page) {
lastForumId=currentForumId;
currentForumId=forumId;
var elem=$("#forum"+forumId);
var elemStr="#forum"+forumId;
if($("#pagination-td").parent().prev().attr("id").substring(5)!=forumId)
{
forumChanged=true;
MakeChanges(elem,page);
}
else
{
if($(".pagination").html()==null)
{
if(elem.find("a").attr("id")>@MyProject.Constants.THREAD_COUNT)
{
$("#pagination-td").pagination(elem.find("a").attr("id"), {
items_per_page: @MyProject.Constants.THREAD_COUNT,
callback: handlePaginationClick
});
}
}
}
$.get('/Forum/ForumThreads', { id: forumId, beginNumber: page - 1, count: @MyProject.Constants.THREAD_COUNT }, function (data) {
RemoveElements(elem.prev(), @MyProject.Constants.THREAD_COUNT);
elem.before(data);
elem.hide();
$("tr:not("+elemStr+"):hidden").show(300);
});
CorrectPagination(page);
}
function RemoveElements(element)
{
if (element.hasClass("forum-desc")) return false;
var prevElement=element.prev();
element.remove();
RemoveElements(prevElement);
}
function MakeChanges(elem,page)
{
var element=elem.prev();
if(forumChanged==true)
{
$.get('/Forum/ForumThreads', { id: lastForumId, beginNumber:0, count: @MyProject.Constants.THREAD_VISIBLE_COUNT }, function (data) {
RemoveElements($("#pagination-td").parent().prev().prev());
$("#pagination-td").parent().prev().before(data);
$("#pagination-td").parent().prev().hide();
$("#pagination-td").parent().remove();
elem.after('<tr style="display:none"><td id="pagination-td" colspan="3" style="border-bottom:none;"></td></tr>');
if(elem.find("a").attr("id")> @MyProject.Constants.THREAD_COUNT)
{
$("#pagination-td").pagination(elem.find("a").attr("id"), {
items_per_page: @MyProject.Constants.THREAD_COUNT,
callback: handlePaginationClick
});
}
$("tr:hidden").show(300);
CorrectPagination(page);
$("#pagination-td").parent().prev().hide();
});
}
}
function handlePaginationClick(new_page_index,pagination_container)
{
$.history.load(currentForumId+"page_"+(new_page_index+1));
return false;
}
function CorrectPagination(page) {
$(".pagination span.current:not(.prev):not(.next)").replaceWith('<a href="#">' + $(".pagination span.current:not(.prev):not(.next)").html() + '</a>');
$(".pagination a:not(.prev):not(.next)").eq(page - 1).replaceWith('<span class="current">' + $(".pagination a:not(.prev):not(.next)").eq(page - 1).html() + "</span>");
if ($(".pagination span.current:not(.prev):not(.next)").next().html() == "Next") {
$(".pagination span.prev").replaceWith('<a class="prev" href="#">Prev</a>');
$(".pagination a.next").replaceWith('<span class="current next">Next</span>');
}
else {
if ($(".pagination span.current:not(.prev):not(.next)").prev().html() == "Prev") {
$(".pagination a.prev").replaceWith('<span class="current prev" >Prev</span>');
$(".pagination span.next").replaceWith('<a class="next" href="#">Next</a>');
}
else {
$(".pagination span.prev").replaceWith('<a class="prev" href="#">Prev</a>');
$(".pagination span.next").replaceWith('<a class="next" href="#">Next</a>');
}
}
}
There are threads of forum in page and I use one pagination(to active thread)... By clicking other more button, the current thread is changed to that thread.
So in the html I have this
<table id="forum-table" class="border-top">
@foreach (var forum in Model)
{
<tr class="forum-desc">
<td class="forum-name" colspan="4"><a class="label-h4 purple" href="/Forum/Forums/@forum.Key.Forum.Id">@forum.Key.Forum.Name</a>
@if (forum.Key.Forum.Description != null)
{
<span> - </span>
<span>@forum.Key.Forum.Description</span>
}</td>
</tr>
for(int index = 0; index < forum.Value.Count; index++)
{
<tr>
<td class="thread-pic"><img src="/img/forum/thread-icon.png" alt="" /></td>
<td class="thread-name">
<a href="/Forum/Thread/@forum.Value[index].Thread.Id" class="blue linked">@forum.Value[index].Thread.Title</a>
</td>
<td class="thread-post-count">
<span>Posts:</span>@forum.Value[index].PostCount
</td>
<td class="thread-information">
<span>by </span><a class="blue" href="/Home/UserProfile/@forum.Value[index].LastPostUserName">@forum.Value[index].LastPostUserName</a> <br />
@if (forum.Value[index].LastPostDate != DateTime.MinValue)
{
@forum.Value[index].LastPostDate
}
</td>
</tr>
}
if (forum.Key.ThreadCount > @MyProject.Constants.THREAD_VISIBLE_COUNT)
{
<tr id="forum@(forum.Key.Forum.Id)">
<td class="more-td">
<a href="javascript:void" class="blue linked more-button" id="@forum.Key.ThreadCount">more</a>
</td>
</tr>
}
if (forum.Key.Forum.Id == Model.Keys.FirstOrDefault().Forum.Id)
{
<tr style="display:none">
<td id="pagination-td" colspan="3" style="border-bottom:none;"></td>
</tr>
}
if (forum.Key.ThreadCount == 0)
{
<tr>
<td colspan="4"><span>No threads available in this forum</span></td>
</tr>
}
}
</table>
So I want shortest(efficient) javascript/jquery code for mixing this two plugins.
Overall this looks like a decent approach. As you get better with jQuery you will learn to chain more and make changes using advanced descendent and adjacent selectors that require less code.
Most of the functions are a little verbose but that isn't a bad thing because it shows your work.
This block has a lot of room for improvement.
RemoveElements($("#pagination-td").parent().prev().prev());
$("#pagination-td").parent().prev().before(data);
$("#pagination-td").parent().prev().hide();
$("#pagination-td").parent().remove();
elem.after('<tr style="display:none"><td id="pagination-td" colspan="3" style="border-bottom:none;"></td></tr>');
You may be able to clean that up using closest()
instead of .parent().prev()
. I couldn't follow exactly what you're targeting but I think you were looking for the previous table row. I can't tell exactly what you're trying to hide and remove but using closest() might help and animating the hide and waiting for it to complete before removing something.
RemoveElements($("#pagination-td").closest(".thread"));
$("#pagination-td").closest(".thread").before(data);
$("#pagination-td").closest(".thread").hide('fast', function() {
$("#pagination-td").closest(".itemToRemove").remove(); });
$('#formTable tr:last').after('<tr class="hidden"><td id="pagination-td" colspan="3"></td></tr>');
Now move your inline CSS to a stylesheet
#pagination-td { border-bottom: none; }
Dylan, I think changing parent().prev()
with closest()
isn't anything big problem... There are such a big problems with large code... For example take a look at that function
function CorrectPagination(page) {
$(".pagination span.current:not(.prev):not(.next)").replaceWith('<a href="#">' + $(".pagination span.current:not(.prev):not(.next)").html() + '</a>');
$(".pagination a:not(.prev):not(.next)").eq(page - 1).replaceWith('<span class="current">' + $(".pagination a:not(.prev):not(.next)").eq(page - 1).html() + "</span>");
if ($(".pagination span.current:not(.prev):not(.next)").next().html() == "Next") {
$(".pagination span.prev").replaceWith('<a class="prev" href="#">Prev</a>');
$(".pagination a.next").replaceWith('<span class="current next">Next</span>');
}
else {
if ($(".pagination span.current:not(.prev):not(.next)").prev().html() == "Prev") {
$(".pagination a.prev").replaceWith('<span class="current prev" >Prev</span>');
$(".pagination span.next").replaceWith('<a class="next" href="#">Next</a>');
}
else {
$(".pagination span.prev").replaceWith('<a class="prev" href="#">Prev</a>');
$(".pagination span.next").replaceWith('<a class="next" href="#">Next</a>');
}
}
}
In that question I found a more efficient slutuion for it... Take a look at this
jquery history plugin set current page possible?
There is same function with less code
var panel = jQuery(this);
// Attach control functions to the DOM element
this.selectPage = function(page_id){ pageSelected(page_id);}
And then
$("#Pagination")[0].selectPage(9); //0-based, 9 = page 10
Let's check yourself...For other functions may be shortest way too...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With