Doctype selector property editor for Umbraco

This post is about my first Umbraco 7 property editor. Its a document type selector which then allows you to select properties of that document type. What use is that? Read on…

A little context

For a recent project, I needed to create a directory package. Just like the back-office has a content lister that allows filtering of child pages, this package would allow similar functionality on the front-end of a site. An editor would be able to create child pages of a particular document type, then the parent page of these would contain a gridview control that would allow filtering and searching of that content. This landing page would have config allowing the user to select which properties of that document type would be shown in the grid view, which would be included in the search, which properties could be sorted or filtered etc.

The very first step in this process was to create a property editor that would allow a user to select a document type and then choose properties of that document type in a check box list.

The source

Grab the zip file here and go nuts…

Download (ZIP, 2KB)

HTML

<div ng-controller="lcc.DocTypeSelectorController"> <!--// 1 //-->

 <select ng-model="model.value.selectedDocType.id" ng-options="doctype.id as doctype.name for doctype in doctypes" ng-change="chooseDocType()"></select> <!--// 2 //-->

 <table>
 <tr>
 <th>Property</th>
 <th>Show in listings</th>
 </tr>
 <tr ng-repeat="prop in docTypeProperties"> <!--// 3 //-->
 <td>
 <label for="{{$id}}-{{prop.alias}}">{{ prop.alias }}</label>
 </td>
 <td>
 <input id="{{$id}}-{{prop.alias}}" name="{{$id}}-{{prop.alias}}" type="checkbox" value="{{prop.alias}}" ng-model="prop.selected" />
<!--// 4 //-->

 </td>
 </tr>
 </table>

 {{model.value | json }}
</div>
  1. This links the html to the controller
  2. The select lists all the document types. The controller itself calls a c# class which returns a list of document types as json. The select also triggers an ‘ng-change’ event which reloads the properties of the selected doc type.
  3. The table is a simple repeater that lists properties of the selected doctype.
  4. Each checkbox is linked to the boolean ‘selected’ value of the property model.

Controller

angular.module("umbraco").controller("lcc.DocTypeSelectorController", function ($scope, docTypeSelectorResource) {
 //1
 $scope.doctypes = docTypeSelectorResource.getAll();
 $scope.selectedProps = []
 
 //2
 if (!angular.isObject($scope.model.value)) {
    $scope.model.value = {};
 }
 
 //3
 if (!angular.isObject($scope.model.value.selectedDocType)) {
    $scope.model.value.selectedDocType = {};
 } else {
    //get the list of props for the selected doc type
    $scope.docTypeProperties = $scope.model.value.docTypeProperties;
 }
 
 //4
 $scope.chooseDocType = function () {
    //get all properties of doctype
    $scope.docTypeProperties =    docTypeSelectorResource.getPropertiesForDocType($scope.model.value.selectedDocType.id);
 }
 
 //5
 $scope.$watch('docTypeProperties', function (nv) {
    $scope.model.value.docTypeProperties = nv;
 }, true);

});
  1. All the doctypes get loaded from the c# class using Umbraco’s ContentTypeService. This is done through an angular resource which was created. The resource is responsible for getting all doctypes and getting properties of a specific doctype.
  2. A check is made for whether the model value has been set. If not, its set to an empty object
  3. Another check is made to see if a document type has been selected. If it has been, the properties of that document type are loaded.
  4. The ‘chooseDocType’ function is executed whenever a different doctype is selected.
  5. A watch is put on the docTypeProperties model which is bound to the checkbox list. So, whenever a checkbox is ticked or unticked, the model is updated.

 Resource

//1
angular.module("umbraco.resources")
.factory("docTypeSelectorResource", function ($http) {

 var docTypeService = {};
 docTypeService.getAll = function () {
   var allDocTypes =  $http.get("Backoffice/DocTypeSelector/DocTypeSelectorApi/GetAllDocTypes").then(function (response) {
     return response.data;
   });

   return allDocTypes;
 }
 
//2
 docTypeService.getPropertiesForDocType = function (id) {
 var props = $http.get("Backoffice/DocTypeSelector/DocTypeSelectorApi/GetPropertiesForDocType?id=" + id).then(function (response) {
     return response.data;
   });
   return props;
 }

 return docTypeService;
})
  1. The angular resource makes use of the http service, which is injected here. The ‘getAll’ function calls the c# class responsible for using the ContentTypeService. Once the response is returned, the data of the response is then returned.
  2. The ‘getPropertiesForDocType’ function is pretty much the same except that it expects an id parameter to be passed to it. This is supplied from the id of the selected doctype ($scope.model.value.selectedDocType.id)

That’s about it

This is just the first step in a larger package. The next step is to implement more checkbox lists allowing the user to configure the grid view that will in the end allow filtering, searching and sorting of child pages.

This is my first step into angularjs and, although this works, I’m sure there must be better ways to go about this. If anyone has any tips or suggestions, they’d be very welcome.

Leave a Reply