Recreating the listview in a custom section

by David Brendel

Introduction

In this article I will show how easy it is to add the Umbraco list view to your custom section.

I was always curious how you could use the Umbraco listview in a custom section of your own. A few days ago I had a little talk with Tim Geyssens about his new package UI-O-Matic (if you haven't checked it out already i recommend you doing it!) and we talk about how to enable the list view for nodes in the custom section of this package. A day later and Tim had implemented a basic list view as it was nothing. So again a big #h5yr!

So to be honest the list view is not the built-in list view of Umbraco. That's because it's so specific to all things umbraco does when editing content that it's not easy to implement it in a custom section. I really think it's not possible at all. But proof me wrong if you can! So to make it more clear we will implement the listview behaviour on our own!

The result we want to achieve is this:

The desired outcome

After our section is ready, I need a tree that is responsible for the new section. I won't get into detail here as it is plain simple. It just returns one node as the root node, which has the view assigned with our listview. So nothing special here.

For some convenience I use the ServerVariableParser to register the path to our API-Controller to reuse it in our AngularJS code a bit more easier. If you haven't, you should take a look at that way to store your paths.

To have some dummy data I create some on startup. This is using PetaPoco to drop and create the necessary table and insert some dummy pocos. For some additional information about PetaPoco I made a blog post and there are some additional information on the web.

Let's have a look at the models that are used. As can be seen I use a "People" model for this demo. So the listview will display some people information. It's dead simple for this demo. The model is marked by different attributes which are used by PetaPoco to know the database structure and mapping of table columns to properties. Also I'm using DataContract for the json serialisation.

So what magic does happen here. First we check if a search term was set and if yes we need to build the where clause. To do this we go through each property of our poco and check if we find any column-attributes on them. If yes we enlarge the where clause with the name/value of that attribute, if not we just using the property name.

After that I check if sort column and sort order is set and adding the OrderBy part to the query with the column and sort order.If they are not provided the ORderBy is defined with default values.

With the finished statement a query is run to the database to fetch all objects. To consider our pagination state the Paged()-method is used which takes the current page number, how many items per page should be used and the build statement.

Package

As for each (or nearly each) extension built for Umbraco like grid or property editors there is the need of a package.manifest file. This is used to register our AngularJS controller and resource needed for the listview.

As this is a fairly simple demo only two js files are registered and nothing more.

AngularJS

First have a look at the resource file. It used to have all calls to our API-Controller bundled in one file for more convenience and a better code structure. The resource provides two methods to fetch data from the API. The only one used in this demo is in fact the getPaged()-method.

The fetchData()-method is obviously used to fetch the data from the API by using the resource created previously by calling the getPaged-method with some $scope variables which are holding information about the search term, itemsPerPage, current page and so on.

The order()-method is used for ordering the data (yeah captain obvious). The variables reverse and predicate are used in the view which is described a bit later.

The toogleSelection()-method is used to store the ids of the items we checked in the listview. This is needed for bulk deleting, updating or whatever else.

The prevPage()-, nextPage()- and setPage()-methods are used for the pagination to set on which page we currently are.

The search()-method is of course used to set the search term.

All of these methods are calling fetchData() at the end to get the right objects from the database regarding the variables we set through them.

HTML

The html view is divided into two main parts. The first one is the header above the table which holds the search box and the delete button for bulk deleting.

The footer holds the pagination. The available page numbers and the prev/next buttons are rendered. Of course this could be tweaked to only show a certain number of pages or hide the prev/next buttons if on the first/last page.

Wrapping up

As you can see it is possible with fairly simple methods to enhance the user experience of your packages or websites by reusing a functionality that is already used by umbraco itself and thus loved by our editors.

For a better jumb start I created a github repo which is ready to go, so give it a try!