In a previous blog post I showed how Aikau was beginning to provide support for the XML-based Forms Runtime that Share uses to render forms using the old YUI2 controls. I then wrote additional blogs showing how it could be used to build Aikau pages for Tasks and Data Lists. I've recently looked into how the forms runtime is used to provide the Advanced Search page in Share and have added some updates into the 1.0.91 release to support a new Share extension that you can find here. This is provided as an extension module that was created using the approach described in this blog post.
PLEASE NOTE: In order to test this out you'll need at least aikau 1.0.91 JAR as well as the matching version of the aikau-forms-runtime-support JAR. These will need to be placed in your share/WEB-INF/lib folder (the server will need to be restarted).
In order to perform an advanced search in Share it is necessary to go to the Advanced Search page. This allows you to select from a number of search forms configured in the Share forms runtime. When you select a form type ("Content" and "Folder" are the only two provided out-of-the-box) the form is loaded, shown on the page and you can then enter parameters that are relevant for searching for the data type matched to the form.
The sample extension provides a way in which advanced search could be used without switching pages. The purpose of this extension is just to show how you can make use of the Aikau FormsRuntimeService to work with existing form configuration. Let's step through the solution..
The FormsRuntimeService is not included in the page by default, so we need to add it into the array of services in the model. In the faceted-search.get.js controller extension this can be done as follows:
model.jsonModel.services.push("alfresco/services/FormsRuntimeService");
We're going to allow the user to initiate an advanced search by clicking a button (this isn't the only solution we could have applied, but it's very simple). We can use the "Developer Tools" (described in this blog post) to identify the widget to add the button to and to get the code snippet for finding that widget in the model.
var menubar = widgetUtils.findObject(model.jsonModel.widgets, "id", "FCTSRCH_TOP_MENU_BAR");
if (menubar && menubar.config && menubar.config.widgets)
{
menubar.config.widgets.push(getAdvancedSearchButton());
}
In the code snippet above you'll see that we're calling the getAdvancedSearchButton function - we now need to define this function to create a button.
function getAdvancedSearchButton() {
return {
name: "alfresco/buttons/AlfButton",
config: {
label: "Advanced Search",
additionalCssClasses: "call-to-action"
}
};
}
At the moment the button isn't going to do anything because has not been configured with publishTopic or publishPayload attributes. We want to generate a dialog to show the advanced search forms in, so we need to publish on the relevant topic for creating a dialog. The basic configuration would look like this:
publishTopic: "ALF_CREATE_DIALOG_REQUEST",
publishPayload: {
dialogId: "ADVANCED_SEARCH_DIALOG",
dialogTitle: "Advanced Search",
contentWidth: "1000px",
hideTopic: "ALF_ADVANCED_SEARCH"
}
This defines the basic configuration for the dialog itself, but provides no information for what should go into it - for that we need to provide a widgetsContent attribute.
We need to be able to switch between the different advanced search forms. When you want Aikau to dynamically update a rendered model it is convenient to use the DynamicWidgets widget. This will update the model displayed based on publications on the topic it is configured to subscribe to:
widgetsContent: [
{
name: "alfresco/layout/DynamicWidgets",
config: {
subscribeGlobal: true,
subscriptionTopic: "ADV_SEARCH_FORM_RETRIEVED"
}
}
]
When the dialog is displayed we want to automatically display a default advanced search form. This can be configured through the publishOnShow attribute. We want to publish on the ALF_FORM_REQUEST topic (which the FormsRuntimeService subscribes to) and provide the necessary information for the form to be rendered. The main attributes are itemId, itemKind, mode and formId. In addition to this we need to override some of the default behaviour.
We need to make sure that the DynamicWidgets instance receives the form model to be rendered so the alfSuccessTopic is configured to match the subcriptionTopic previously used.
The default behaviour of a form generated by the FormsRuntimeService is to publish to the CrudService, so we need to override that via the formConfig attribute. Here we are changing the button label to be "Search" and the button publish topic to be ALF_ADVANCED_SEARCH (subscribed to by the AlfSearchList already on the page).
Interestingly the "Keywords" field that you see on the Advanced Search page is not configured as part of the form so we need to add it in using the widgetsBefore attribute.
publishOnShow: [
{
publishTopic: "ALF_FORM_REQUEST",
publishPayload: {
itemId: "cm:content",
itemKind: "type",
mode: "edit",
formId: "search",
alfSuccessTopic: "ADV_SEARCH_FORM_RETRIEVED",
formConfig: {
okButtonLabel: "Search",
okButtonPublishTopic: "ALF_ADVANCED_SEARCH",
formSubmissionPayloadMixin: {
alfResponseScope: "ADV_SEARCH_",
datatype: "cm:content"
},
widgetsBefore: [
{
name: "alfresco/forms/controls/TextBox",
config: {
label: "Keywords",
name: "searchTerm"
}
}
]
}
},
publishGlobal: true
}
]
This configuration would now render an advanced search form, but we want to enable the user to switch between any advanced search form that has been configured. To do this we're going to add an Aikau Form into the widgetsContent array to provide this.
Within the form we have a Select widget for choosing the form to display (hard-coded here to provide the out-of-the-box types). The form is configured to automatically save on changes using the autoSavePublishTopic (which publishes the ALF_FORM_REQUEST again) and the autoSavePublishPayload roughly matches that of the publishOnShow configuration previously used.
The purpose of the hidden TextBox that copies the selected form value is described in more detail here.
{
name: "alfresco/forms/Form",
config: {
autoSavePublishTopic: "ALF_FORM_REQUEST",
autoSavePublishGlobal: true,
autoSavePublishPayload: {
itemKind: "type",
mode: "edit",
formId: "search",
alfSuccessTopic: "ADV_SEARCH_FORM_RETRIEVED",
formConfig: {
okButtonLabel: "Search",
okButtonPublishTopic: "ALF_ADVANCED_SEARCH",
formSubmissionPayloadMixin: {
alfResponseScope: "ADV_SEARCH_"
},
widgetsBefore: [
{
name: "alfresco/forms/controls/TextBox",
config: {
label: "Keywords",
name: "searchTerm"
}
}
]
}
},
widgets: [
{
name: "alfresco/forms/controls/Select",
config: {
fieldId: "SELECT_FORM",
label: "Look for",
description: "This indicates the type of thing that you want to search for",
name: "itemId",
optionsConfig: {
fixed: [
{
label: "Content", value: "cm:content"
},
{
label: "Folder", value: "cm:folder"
}
]
}
}
},
{
name: "alfresco/forms/controls/TextBox",
config: {
fieldId: "DATA_TYPE",
name: "formConfig.formSubmissionPayloadMixin.datatype",
autoSetConfig: [
{
copyRule: {
targetId: "SELECT_FORM"
}
}
],
visibilityConfig: {
initialValue: false
}
}
}
]
}
}
The video below shows the advanced search in action. This is quite an involved use of the FormsRuntimeService but does show how it is beginning to support advanced customization - if you have any use cases that you'd like to see solved then please comment below.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.