Joseph Bulger IV

Technology

Creating an PagedList<T> that uses AJAX

by Joseph on Apr.14, 2010, under Consulting, Programming, Technology

I’ve been using this PagedList functionality that i found from a blog article Rob Conery put up, and a control I found by Robert Muehsig which I’ve really enjoyed using so far.

One of the things that was missing from the functional set that I ended up needing was the ability to page the list, but through issuing AJAX requests instead of the typical post back.

So I went off and extended the existing model to support AJAX requests, and thought I would share it in case anyone else needed to do the same thing.

I guess the best place to start would be the use case.  So to start I created a control that encapsulates the Paging UI layout and calls I need.  The use of the original control looks like this:


Html.RenderPartial("AjaxPagination",
    new AjaxPaginationViewData
        {
            PageIndex = Model.PageIndex,
            Action = "CondoPage",
            Controller = "Home",
            AjaxOptions =
                new AjaxOptions { UpdateTargetId = "updatedContent" },
            TotalCount = Model.TotalCount,
            PageSize = Model.PageSize,
            NumberOfPagesToEachSide = 2
        }
);

The new AJAX functionality is called similarly:


<% using (Ajax.BeginForm("SomePage",
        "SomeController",
        new AjaxOptions { UpdateTargetId = "updatedContent" })) { %>

        <% Html.RenderPartial("AjaxPagination",
                new AjaxPaginationViewData {
                        PageIndex = Model.PageIndex,
                        Action = "SomeAction",
                        Controller = "SomeController",
                        AjaxOptions = new AjaxOptions
                                { UpdateTargetId = "updatedContent" },
                        TotalCount = Model.TotalCount,
                        PageSize = Model.PageSize,
                        NumberOfPagesToEachSide = 2
                });%>

<% } %>

A couple things to note. You’ll notice that the AJAX control is rendered inside a Ajax.BeginForm. This is because I’m using the Microsoft.Ajax way of making AJAX calls.  This could also be done using jQuery or something else that can process AJAX calls. I just went this way because the scripts are already included in asp.net mvc app when you first create the project.  The result of the AJAX call will be a partial view, and we’ll need to put that somewhere.  That’s where the UpdatedTargetId comes into play. Other things we include in the AJAX control that are not in the original are the Action and the Controller, and some AjaxOptions. PageActionLink doesn’t work with the AJAX control, because we’ll be using Ajax.ActionLink to build the link, which is why I broke it up into Action, and Controller. For the AjaxOptions, we need those to specify the target of the call.

So now that’s been explained, let’s look at the controls themselves.  Here’s a comparison of the original control and the ajax control.

The original is one this way:


<% if (Model.HasPreviousPage) { %>
    <a href="<%=Model.PageActionLink.Replace("%7Bpage%7D", (Model.PageIndex - 1).ToString())%>">Previous</a>
<% } %>

<% if (Model.GetFirstPageToLink() != 1) { %>...<% } %>

<%for (var page = Model.GetFirstPageToLink(); page <= Model.GetLastPageToLink(); page++) {
    if (page == Model.PageIndex) { %>
        <%=page.ToString()%>
<% } else { %>
    <a href="<%=Model.PageActionLink.Replace("%7Bpage%7D", page.ToString())%>"><%=page.ToString()%></a>
<% } 

    if (page != Model.GetLastPageToLink()) { %>|<% } } %>

<% if (Model.GetLastPageToLink() != Model.PageCount) { %>...<% } %>

<% if (Model.HasNextPage) { %>
    <a href="<%=Model.PageActionLink.Replace("%7Bpage%7D", (Model.PageIndex + 1).ToString())%>">Next</a>
<% } %>

And the AJAX control is done this way:


<% if (Model.HasPreviousPage) { %>

<%= Ajax.ActionLink("Previous", Model.Action, Model.Controller, new { page = (Model.PageIndex - 1).ToString() }, Model.AjaxOptions)%>

<% } %>

<% if (Model.GetFirstPageToLink() != 1) { %>...<% } %>

<%for (var page = Model.GetFirstPageToLink(); page <= Model.GetLastPageToLink(); page++) {
    if (page == Model.PageIndex) { %>
        <%=page.ToString()%>
    <% } else { %>

<%= Ajax.ActionLink(page.ToString(), Model.Action, Model.Controller, new { page = page.ToString() }, Model.AjaxOptions)%>

<% } if (page != Model.GetLastPageToLink()) { %> | <% } } %>

<% if (Model.GetLastPageToLink() != Model.PageCount) { %>...<% } %>

<% if (Model.HasNextPage) { %>

<%= Ajax.ActionLink("Next", Model.Action, Model.Controller, new { page = (Model.PageIndex + 1).ToString() }, Model.AjaxOptions)%>

<% } %>

The big difference here is the way that the links are generated. The original control simply creates an anchor tag and passes in the url generated by the Model. The AJAX control uses AJAX.ActionLink() instead, so we can have the link support AJAX.

So knowing how the control looks, this is the Model for the AJAX control itself:


public class AjaxPaginationViewData
{
    public int NumberOfPagesToEachSide { get; set; }
    public int PageIndex { get; set; }
    public int PageSize { get; set; }
    public int TotalCount { get; set; }

    public string Action { get; set; }
    public string Controller { get; set; }

    public AjaxOptions AjaxOptions { get; set; }

    public int PageCount
    {
        get
        {
            return (int)Math.Ceiling((double)TotalCount / PageSize);
        }
    }
    public bool HasPreviousPage
    {
        get
        {
            return (PageIndex > 1);
        }
    }

    public bool HasNextPage
    {
        get
        {
            return (PageIndex * PageSize) <= TotalCount;
        }
    }

    public int GetFirstPageToLink()
    {
        return (PageIndex - NumberOfPagesToEachSide > 1 ? PageIndex - NumberOfPagesToEachSide : 1);
    }

    public int GetLastPageToLink()
    {
        return (PageIndex + NumberOfPagesToEachSide < PageCount ? PageIndex + NumberOfPagesToEachSide : PageCount);
    }
}

That pretty much explains how the control is built.

The only thing left is how the interaction with PagedList happens.  For that we look at the action that the control calls.  In this example, we’re calling SomeAction in SomeController, and it would look something like this:


public ActionResult SomeAction(int page)
{
    CachedPage = page;
    var query = GetSearchQuery(CachedSearchParameters);
    var model = query.ToPagedList(page, DefaultPageSize);
    return PartialView("AjaxResults", model);
}

The ToPagedList performs the functionality that is included with the PagedList classes which you can find here.

Let me know what you think, and if you’d like some demo source to see this in action I can happily provide, just let me know.

Leave a Comment :, , , more...

First Impressions of Droid Eris

by Joseph on Feb.22, 2010, under Technology

I just recently got a new phone, a Droid Eris. So far I’m liking it a lot. The keyboard is surprisingly easy to use. I haven’t gotten around to tethereing the phone yet, but thats my next step. Then I’ll be able to use my computer from the road, something the iPhone didn’t offer me, which is why I went with an Android phone. So here’s hoping!

Leave a Comment : more...

I finally got an invite to Google Voice

by Joseph on Sep.05, 2009, under Technology

Google Voice is a message management system that was originally called  Grand Central, but got bought out by Google.  I was a real fan even before Google got it, but all the lines had been bought out so I couldn’t get into it.  I recently received an email that they had opened up some more lines, so I jumped.

Now I have google voice, and there are some things that I think are really cool about it.  When someone leaves you a voicemail, it transcribes the recording for you so you can read it online.  Also, all texts that are sent to you are viewable online as well.  One other awesome feature is that you can add a call widget to your web site (I have one on the right hand side) that allows people to call you without giving out your phone number.  It’s great if you have a portfolio online, and want people to contact you about freelance jobs or something, but you don’t want to give out your number.

Check it out!

Leave a Comment : more...

Building a Reputation System

by Joseph on Sep.03, 2009, under Church, Consulting, Programming, Technology

I’m working on a reputation system for a site I’ve been recently working on (http://www.serveandtrade.com).  I’m going through some ideas so I thought I’d post them on here and see what people think.

Let’s start buy throwing up what we currently have so we can see where we’re trying to go.  Here’s a mockup of what a user will see when they search for trades right now.

currentsearchconcept

I have a couple problems with how it works right now.

  1. I don’t like that it’s in a grid/table format.  I have to fix that first.  I’m moving more towards something like a list layout.
  2. There are some things missing that I would like to be able to do.  For instance, if I just searched for “can of soup”, and I see that Michelle has the one I want, I would like to have a button/link/something to click on that says “I want that!”  Right now the only thing you can do is go look at the trade, or ask a question.
  3. Clicking on the owner’s link takes you to their profile, but it doesn’t show you what other trades they have, or trades they are looking for.  That information could really be useful.

I’m sure there are other things I could think of, but for now I’m going to start focusing on these three and build some mockups to illustrate these workflows.

First, getting rid of the grid.

newsearchconcept

This search list looks a lot better I think.  There are some more features on here then the other one, but we’ll go over those in subsequent posts.

So at this point I’m looking for any feedback.  ANY feedback, good or bad… I’ll take it all.  I really haven’t made up my mind at this point yet, but I think I’m heading in the right direction.

Next post will be about the “I want it!” feature.  Stay tuned!

Leave a Comment :, , more...

Trying out Microsoft Hohm: Save Energy, Save Money

by Joseph on Jul.06, 2009, under General, Technology

I’m trying out a new product Microsoft is releasing on the web called Hohm.  It’s a web site dedicated to tracking your energy expenditure and cost, so that you can reduce your energy consumption and also save you some cash along the way.

How does it accomplish this?  It profiles you and your house.  It asks you some basic (and some not so basic) information about your house and your energy habits.  The cool thing is you can choose to fill in as much, or as little, as you want.  No pressure.  However, the more information you can give it the more accurate the reports will be.

Other cool things include the ability to track your energy bills through an automated feed.  This has to be set up with your utility company(ies), but if they offer it, then it’s a quick way for Hohm to get a lot of information about your energy consumption.  I live in Homestead, FL, and as of today they haven’t set up any of the providers here.  I’m hoping they will in the future so I can submit them my data feed and get some real data to project.

I’m really using it as a way to try and save money primarily.  If it works out I’ll be writing a success story on it at a later date.

1 Comment :, , more...

  • Link with me

    Joseph Bulger
  • Call me

  • What I'm Doing...

    Powered by Twitter Tools

  • Looking for something?

    Use the form below to search the site:

    Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

    Visit our friends!

    A few highly recommended friends...

    Archives

    All entries, chronologically...