Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

 

AngularJS powered by SilverStripe

My recent blog post on Backbone unit testing mentioned AngularJS, as being one of the...

Read post

angularjs and silverstripeMy recent blog post on Backbone unit testing mentioned AngularJS, as being one of the more popular emerging JavaScript frameworks. A common use case for AngularJS is filtering lists of data such as products. I’ve put together an example application which creates a simple product catalogue and more importantly highlights the concept of AngularJS and SilverStripe working together.

On the client-side we have a simple AngularJS application. This manipulates product data and handles user interactions. On the backend, we’ve got a SilverStripe ModelAdmin, Controller, and a custom page type. These are all brought together with AngularJS enhanced SilverStripe templates.

Here’s how it all fits together, starting with the backend.

ModelAdmin

modeladmin

The ModelAdmin is where products are managed. Each product has a title, description, image, and belongs to a product catalogue. The information entered here, is made available to our AngularJS application, via the controller.

Controller

The controller receives AJAX requests from our AngularJS application, and returns JSON containing product information. We take advantage of SilverStripe’s caching to optimise responses. No need to query the database and rebuild the product catalogue JSON every request.

Product catalogue page

Product catalogue page

This is the product catalogue page type. The main point of interest here is the ‘products per page’ field. Our product catalogue will paginate using the value of this field. Setting the value to 0 will display all products on a single page.

AngularJS application

AngularJS application

We manipulate product data on the client-side using AngularJS / SilverStripe templates and a little bit of JavaScript. Controllers.js sends an AJAX request to our backend controller then handles the response. The JSON returned by the controller, is assigned to the $scope.products property, which makes product data (title, description, image) available for use in our templates.

At the core of the product catalogue template is ProductCatalogProductList.ss. Similar to looping over lists in SilverStripe templates, we use the AngularJS directive ngRepeat to loop over our Product data. A number of filters are applied, which limit the number of products shown, change the sort order, and filter products based on their title and description values.

One of the great things about AngularJS is two way data binding. You can bind DOM elements to data models using directives. If applied to a search field, changes to the DOM (user enters a search term) are reflected in that element’s data model, and any changes to the model (autocomplete, search suggestion for example) automatically update the DOM element. This becomes really useful when you use the value of one model, to filter DOM elements, bound to another model. This is what happens in the product catalogue when you search, sort, and paginate Products. Action taken on the UI, updates a data model, which updates the state of another DOM elements.

Having this wiring done behind the scenes, by the framework, is great. Doing it manually in frameworks like Backbone, can be time consuming and lead to performance issues, if you’re not careful.

The pagination template works thanks to a useful SilverStripe requirements feature, and also has a gotcha you should watch out for.

The AngularJS app needs know the number of Products to display per page. Content Authors edit this value in the CMS, but we need to make it available on the client-side. In the ProductCatalogPage.php controller we use SilverStripe’s Templated JavaScript feature to do this. The value is then assigned to $scope.ProductsPerPage in controllers.js which makes it available in AngularJS templates and by JavaScript functions in the client-side controller.

The gotcha when working with AngularJS in SilverStripe templates is the special character ‘$’. Both SilverStripe templates and AngularJS use ‘$’ to prefix variable names. Luckily the workaround is easy, escape AngularJS nested scope variables a backslash ‘\’. There are some examples of escaping AngularJS nested scope variables in the pagination template.


This is a basic example of how SilverStripe can be used to power an AngularJS application. The use-case shown here is a product catalogue but the same setup can be applied to any data you wish to model. If you want to try it out, the example application is available from our addons site


David CraigDavid started out as a print designer creating magazine layouts and working on advertising campaigns. His love of layout and design led to an interest in the web, and how to make it user friendly. Since his shift to the web, David has worked for startups on various projects including marketing sites, campaigns, user interfaces and multi-device web applications. David enjoys discovering new music, brewing beer and looking at well designed things.