Aikau Mini Examples - CRUD Service (create)

cancel
Showing results for 
Search instead for 
Did you mean: 

Aikau Mini Examples - CRUD Service (create)

ddraper
Intermediate II
0 5 9,185

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.



5 Comments
blog_commenter
Active Member
[…] post picks up where the last one left off. Since I’d started using Data Lists as a case study for demonstrating the […]
blog_commenter
Active Member
Thanks for this great tutorial.

I've some trouble with the 4.2.f version:  ReferenceError: 'JSON' is not defined

Where can'i get this object?
ddraper
Intermediate II
JSON is a native JavaScript object that is not available in the Rhino JavaScript engine used in Alfresco 4.x ... to take advantage of the JSON native object you'll need to use 5.x in order to have access to the updraded version of Rhino. You can try using the jsonUtils object instead.
blog_commenter
Active Member
Hey,
I have a question. I use 'alfresco/services/SiteService'  to retrieve all sites (same like 'site manager' under admin tools in share - just copied the code). But What I want is add an extra column with a button. So far no problem. But I am not able to provide the button the site name as payload - in other word I would like that when the button is clicked, the site name is provided so that my custom publishTopic subscription may be able to do something - it must now the site name .

Here the code, which is direct inside the 'alfresco/documentlibrary/views/layouts/Row' widget which contains following widget :



{
  name: 'alfresco/documentlibrary/views/layouts/Cell',
  config: {
    additionalCssClasses: 'siteManager mediumpad',
    widgets: [
      {
        name: 'alfresco/buttons/AlfButton',
        config: {
          useHash: true,
   publishPayloadType: 'BUILD',
   publishPayloadModifiers: ['processCurrentItemTokens'],
   label: 'Bearbeiten',
   // iconClass: 'alf-folder-up-icon',
   publishTopic: 'HUZ_EDIT_SITE_DIALOG',
   publishPayload: {
     siteName: {shortName}
   }
        }
      }
    ]
  }
};



In other widgets like property link widget ('alfresco/renderers/PropertyLink') I may add inside the 'publishPayload' the properties of the clicked row which then are accessible. I would appreciate your help very much!
ddraper
Intermediate II
@christof: Have you read through the tutorial chapter that covers the PublishAction widget (https://github.com/Alfresco/Aikau/blob/master/tutorial/chapters/Tutorial9.md) or reviewed the JSDoc (http://dev.alfresco.com/resource/docs/aikau-jsdoc/PublishAction.html) for it?



To start with you should probably be using the 'PROCESS' rather than 'BUILD' publishPayloadType - that should work with the rest of your configuration ('BUILD requires special attributes in the payload).