How to customise action buttons

Paolo Predonzani edited this page Dec 26, 2017 · 3 revisions

The previous page left us with a customised view for owd:dossier objects, but with the buttons still performing the default stub action.

This page will show how to connect the buttons to actions that actually change a dossier's status. Clicking on the "Mark active" button will change the status to Active, clicking on "Mark retired" will change the status to Retired. Simple as that.

Customised action buttons in alfresco-inboxes

To implement the status change, we're going to use a CMIS update call. We're also going to see why this approach and the possible alternatives.

How buttons are connected to events

Buttons are primarily user interface objects so a good place to start studying them is the html template that generates them. Open the Item.html file located at src/main/amp/web/js/softwareloop/inboxes/templates/ in the source distribution. The relevant lines are shown here:

<button class="inboxes-item-button inboxes-item-button-approve"
    data-dojo-attach-event="click:approveAction">${approveLabel}
</button>
<button class="inboxes-item-button inboxes-item-button-reject"
    data-dojo-attach-event="click:rejectAction">${rejectLabel}
</button>

The data-dojo-attach-event attribute is the one involved in event handling. Its value click:approveAction provides the specific details of what event to attach to (click) and the function name to be called (approveAction). The attribute and the whole mechanism are specific to Dojo/Aikau. There is some automatic processing performed by the framework, going on behind the scenes, that translates the custom attribute in regular event listeners attached to the button's node. The details are explained in Dojo's documentation.

Here we're only interested in the result of this html fragment: when the "Mark active" (or "Mark retired") button is pressed, the event handler function approveAction() (or rejectAction()) is invoked on the component.

The event handlers

The component is the Dossier.js we discussed in the previous page. The two event handler functions are shown below:

approveAction: function () {
    this.updateStatus("Active");
},

rejectAction: function () {
    this.updateStatus("Retired");
},

The functions simply delegate the actual change in status to updateStatus(), passing the desired status as an argument.

##CMIS update invocation

updateStatus() runs a webscript on Alfresco's repository with Share acting as a proxy between the browser and the repository. At the end of the update, it triggers a page reload.

updateStatus: function (status) {
    var url = lang.replace(
        "{proxyUri}cmis/s/workspace:SpacesStore/i/{entryId}",
        {
            proxyUri: Alfresco.constants.PROXY_URI,
            entryId: this.entry.id
        }
    );
    var dossierStatus = this.entry.attributes["owd:dossierStatus"];
    dossierStatus.values[0] = status;
    var updateAttributes = {};
    updateAttributes["owd:dossierStatus"] = dossierStatus;
    cmis.updateEntry(url, updateAttributes, function() {
        location.reload(false);
    });
}

The webscript responds to HTTP PUT invocations and takes an XML atom entry as its input, much like a CMIS query returns XML atom entries in its output. The details of the protocol are handled in the utility module "softwareloop/cmis/cmis"; Dossier.js only needs to invoke cmis.updateEntry().

In this code, only the owd:status attribute is updated. All other attributes are not transmitted to the CMIS update webscript and consequently are left unmodified.

CMIS alternatives

CMIS is a flexible protocol that does the job in our example. It is also natively supported by Alfresco's repository, which allowed us to focus on Share only, without writing any custom code for the repository. However CMIS has limitations of which you must to be aware in case you deal with other scenarios.

First, running a CMIS update requires the logged in user to have write permissions on the object. This may not always be the case. Sometimes in a workflow, a user can perform an approve/reject action but does not have write access to all the attributes of the object.

Second, CMIS supports CRUD on single objects but cannot perform a complex transaction on multiple related object.

Third, CMIS is not aware of and cannot operate directly on Activiti.

When CMIS is not sufficient, the alternative is to write a custom webscript on Alfresco's repository to perform the required operation. Custom webscripts benefit from transactions, can operate on multiple objects, can apply permissions according to any logic and have access to a wide range of server-side APIs.

Conclusions

In many Alfresco projects, the requirements for UI customisations are as strong as for content model customisations. Sometimes users want the UI to expose more information, sometimes less, sometimes more or less depending on the task at hand.

Alfresco-inboxes makes customisations of presentation and actions very simple and accessible to most developers as hopefully this page has demonstrated.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.