This is one post in a series of short examples of things that can be done using the Aikau framework. The series is not intended to provide complete documentation but simply to show how to solve frequently encountered problems, implement repeating UI patterns, showcase how to use existing widgets or how to create new ones.
Real World Use Case
There are already pages in Share for handling Data Lists, but they haven't been updated for many releases. They are therefore a good candidate to demonstrate how it's possible to re-use Aikau widgets to rebuild (and enhance) existing Share features. It may also be necessary to extend the existing Aikau widgets to achieve specific use cases.
This post picks up where the last one left off. We've now got the basic Data List functionality for reading Data Lists and all that remains is to tweak the layout and handle creation and deletion of Data List items.
Using Library Files
We want our page to look like it belongs in Share and this means adding in the header and footer (unless of course you want to use the 'hybrid' template that automatically adds these for you - to do this, render the page using 'share/page/hdp/...' rather than 'share/page/dp/...'). To include the header and footer we need to import the library files provided and then call the functions they provide to set up the initial page model:
var services = getHeaderServices(),
widgets = getHeaderModel('Data Lists');
model.jsonModel = getFooterModel(services, widgets);
It's essential that imports as the first lines of your WebScript controller (not even comments can come before or between them) otherwise an error will be generated. When calling 'getHeaderModel' we can optionally provide a page title as we are doing here.
We're going to tweak the layout by using a combination of 'alfresco/layout/HorizontalWidgets' and 'alfresco/layout/VerticalWidgets' to place our widgets as we want them on the screen. There are other widgets in the 'alfresco/layout' package that we could use as well - one option would have been to use the 'alfresco/layout/AlfSideBarContainer' widget to add in a resizeable sidebar - but in this case I'm just fixing a sidebar using applying a fixed width to a child widget in a HorizontalWidgets instance as described in this previous post. Since it's already been covered I'm not going to include the code here, but please download the example code to review it.
Adding a New Item Button
This was actually the most interesting part of this example because we need to vary the published payload of a 'New Item' button for all of the different Data List types and instances. This is because we needed to include the NodeRef of the Data List to add an item to as well as the specific form controls for the Data List type that was currently being shown.
I considered a variety of alternatives to solve this and each had their merits, but I decided to extend 'alfresco/button/AlfButton' to support the use case but eventually decided that the new widget was such a valuable addition that I added it straight into the main Alfresco code base. This in itself demonstrates another benefit of Aikau - because all the code is so decoupled it is so much easier to accept contributions of individual widgets without causing any major disruptions.
Anyway... the new widget is 'alfresco/buttons/AlfDynamicPayloadButton' and allows you to create subscriptions to topics that update the payload on publication. In this case we are able to subscribe to the 'BLOG_LOAD_DATA_LIST' topic that was setup in the previous blog post to set the 'alf_destination' request parameter as follows:
topic: pubSubScope + 'BLOG_LOAD_DATA_LIST',
In this example we listen for publications on the (scoped) 'BLOG_LOAD_DATA_LIST' topic and then update the publication payload of the button when the topic is published on. The 'nodeRef' attribute of the published payload is mapped to the 'formSubmissionPayloadMixin.alf_destination' attribute of the buttons 'publishPayload' attribute (note that we can use dot-notation syntax to set nested attributes).
Dynamic Button Visibility
We need to create a new button for every Data List type (because each Data List type expects different properties and therefore we need to specify different form controls) so we end up with more than one button. So that only one button is displayed at a time we use the 'visibilityConfig' (described in this previous blog post) to only show the appropriate button for the currently selected Data List:
topic: pubSubScope + 'BLOG_LOAD_DATA_LIST',
Note that we're triggered off the same topic that is published whenever a user clicks on a specific Data List and that our rule is based on the name of the current data list (see the full code, but 'dataListTypes' is the array of Data Lists being iterated over to build the buttons).
We also set an initial visibility of false so that it's not possible for a user to try and create a new Data List item until a Data List has been selected.
I've also added an 'alfresco/renderers/PublishAction' widget to each rendered item as was done for the Data List list. However, since that has already been described in this previous blog post I won't go into it again. However it is worth mentioning that I could have added another instance for opening an edit dialog.
This obviously isn't the finished article and doesn't provide all the capabilities that the existing Data List page in Share provides. The idea is to illustrate that it's relatively easy to build functional pages for an Alfresco Repository using Aikau by simply re-using existing REST APIs and widgets. Hopefully we'll be able to use Aikau to re-write Data Lists (as well as the other site pages) in a future Alfresco release.
Example In Action
This screenshots shows the page in action:
Download the complete example code here.