/**
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* This renders a drop-down select menu using a wrapped [Select]{@link module:alfresco/forms/controls/Select}
* widget that when changed will publish information about the change in value for the current rendered item.
*
* @module alfresco/renderers/PublishingDropDownMenu
* @extends module:aikau/core/BaseWidget
* @mixes external:dijit/_OnDijitClickMixin
* @mixes module:alfresco/renderers/_PublishPayloadMixin
* @author Dave Draper
*/
define(["dojo/_base/declare",
"aikau/core/BaseWidget",
"dijit/_OnDijitClickMixin",
"alfresco/renderers/_PublishPayloadMixin",
"alfresco/core/ObjectTypeUtils",
"alfresco/forms/controls/Select",
"dojo/_base/lang",
"dojo/dom-class"],
function(declare, BaseWidget, _OnDijitClickMixin, _PublishPayloadMixin, ObjectTypeUtils,
Select, lang, domClass) {
return declare([BaseWidget, _OnDijitClickMixin, _PublishPayloadMixin], {
/**
* An array of the CSS files to use with this widget.
*
* @instance
* @type {object[]}
* @default [{cssFile:"./css/PublishingDropDownMenu.css"}]
*/
cssRequirements: [{cssFile:"./css/PublishingDropDownMenu.css"}],
/**
* An array of the i18n files to use with this widget.
*
* @instance
* @type {Array}
*/
i18nRequirements: [{i18nFile: "./i18n/PublishingDropDownMenu.properties"}],
/**
* Optional override for the title text to be displayed when hovering over the cancel "button"
*
* @instance
* @type {String}
*/
cancelPublishLabel: null,
/**
* This is the topic that will be published on when the drop-down menu value is changed.
*
* @instance
* @type {string}
* @default
*/
publishTopic: null,
/**
* This will be set to reference the [Select]{@link module:alfresco/forms/controls/Select} that is
* wrapped by this widget.
*
* @instance
* @type {object}
* @default
*/
_dropDownWidget: null,
/**
* This is the options config that will be passed onto the wrapped [DojoSelect]{@link module:alfresco/forms/controls/Select}
* widget.
*
* @instance
* @type {object}
* @default
*/
optionsConfig: null,
/**
* This is the dot-property that will be evaluated on the current item being rendered to determine whether or not
* the wrapped [select]{@link module:alfresco/forms/controls/Select} widget should be disabled. The value of the
* evaluated property is expected to be a boolean (or it will be evalutated as a "truthy"/"falsy" value, e.g. 0
* would be false and 1 would be true, the empty string false, any other string true, etc).
*
* @instance
* @type {string}
* @default
* @since 1.0.35
*/
disablementProperty: null,
/**
* Overrides [the inherited function]{@link module:aikau/core/BaseWidget#createWidgetDom}
* to construct the DOM for the widget using native browser capabilities.
*
* @instance
* @since 1.0.101
*/
createWidgetDom: function alfresco_renderers_PublishingDropDownMenu__createWidgetDom() {
this.containerNode = this.domNode = document.createElement("div");
this.domNode.classList.add("alfresco-renderers-PublishingDropDownMenu");
this.processingNode = document.createElement("div");
this.processingNode.classList.add("indicator");
this.processingNode.classList.add("processing");
this.processingNode.classList.add("hidden");
this.processingNode.setAttribute("tabindex", "0");
this.processingNode.setAttribute("title", this.cancelPublishLabel);
this._attach(this.processingNode, "ondijitclick", lang.hitch(this, this.onChangeCancel));
this.warningNode = document.createElement("div");
this.warningNode.classList.add("indicator");
this.warningNode.classList.add("warning");
this.warningNode.classList.add("hidden");
this.successNode = document.createElement("div");
this.successNode.classList.add("indicator");
this.successNode.classList.add("success");
this.successNode.classList.add("hidden");
this.dropDownNode = document.createElement("div");
this.domNode.appendChild(this.processingNode);
this.domNode.appendChild(this.warningNode);
this.domNode.appendChild(this.successNode);
this.domNode.appendChild(this.dropDownNode);
},
/**
*
* @instance
*/
postCreate: function alfresco_renderers_PublishingDropDownMenu__postCreate() {
if (ObjectTypeUtils.isString(this.propertyToRender) &&
ObjectTypeUtils.isObject(this.currentItem) &&
lang.exists(this.propertyToRender, this.currentItem))
{
// Get the value of the property to render...
this.value = lang.getObject(this.propertyToRender, false, this.currentItem);
// Set up the values needed to handle the pub/sub events coming out of the wrapped dropdown...
var uuid = this.generateUuid();
var fieldId = "DROPDOWN";
var subscriptionTopic = uuid + "_valueChangeOf_" + fieldId;
var isDisabled = this.disablementProperty && lang.getObject(this.disablementProperty, false, this.currentItem);
// Create the widget...
this._dropDownWidget = new Select({
id: this.id + "_SELECT",
additionalCssClasses: this.additionalCssClasses || "",
pubSubScope: uuid,
fieldId: fieldId,
value: this.value,
optionsConfig: this.optionsConfig,
disablementConfig: {
initialValue: isDisabled
}
}, this.dropDownNode);
// Create the subscription AFTER the widget has been instantiated so that we don't
// unnecessarily process the setup publications which are intended to be processed by
// other controls in the same scoped form...
this.alfSubscribe(subscriptionTopic, lang.hitch(this, this.onPublishChange), true);
if(this.additionalCssClasses)
{
domClass.add(this.domNode, this.additionalCssClasses);
}
}
else
{
this.alfLog("warn", "Property for PublishingDropDown renderer does not exist:", this);
}
},
/**
*
* @instance
* @param {object} payload The information about the change in value.
*/
onPublishChange: function alfresco_renderers_PublishingDropDownMenu__onPublishChange(payload) {
this.alfLog("log", "Drop down property changed", payload);
if (this.publishTopic !== null && !this._resetInProgress)
{
var updatePayload = this.generatePayload(this.publishPayload, this.currentItem, payload, this.publishPayloadType, this.publishPayloadItemMixin, this.publishPayloadModifiers);
// Get the selected value, this will only be confirmed on publication success
this._updatedValue = payload.value;
// Hide any previously displayed warning image and show the processing image...
domClass.remove(this.processingNode, "hidden");
domClass.add(this.warningNode, "hidden");
domClass.add(this.successNode, "hidden");
// Genereate a uuid for the response to ensure we only provide an update for our request...
var responseTopic = this.generateUuid();
this._updateSuccessHandle = this.alfSubscribe(responseTopic + "_SUCCESS", lang.hitch(this, this.onChangeSuccess));
this._updateFailureHandle = this.alfSubscribe(responseTopic + "_FAILURE", lang.hitch(this, this.onChangeFailure));
this._updateCancelHandle = this.alfSubscribe(responseTopic + "_CANCEL", lang.hitch(this, this.onChangeCancel));
updatePayload.responseTopic = responseTopic;
// Update the title text of the cancel button
this.processingNode.title = this.cancelPublishLabel || this.message("alf.renderers.PublishingDropDownMenu.cancelUpdate", this.value);
// Request to make the update...
this._reponsePending = true;
this.alfPublish(this.publishTopic, updatePayload);
}
else
{
this.alfLog("warn", "A drop-down property was changed but there is no 'publishTopic' defined to publish on", this);
}
},
/**
* This function is called whenever the request to update the value is completed successfully. It will hide the
* processing image and display the success image.
*
* @instance
* @param {object} payload
*/
onChangeSuccess: function alfresco_renderers_PublishingDropDownMenu__onChangeSuccess(payload) {
this.alfUnsubscribeSaveHandles([this._updateSuccessHandle,this._updateFailureHandle, this._updateCancelHandle]);
domClass.add(this.processingNode, "hidden");
domClass.remove(this.successNode, "hidden");
this.alfLog("log", "Update request success", payload);
// Update with the successfully applied value...
this.value = this._updatedValue;
this._reponsePending = false;
},
/**
* This function is called whenever the request to update the value fails. It will hide the
* processing image and display the warning image.
*
* TODO: Ideally this should include a popup failure message
* TODO: The CoreXhr standard failure dialog should be prevented from being displayed
*
* @instance
* @param {object} payload
*/
onChangeFailure: function alfresco_renderers_PublishingDropDownMenu__onChangeFailure(payload) {
this.alfUnsubscribeSaveHandles([this._updateSuccessHandle,this._updateFailureHandle, this._updateCancelHandle]);
domClass.add(this.processingNode, "hidden");
domClass.remove(this.warningNode, "hidden");
this.alfLog("log", "Update request failed", payload);
// Reset the value on failure...
this._resetInProgress = true;
this._dropDownWidget.setValue(this.value);
this._resetInProgress = false;
this._reponsePending = false;
},
/**
* This function is called whenever the request to update the value is cancelled. It hides the processing image
* and doesn't display anything else.
*
*/
onChangeCancel: function alfresco_renderers_PublishingDropDownMenu__onChangeCancel(payload) {
this.alfUnsubscribeSaveHandles([this._updateSuccessHandle, this._updateFailureHandle, this._updateCancelHandle]);
domClass.add(this.processingNode, "hidden");
this.alfLog("log", "Update request cancelled", payload);
// Reset the value on cancellation...
this._resetInProgress = true;
this._dropDownWidget.setValue(this.value);
this._resetInProgress = false;
this._reponsePending = false;
}
});
});