Posts

Umbraco custom model with pager

Umbraco is the open source content management system allowing for quick content creation and easy customization as it uses ASP.NET MVC pattern to render page components.

The power of Umbraco is the flexibility and a host of features it provides out of the box. It is also written in C# which makes it especially popular amongst the developers.

Creating custom views with Umbraco is very easy, as we can set-up our own routing methods by inheriting from RenderMvcController and overriding action methods accepting and returning RenderModel object:

public class MyPageController : RenderMvcController
{

public override ActionResult Index(RenderModel model)
{
//your logic here

return base.Index(model);
}
}

However, if we want to accept and return our own custom model, the hack is required.
Suppose we want to return custom model containing pager information. We can do that by extending RenderModel class as follows:

public class MyCustomModel : RenderModel
{
public MyCustomModel() : this(new UmbracoHelper(UmbracoContext.Current).TypedContent(UmbracoContext.Current.PageId)) { }
public MyCustomModel(IPublishedContent content, CultureInfo culture) : base(content, culture) { }
public MyCustomModel(IPublishedContent content) : base(content) { }

public string Title { get; set; }
public List<IPublishedContent> ModelItems { get; set; }
public Pager Pager { get; set; }
}

Our pager class will look as this:

 public class Pager
 {
 public int TotalPages { get; set; }
 public int CurrentPage { get; set; }
 public int PageSize { get; set; }
 public int NumberOfRows { get; set; }
 }
 

Next, our controller action will have following logic:

public override ActionResult Index(RenderModel model)
{
var myCustomModel = new MyCustomModel();

var modelItems = model.Content.Children.OrderByDescending(x => x.CreateDate);
//pager logic
const int PAGE_SIZE = 6;
var currentPage = 1;
int.TryParse(Request.QueryString["page"], out currentPage);

myCustomModel.Pager = new Pager()
{
PageSize = PAGE_SIZE,
TotalPages = (int)Math.Ceiling((double)modelItems.Count() / (double)PAGE_SIZE),
CurrentPage = currentPage
};

myCustomModel.ModelItems = currentPage == 0 ? modelItems.Take(PAGE_SIZE).ToList() : modelItems.Skip((currentPage - 1) * PAGE_SIZE).Take(PAGE_SIZE).ToList();

if (myCustomModel.Pager.CurrentPage > myCustomModel.Pager.TotalPages) { myCustomModel.Pager.CurrentPage = myCustomModel.Pager.TotalPages; }
else if (myCustomModel.Pager.CurrentPage < 1) { myCustomModel.Pager.CurrentPage = 1; }

return base.Index(myCustomModel);
}

As we return custom model from the action, we also need to define this in our custom view as shown below:

@inherits Umbraco.Web.Mvc.UmbracoViewPage<MyCustomModel>

<div class="row">
<div class="col-md-6">
@foreach (var item in Model.ModelItems.Take(Model.Pager.NumberOfRows))
{
//display your item data here
}
</div>
</div>

@Html.Partial("_Pager", Model.Pager) //embed pager view

Finally, the pager partial view should look as follows:

@model Pager

@{
var IsBreak = false;
}

<div class="container">
@if (Model.TotalPages > 1)
{
<ul class="pager">
@if (Model.CurrentPage > 1)
{
<li><a href="?page=@(Model.CurrentPage - 1)">Previous</a></li>
}
@for (int p = 1; p < Model.TotalPages + 1; p++)
{
var linkClass = (p == Model.CurrentPage) ? "disabled" : "active";
if (p == Model.CurrentPage)
{
<li class="@Html.Raw(linkClass)"><a href="?page=@p">@p</a></li>
IsBreak = false;
}
else
{
if (p == 1
|| p == Model.CurrentPage - 1
|| p == Model.CurrentPage + 1
|| p == Model.TotalPages - 1
|| p == Model.TotalPages)
{
<li class="@Html.Raw(linkClass)"><a href="?page=@p">@p</a></li>
IsBreak = false;
}
else
{
if (IsBreak)
{
continue;
}
else
{
<li><a href="#">...</a></li>
IsBreak = true;
}
}
}
}

@if (Model.CurrentPage < Model.TotalPages)
{
<li><a href="?page=@(Model.CurrentPage + 1)">Next</a></li>
}
</ul>
}
</div>

The above is fully working example – of course you need to do some html adjustments depending on your requirements. Enjoy!

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...