Skip navigation
All Places > Alfresco Content Services (ECM) > Blog > 2014 > September > 29

Introduction



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



Sometimes you want to be able to create things. And sometimes you want to be able to do this via a form dialog without going to a new page.

Example



This post picks up where the last one left off. I'm going to assume that you've already worked your way through the post or have at least downloaded the example JAR and taken a look at the code. We've already built a basic list of our Data Lists with the ability to delete individual items and inline edit the title of each Data List. We now want to provide the ability to create new Data Lists to add to our list.

Getting the Data List Container



Data Lists in Share are created within sites and each Data List is a new node created within a 'container' folder within the site. When creating a new Data List we need to know the nodeRef of that container to include in our POST request. Since the REST API doesn't support creation using site and container IDs we'll need to obtain the container nodeRef in our WebScript. This doesn't actually relate to Aikau in any way other than to show you that you can build data on the server before sending it to the client:

var alfDestination = null;

var result =

  remote.call('/slingshot/datalists/lists/site/datalistexample/dataLists');

if (result.status.code == status.STATUS_OK)

{

  alfDestination = JSON.parse(result).container;

}


If I was doing this for real, I'd probably want to use more defensive code but the snippet above is sufficient for the purposes of this example.

Create a form



We now want to create the form controls to capture the data required for our POST request:

var formControls = [

  {

    name: 'alfresco/forms/controls/DojoValidationTextBox',

    config: {

      name: 'alf_destination',

      value: alfDestination,

      visibilityConfig: {

        initialValue: false

      }

    }

  },

  {

    name: 'alfresco/forms/controls/DojoValidationTextBox',

    config: {

      label: 'Title',

      name: 'prop_cm_title',

      requirementConfig: {

        initialValue: true

      }

    }

  },

  {

    name: 'alfresco/forms/controls/DojoTextarea',

    config: {

      label: 'Description',

      name: 'prop_cm_description'

    }

  },

  {

    name: 'alfresco/forms/controls/DojoSelect',

    config: {

      label: 'List Type',

      name: 'prop_dl_dataListItemType',

      value: 'dl:event',

      optionsConfig: {

        publishTopic: 'ALF_GET_FORM_CONTROL_OPTIONS',

        publishPayload: {

          url: url.context + '/proxy/alfresco/api/classes/dl_dataListItem/subclasses',

          itemsAttribute: '',

          labelAttribute: 'title',

          valueAttribute: 'name'

        }

      }

    }

  }

];


Since i've already covered the basics of defining forms I'll focus on just the last control which is the 'alfresco/forms/controls/DojoSelect'.  The key thing to note about this is the 'optionsConfig' section which allows us to define how to retrieve and render the options to make available to the user.



We're going to use the 'alfresco/services/OptionsService' (which will be added into the page's JSON model later) to handle requests for options. This service is designed to return data in the structure that form controls expect and allows you to specify the:



  • itemsAttribute - a dot-notation property to look-up in the JSON response body that identifies an array of options (setting as the empty string indicates that the entire response is an array)


  • labelAttribute - the dot-notation property to use in each option as the label


  • valueAttribute - the dot-notation property to use in each option as the value


Use a dialog



We want to add a button to the page that will popup a dialog containing our form. Dialogs can be created using the 'alfresco/dialogs/AlfDialogService' and the is a topic just for form specific dialogs:

var button = {

  name: 'alfresco/buttons/AlfButton',

  config: {

    label: 'New List',

    additionalCssClasses: 'call-to-action',

    publishTopic: 'ALF_CREATE_FORM_DIALOG_REQUEST',

    publishPayloadType: 'PROCESS',

    publishPayloadModifiers: ['processCurrentItemTokens'],

    publishPayload: {

      dialogTitle: 'New List',

      dialogConfirmationButtonTitle: 'Save',

      dialogCancellationButtonTitle: 'Cancel',

      formSubmissionTopic: 'ALF_CRUD_CREATE',

      formSubmissionPayloadMixin: {

        url: 'api/type/dl%3AdataList/formprocessor'

      },

      fixedWidth: true,

      widgets: formControls

    }

  }

};


When clicked the 'alfresco/buttons/AlfButton' will publish the configured payload on the specified topic. Hopefully you now recognise many of the attributes from the previous blogs posts (e.g. 'publishTopic', 'publishPayload', 'publishPayloadType', 'publishPayloadModifiers') so I'll focus on the dialog specific attributes.



The 'dialogTitle', 'dialogConfirmationButtonTitle' and 'dialogCancellationButtonTitle' should hopefully be self-explanatory. The 'widgets' are just the form controls that we have previously defined (it's not necessary to create the 'alfresco/forms/Form' since the DialogService handles this for us).



Whenever the confirmation button on the dialog is clicked the value of the form will be published on the 'formSubmissionTopic' (which in this case will be handled by our trusty 'alfresco/services/CrudService') and additional data can be 'mixed in' via the 'formSubmissionPayloadMixin' (in this case the actual URL that the CrudService will need to POST to).

Put it all together



Now we just need to add the new definitions and services into our page:

model.jsonModel.services.push('alfresco/dialogs/AlfDialogService',

                              'alfresco/services/OptionsService');

model.jsonModel.widgets.splice(0, 0, button);


Example in action



This is defined in a JavaScript controller for a WebScript mapped to the /crudServiceCreate URL. When deployed to a Share (or any Surf based Aikau application) this can be accessed by the URL: http://localhost:8081/share/page/dp/ws/crudServiceCreate



These screenshots shows the page in action:



DataListCreate1



DataListCreate2



DataListCreate5



DataListCreate4



You can download the entire example here.



Introduction



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



Sometimes you want to be able to update things. And sometimes you want to be able to update things directly from where you see them listed.

Example



This post picks up where the last one left off. I'm going to assume that you've already worked your way through the post or have at least downloaded the example JAR and taken a look at the code. We've already built a basic list of our Data Lists and provided the ability to delete Data Lists by clicking an icon associated with each entry. We now want to switch the existing 'alfresco/renderers/Property' widget for an 'alfresco/renderers/InlineEditProperty' widget to allow inline editing, this is done as follows:

var dataListTitle = widgetUtils.findObject(model.jsonModel.widgets, 'id', 'DATA_LIST_TITLE');

dataListTitle.name = 'alfresco/renderers/InlineEditProperty';

dataListTitle.config = {

  propertyToRender: 'title',

  postParam: 'prop_cm_title',

  refreshCurrentItem: true,

  requirementConfig: {

    initialValue: true

  },

  publishTopic: 'ALF_CRUD_CREATE',

  publishPayloadType: 'PROCESS',

  publishPayloadModifiers: ['processCurrentItemTokens', 'convertNodeRefToUrl'],

  publishPayloadItemMixin: false,

  publishPayload: {

    url: 'api/node/{nodeRef}/formprocessor',

    noRefresh: true,

    successMessage: 'Update success'

  }

};


Let's break down the configuration as we did before:

Publication Updates



The changes here are largely similar to those that were made in the DELETE example. One curiosity here is that we have to use the 'ALF_CRUD_CREATE' topic to perform a POST request rather than an 'ALF_CRUD_UPDATE' topic because the FormsProcessor doesn't support PUT ! The other configuration attributes of note are that we set 'publishPayloadItemMixin' to false to change the default behaviour of including the 'currentItem' object in the publication (because it would confuse the FormsProcessor) and that we set 'noRefresh' to true in the payload to override the default behaviour of publishing a reload topic to refresh the list.

InlineEditProperty



As it's name suggests this widget allows inline editing of properties. This widget (like all Aikau widgets) has been written to be extendable (the 'alfresco/renderers/InlineEditSelect' is an example of extending it). Essentially it just uses an 'alfresco/forms/Form' widget (again - an example of how Aikau aims to re-use as much code as possible) so that we leverage all the power of the forms handling widgets. The main configuration settings to note are that we set 'postParam' when the 'propertyToRender' doesn't match the expected request parameter on the REST API (if 'postParam' is omitted then the request parameter name will be the configured 'propertyToRender' value. Setting 'refreshCurrentItem' to true we ensure that any changes are applied to any other widgets dependant upon the 'currentItem' object. The 'requirementConfig' is the same as is used in Aikau form widgets and this piece of configuration is just delegated onto the underlying form control (in this case an 'alfresco/forms/controls/DojoValidationTextBox').

Example In Action



This is defined in a JavaScript controller for a WebScript mapped to the /crudServiceUpdate URL. When deployed to a Share (or any Surf based Aikau application) this can be accessed by the URL: http://localhost:8081/share/page/dp/ws/crudServiceUpdate This screenshots shows the page in action: DataListsUpdate DataListsUpdateInline DataListsUpdated   You can download the complete example here.

Introduction



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, show case how to use existing widgets or how to create new ones.

Real World Use Case



Sometimes you want to be able to delete things. And sometimes you want to be able to delete things directly from where you see them listed.

Example



This post picks up where the last one left off. I'm going to assume that you've already worked your way through the post or have at least downloaded the example JAR and taken a look at the code.



We've already built a basic list of our Data Lists and now we want to provide an action icon that when clicked will allow us to delete a Data List. This is achieved by using the 'alfresco/renderers/PublishAction' widget. We're going to update the JSON model that was defined in the previous blog post to add a new cell to each row of data in our view:

var deleteCell = {

  name: 'alfresco/documentlibrary/views/layouts/Cell',

  config: {

    widgets: [

      {

        name: 'alfresco/renderers/PublishAction',

        config: {

          iconClass: 'delete-16',

          propertyToRender: 'title',

          altText: 'Delete {0}',

          publishTopic: 'ALF_CRUD_DELETE',

          publishPayloadType: 'PROCESS',

          publishPayload: {

            requiresConfirmation: true,

            url: 'slingshot/datalists/list/node/{nodeRef}',

            confirmationTitle: 'Delete Data List',

            confirmationPrompt: 'Are you sure you want to delete '{title}'?',

            successMessage: 'Successfully deleted '{title}''

          },

          publishPayloadModifiers: ['processCurrentItemTokens', 'convertNodeRefToUrl']

        }

      }

    ]

  }

};

var viewRow = widgetUtils.findObject(model.jsonModel.widgets, 'id', 'VIEW_ROW');

viewRow.config.widgets.push(deleteCell);


There's quite a lot of configuration in this example, so let's break it down into small chunks.

Configuring the DELETE Payload



Firstly we want to define the action itself. We're going to publish on the 'ALF_CRUD_DELETE' topic to which the 'alfresco/services/CrudService' subscribes and we want to identify the specific item that we want to delete.



When defining a publication payload you can optionally select a number of different payload types and here we are setting the 'publishPayloadType' attribute to be 'PROCESS' to indicate that we want to perform some processing on the payload.



A number of processors have been initially included in Aikau and we specify two of them in the 'publishPayloadModifiers' array:



  • 'processCurrentItemTokens' looks for all string data wrapped in curly braces (e.g. the {nodeRef} in 'slingshot/datalists/list/node/{nodeRef}') and converts it to the matching entry in the 'currentItem'.


  • 'convertNodeRefToUrl' replaces any occurence of '://' with '/' to make NodeRef data URL friendly.


Confirmation Prompting



The CrudService recognizes that DELETE actions may require a confirmation so we include a 'requiresConfirmation' attribute in the payload as well as the messages to use in the confirmation dialog title, confirmation dialog body and the subsequent success message (note that we're able to include 'currentItem' tokens in the message strings because the 'currentItem' is always included in the publication to the service).

Icon and Accessibility



The last part of the configuration to describe is that we specify the icon using the 'iconClass' attribute and the 'altText' for the icon. The 'propertyToRender' attribute is available for use as a message token in the alt text so we can provide meaningful text on the action.

Example In Action



This is defined in a JavaScript controller for a WebScript mapped to the /crudServiceDelete URL. When deployed to a Share (or any Surf based Aikau application) this can be accessed by the URL: http://localhost:8081/share/page/dp/ws/crudServiceDelete



This screenshots shows the page in action:



DataListDelete



DataListDeletePromptYou can download the complete example here.



 



Introduction



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



At some stage you're going to need to work with some data and Aikau is specially created to work with Alfresco repositories. The widgets are de-coupled from data by using client-side services as a go-between for getting and setting data on over the Alfresco Repository REST API. Most web applications are ultimately just lists and forms and Share is no different - one area that hasn't had a lot of work recently is the Data Lists in Sites. This area has lots of examples of getting and setting data in a number of different ways. This post and following posts will show how we can use Aikau to work with Data List data.

Example



In this example we're going to do nothing more complicated than just retrieving the list of Data Lists from the Repository. The purpose is just to introduce the 'alfresco/services/CrudService' module as well as basic list building.

Prerequisites



We could have started by actually using the CrudService to create some data lists, but it makes more sense to actually create some data to start of with so that you can compare the existing implementation with the Aikau version, so please do the following:



  1. Log into Alfresco Share


  2. Create a site


  3. Customize the site and add Data Lists to it


  4. Create some data lists (doesn't matter what they are).


Share Data Lists

Pick an API, any API...



Aikau provides a number of dedicated services for working with data (e.g. 'alfresco/services/DocumentService', 'alfresco/services/SearchService', etc.) which typically perform some additional work or error checking to the basic data manipulation. The 'alfresco/services/CrudService' is different in that it provides the raw capability to work with a REST API. Currently there is no dedicated service for working with Data Lists so we're going to use the CrudService for accessing the Data List APIs.

Service Dependencies



First we need to make sure that the CrudService is available on the page. This is done by including in in the list of services in the JSON model for the page.

model.jsonModel = {

  services: [

    'alfresco/services/CrudService'

  ]

};


The majority of services don't require any configuration so can be added to the list as a string. However, it's also possible to add services into the array as objects with name/config attributes as is done with widgets.

Define a List



The most simple form of list in Aikau is the 'alfresco/lists/AlfList' widget that provides basic list capabilities. This is extended by the 'alfresco/lists/AlfHashList' (that allows requests to be manipulated by the URL hash fragment) and the 'alfresco/lists/AlfSortablePaginatedList' (that provides support for sorting and pagination) which is in turn extended by specialist lists such as the 'alfresco/documentlibrary/AlfDocumentList' and 'alfresco/documentlibrary/AlfSearchList', etc. For this example we just need simple capabilities so the basic 'AlfList' widget is sufficient.

var list = {

  name: 'alfresco/lists/AlfList',

  config: {

    loadDataPublishTopic: 'ALF_CRUD_GET_ALL',

    loadDataPublishPayload: {

      url: 'slingshot/datalists/lists/site/datalistexample/dataLists'

    },

    itemsProperty: 'datalists'

  }

};


In this example we are essentially defining the data that we want to work with. The 'loadDataPublishTopic' defines the topic to publish to request data, and the 'loadDataPublishPayload' defines the payload to send when requesting data. We are using a topic defined by the CrudService and which is designed to work with the Alfresco Repository REST API so we do not need to include the full address, just the WebScript declared URL fragment.



It would be nice if all the Alfresco REST APIs used a consistent attribute for the arrays of data that they return but since this is not the case, we can instruct the AlfList to use a specific property in the response body to get the array from using the 'itemsProperty' configuration attribute (note: this will also accept dot-notation values).

Define a View



An 'alfresco/lists/AlfList' widget (and all it's descendants) can render multiple views of data. These are set as the 'widgets' config attribute and in order to actually display any data an AlfList needs to have a least one view configured.



It's possible to build almost any view and you can either re-use the existing view and data rendering widgets or build your own. In this case we're just going to build our view of data as a list of rows, each containing a single cell with a single data renderer.

var views = [

  {

    name: 'alfresco/documentlibrary/views/AlfDocumentListView',

      config: {

      widgets: [

        {

          id: 'VIEW_ROW',

          name: 'alfresco/documentlibrary/views/layouts/Row',

          config: {

            widgets: [

              {

                name: 'alfresco/documentlibrary/views/layouts/Cell',

                config: {

                widgets: [

                  {

                    name: 'alfresco/renderers/Property',

                    config: {

                      propertyToRender: 'title'

                    }

                  }

                ]

              }

            }

          ]

        }

      }

    ]

  }

}];


View definitions can get quite long and if you define a view that you want to re-use then it makes sense to extend 'alfresco/documentlibrary/views/AlfDocumentListView' and declare the widget model in your own subclass (see 'alfresco/documentlibrary/views/AlfSimpleView' and 'alfresco/documentlibrary/views/AlfDetailedView' as examples of this).



The reason that a lot of the list and view modules are defined in the 'alfresco/documentlibrary/' package is purely historical since most of the list and view code has been abstracted from Document Library specific use cases.



Finally we just need to pull all the individual bits together:

list.config.widgets = views;

model.jsonModel.widgets = [list]


Example In Action



This is defined in a JavaScript controller for a WebScript mapped to the /crudService URL. When deployed to a Share (or any Surf based Aikau application) this can be accessed by the URL: http://localhost:8081/share/page/dp/ws/crudService



This screenshot shows the result:



Aikau Data Lists



Obviously this isn't especially exiting or indeed useful... the purpose is just to demonstrate how to access data. You can check out the page models for the document and search views for more complex examples of what is possible.



Download the complete example here.



 



Filter Blog

By date: By tag: