cancel
Showing results for 
Search instead for 
Did you mean: 

Mutli Select Question - Alfresco Development

mags1703
Confirmed Champ
Confirmed Champ

I'm working on a project in which I've developed an action that's working fine as a rule, as a doclib action on a document and as an action in the document detail page in Share using Alfresco CE 6.2-GA. For this I followed Jeff Potts excellent tutorial: http://ecmarchitect.com/alfresco-developer-series-tutorials/actions/tutorial/tutorial.html. I'm using the All-In-One SDK project, version 4.1, in Eclipse. I now need to apply this logic to a group of documents selected by the user in the multi select drop down menu. I don't need user interface like for example "Download as Zip".

I got my new menu item with icon in the drop down list which I configured in an extension module my-custom-share.xml file in a <multi-select> tag. It looks like this:

<config evaluator="string-compare" condition="DocumentLibrary">
<multi-select>
<action type="action-link" id="onActionMultiTag" asset="document" label="my-action-multi-tags" icon="my-action-tag-image"/>
</multi-select>
</config>

In the Share source code I found the actions.js file which I renamed to my-multitag-actions.js and added, as a copy of onActionDownload this piece of code:

onActionMultiTag: function dla_onActionMultiTag(record) {
var downloadDialog = Alfresco.getArchiveAndDownloadInstance(),
config = { nodesToArchive: [] };

if (record.length == 1)
{
config.nodesToArchive.push({"nodeRef": record[0].nodeRef});
config.archiveName = record[0].fileName;
}
else
{
for (var i=0; i<record.length; i++)
{
config.nodesToArchive.push({"nodeRef": record[i].nodeRef})
}
}
downloadDialog.show(config);
}

I placed this file under META-INF/resources/components/documentlibrary/my-multitag. In the extension module my-custom-share.xml I referenced this file like this:

<config evaluator="string-compare" condition="DocLibCustom" replace="true">
<dependencies>
<js src="components/documentlibrary/my-multitag/my-multitag-actions.js" />
<css src="components/toolbar/custom-toolbar.css" />
</dependencies>
</config>

I built the project and tested. I was expecting my menu to do the same as "Download as Zip" but nothing happens. I went into the Share container and found the actions.js file in webapps/share/components/documentlibrary/actions.js. My custom "my-multitag-actions.js" is inside webapps/share/WEB-INF/lib/my-custom-share-1.0-SNAPSHOT.jar. I found that if I paste the onActionMultiTag code into webapps/share/components/documentlibrary/actions.js and restart the container my menu selection works like "Download as Zip".

I suppose the problem is how or where to override actions.js (among other potential problems further on).

Can anybody point me to a tutorial for creating a multi-select action from scratch? I've searched all over and haven't found any complete reference of how to do this.

Thanks.

4 REPLIES 4

afaust
Legendary Innovator
Legendary Innovator

Adding new actions to the document library (this includes the toolbar) is actually reasonably weil documented in the official documentation.

The only thing that they are lacking is a description on the difference in call parameters between multi-select and single item actions. While a single item action will get a "record" parameter of a single object, the multi-select actions get a "records" parameter, which is an array of the same kind of objects. Since the action registered via the official extension point is registered both with the toolbar (multi-select) and the document list (single item), it can be called in both ways and needs to be aware of that, if it wants to support both use cases.

Alternatively, you can also selectively extend only the toolbar component, if you want to limit an action to that scope. I have used that approach to override or complement default toolbar actions, e.g. adding an alternative delete multi-select action which fails if any one file fails to be deleted and provides proper feedback (https://github.com/Acosix/alfresco-utility/blob/master/core/share/src/main/webapp/acosix/components/...).

Thanks for your reply. I'll examine the code and report back

Axel,

After following the https://docs.alfresco.com/6.2/tasks/dev-extensions-share-tutorials-add-action-doclib.html tutorial my understanding improved. I got muy multi-select menu item to do the same as "Download as Zip" with this code in custom-actions.js:

....
YAHOO.Bubbling.fire("registerAction",
{
actionName: "onActionMultiTag",
fn: function org_alfresco_training_onActionMultiTag(record) {
var downloadDialog = Alfresco.getArchiveAndDownloadInstance(),
config = { nodesToArchive: [] };
if (record.length == 1)
{
config.nodesToArchive.push({"nodeRef": record[0].nodeRef});
config.archiveName = record[0].fileName;
}
else
{
for (var i=0; i<record.length; i++)
{
config.nodesToArchive.push({"nodeRef": record[i].nodeRef})
}
}
downloadDialog.show(config);
}
});
....

In this bit of code what's involved in calling my Java class?

Perhaps I have to create a webscript with the class and use the "Call-Web-Script" example as my starting point. In that case, how would I send the nodeRef array in this bit of code?

YAHOO.Bubbling.fire("registerAction",
{
actionName: "onActionCallWebScript",
fn: function org_alfresco_training_onActionCallWebScript(file) {
this.modules.actions.genericAction(
{
success: {
callback: {
fn: function org_alfresco_training_onActionCallWebScriptSuccess(response) {
Alfresco.util.PopupManager.displayPrompt(
{
title: this.msg("alfresco.tutorials.doclib.action.callWebScript.msg.success"),
text: JSON.stringify(response.json),
buttons: [
{
text: this.msg("button.ok"),
handler: function org_alfresco_training_onActionCallWebScriptSuccess_success_ok() {
this.destroy();
},
isDefault: true
},
{
text: this.msg("button.cancel"),
handler: function org_alfresco_training_onActionCallWebScriptSuccess_cancel() {
this.destroy();
}
}]
});
},
scope: this
}
},
failure: {
message: this.msg("alfresco.tutorials.doclib.action.callWebScript.msg.failure",
file.displayName, Alfresco.constants.USERNAME)
},
webscript: {
name: "sample/fileinfo?nodeRef={nodeRef}",
stem: Alfresco.constants.PROXY_URI,
method: Alfresco.util.Ajax.GET,
params: {
nodeRef: file.nodeRef
}
},
config: {}
});
}
});

The sample webscript would just count the number of documents.

Thanks.

Axel,

In the meantime I've wrapped my action logic in a Java class webscript where I call the action logic in a loop for each NodeRef. It might not be the best way but performance is not an issue in this case. I call my webscripot this way:

http://localhost:8080/alfresco/service/multitagwebscript/workspace://SpacesStore/e54a0c20-48e3-4620-a2a0-864d38a10a6c

It's defined like this:

<url>/multitagwebscript/{nodeRef}</url>

I also know the menu selection is working becuae when I use this code:

YAHOO.Bubbling.fire("registerAction",
{
actionName: "onActionImageMultiTag",
fn: function org_alfresco_training_onActionImageMultiTag(images) {
var nodesRef = [];
var ii = 0;
for (var i=0, ii=images.length ; i<ii ; i++){
nodesRef.push(images[i].nodeRef);
}
Alfresco.util.PopupManager.displayMessage(
{
text: this.msg("alfresco.tutorials.doclib.action.showCustomMessage.text",
i, Alfresco.constants.USERNAME)
});
}
});

the popup shows the number of documents selected.

What I haven't been able to do is to call the webscript from the custom-doclib-actions.js code. I have this:

YAHOO.Bubbling.fire("registerAction",
{
actionName: "onActionImageMultiTag",
fn: function org_alfresco_training_onActionImageMultiTag(images) {
var nodesRef = [];
var ii = 0;
for (var i=0, ii=images.length ; i<ii ; i++){
nodesRef.push(images[i].nodeRef);
}
this.modules.actions.genericAction(
{
success: {
callback: {
fn: function org_alfresco_training_onActionImageMultiTagSuccess(response) {
Alfresco.util.PopupManager.displayPrompt(
{
title: this.msg("alfresco.tutorials.doclib.action.ImageMultiTag.msg.success"),
text: JSON.stringify(response.json),
buttons: [
{
text: this.msg("button.ok"),
handler: function org_alfresco_training_onActionImageMultiTagSuccess_success_ok() {
this.destroy();
},
isDefault: true
}]
});

},
scope: this
}
},
failure: {
message: this.msg("alfresco.tutorials.doclib.action.ImageMultiTag.msg.failure")
},
webscript: {
name: "multitagwebscript/{nodeRef}",
stem: "http://localhost:8080/alfresco/service/",
method: Alfresco.util.Ajax.GET,
params: {
nodeRef: nodesRef
}
},
config: {}
});
}
});

What syntax do I need for this part?

webscript: {
name: "multitagwebscript/{nodeRef}",
stem: "http://localhost:8080/alfresco/service/",
method: Alfresco.util.Ajax.GET,
params: {
nodeRef: nodesRef
}
},

Thanks.