Customise "Send for approval" button for page edit mode - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Customise "Send for approval" button for page edit mode

  • Hi,

    I would like to add a new button or modify the "Send for approval" button so user could select specific email of approver for a workflow, instead of the sending to all the approvers of the same roles.

    However, I couldn't seem to find the page backend view template (ascx) that I can override with viewmap. Please advice.

    Thanks.

  • Anyone?

  • I managed to add a button beside "Send for approval" by overriding the workflow, but I'm not sure where to place the script so I could call my ajax script when the button is clicked.

  • Hello, sfdev, what is the use case here? As far as I understand, you would like to dynamically select approvers for each item, right? How many approvers do you have? What are the specific scenarios?

  • The scenario will be something like:

    1. Press on Send for Approval button or my custom button (if default button can't be removed)

    2. Run AJAX script to grab a list of approvers (maybe 10?) from a service so users could select their approvers

    3. Post the selected users back to the workflow

    I can't figure out where to inject the AJAX script and posting data back to the workflow. Is this scenario feasible?

  • It seems like to me that doing this would kind of defeats the reason for using the workflow, if you configure it to use a Role instead of individuals users then they all get the email and then whom ever is available will approve the content.   Here is a way to assign workflows based on user Role in Sitefinity.  I believe this would be the best starting point for your extension into the system.

    https://www.progress.com/documentation/sitefinity-cms/tutorial-customize-workflow-definitions

  • Understand and appreciate your perspective, I've read that documentation before as well. But is my scenario doable? I just need someone to point me the right place for script injection.

  • Which version of Sitefinity are you using? There is a large difference between 11.x & 12.x for page editing.

  • Hi jread, I am using Version 10.2.x

  • You will need to register you clientside script to attach to the load event of the page editor.  The belowJS file is what Siteifnity uses to attached to the 'page load' OnDetailViewLoaded().  Once that script loads and attaches you should be able to modify the UI behavior

    // called by the DetailFormView when it is loaded
    function OnDetailViewLoaded(sender, args) {
        // the sender here is DetailFormView
        var currentForm = sender;
        Sys.Application.add_init(function () {
                                     $create(Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension,
                                             { _detailFormView: currentForm },
                                             {},
                                             {},
                                             null);
                                 });
    }
    
    Type.registerNamespace("Telerik.Sitefinity.Modules.Pages.Web.UI");
    
    Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension = function () {
        Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension.initializeBase(this);
        this._detailFormView = {};
        this._binder = null;
        this._emptyGuid = "00000000-0000-0000-0000-000000000000";
    
        this._dataItem = null;
        this._translationSyncedWarningDialog = null;
    
        this._onDataBindDelegate = null;
        this._formCreatedDelegate = null;
        this._formClosingDelegate = null;
        this._continueToEditPageDelegate = null;
        this._copyLanguageChangedDelegate = null;
        this._isNewLanguageVersion = false;
    }
    
    Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension.prototype = {
        initialize: function () {
            Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension.callBaseMethod(this, "initialize");
    
            this._binder = this._detailFormView.get_binder();
    
            if (this._detailFormView) {
                this._formCreatedDelegate = Function.createDelegate(this, this._formCreatedHandler);
                this._detailFormView.add_formCreated(this._formCreatedDelegate);
    
                this._formClosingDelegate = Function.createDelegate(this, this._formClosingHandler);
                this._detailFormView.add_formClosing(this._formClosingDelegate);
    
                this._translationSyncedWarningDialog = this._detailFormView.getPromptDialogByName("translationSyncedWarningDialog");
            }
        },
    
        dispose: function () {
            if (this._onDataBindDelegate) {
                if (this._detailFormView) {
                    this._detailFormView.remove_onDataBind(this._onDataBindDelegate);
                }
                delete this._onDataBindDelegate;
            }
    
            if (this._formCreatedDelegate) {
                if (this._detailFormView) {
                    this._detailFormView.remove_formCreated(this._formCreatedDelegate);
                }
                delete this._formCreatedDelegate;
            }
    
            if (this._formClosingDelegate) {
                if (this._detailFormView) {
                    this._detailFormView.remove_formCreated(this._formClosingDelegate);
                }
                delete this._formClosingDelegate;
            }
    
            if (this._continueToEditPageDelegate) {
                delete this._continueToEditPageDelegate;
            }
    
            Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension.callBaseMethod(this, "dispose");
        },
    
        _formCreatedHandler: function (sender, args) {
            var dataItem = this._binder.get_dataItem();
            this._dataItem = dataItem;
            var detailFormView = this._detailFormView;
    
            //This is needed because the binder dataItem is sometimes changed after that (on dataBind) and we need to preserve the source object and language
            if (!this._onDataBindDelegate) {
                this._onDataBindDelegate = Function.createDelegate(this, this._onDataBindHandler);
                detailFormView.add_onDataBind(this._onDataBindDelegate);
            }
    
            var commandArgument = args.get_commandArgument();
            if (!args.get_isNew() && args.get_commandName() == "edit") {
                this._toggleSectionByName("CopyLanguageSection", true);
            }
            else {
                if (commandArgument && commandArgument.language && commandArgument.sourceObjectId != this._guidEmpty) {
                    dataItem.Language = commandArgument.language;
                    dataItem.SourceLanguagePageId = commandArgument.sourceObjectId;
    
                    var hideReturnToPages = commandArgument.isFromEditor;
    
                    this._binder.set_uiCulture(dataItem.Language);
    
                    this._toggleSectionByName("TemplateSection", true);
                    this._toggleSectionByName("CopyLanguageSection", false);
                    this._toggleWidgetByName("CreateAndReturnWidgetElement", hideReturnToPages);
                    this._isNewLanguageVersion = true;
    
                    var copyLanguageField = this._getFieldControlByDataFieldName("AvailableLanguages");
                    dataItem.SourceLanguage = this._detailFormView._defaultLanguage;
                    copyLanguageField.set_selectedLanguage(this._detailFormView._defaultLanguage, false);
                    if (!this._copyLanguageChangedDelegate) {
                        this._copyLanguageChangedDelegate = Function.createDelegate(this, this._copyLanguageChanged);
                        copyLanguageField.add_valueChanged(this._copyLanguageChangedDelegate);
                    }
                }
                else {
                    this._toggleSectionByName("TemplateSection", false);
                    this._toggleSectionByName("CopyLanguageSection", true);
    
                    if (args.get_commandName() == "duplicate") {
                        // Do not allow the user to change the framework on duplicate.
                        this._toggleFrameworkOptions(true);
                    }
                    //Set language for the template selector
                    if (commandArgument && commandArgument.language) {
                        var templateSelectorField = this._getFieldControlByDataFieldName("Template");
                        templateSelectorField.set_language(commandArgument.language);
                    }
                }
            }
        },
        _toggleFrameworkOptions: function (bDisable) {
            var frameworkField = this._getFieldControlByDataFieldName("Framework");
            if (frameworkField)
                jQuery("input", frameworkField.get_choiceElement()).prop('disabled', bDisable);
        },
        _copyLanguageChanged: function (elm) {
            this._binder.get_dataItem().SourceLanguage = elm.get_value();
        },
    
        _onDataBindHandler: function (sender, dataItem) {
            dataItem.Item.Language = this._dataItem.Language;
            dataItem.Item.SourceLanguagePageId = this._dataItem.SourceLanguagePageId;
    
            var copyLanguageField = this._getFieldControlByDataFieldName("AvailableLanguages");
            if (copyLanguageField) {
                dataItem.Item.SourceLanguage = this._detailFormView._defaultLanguage;
                copyLanguageField.set_selectedLanguage(this._detailFormView._defaultLanguage, false);
            }
        },
    
        _formClosingHandler: function (sender, args) {
            var form = sender;
            var commandArgument = args.get_commandArgument();
            var isNew = args.get_isNew();
    
            if (form.get_isMultilingual() && commandArgument) {
                isNew = commandArgument.languageMode == "create";
            }
    
            if (isNew && args.get_isDirty()) {
                var widgetCommandName = form.get_widgetCommandName();
    
                if (widgetCommandName == form.get_createCommandName() && this._isNewLanguageVersion == true) {
                    this._continueToEditPageDelegate = Function.createDelegate(this, this._continueToEditPage);
                    this._translationSyncedWarningDialog.show_prompt('', '', this._continueToEditPageDelegate, { dataItem: args.get_dataItem(), context: form });
    
                }
                else {
                    dialogBase.closeCreated(args.get_dataItem(), form);
                }
                args.set_cancel(true);
            }
        },
    
        _continueToEditPage: function (sender, args) {
            var dataItem = args.get_commandArgument().dataItem;
            var context = args.get_commandArgument().context;
            var cancelEdit = args.get_commandName() == 'cancel';
    
            if (cancelEdit) {
                dialogBase.closeCreated(dataItem, null);
            }
            else {
                dialogBase.closeCreated(dataItem, context);
            }
        },
    
        _getWidgetByName: function (name) {
            var widget;
            var widgetBarIdsCount = this._detailFormView.get_widgetBarIds().length;
            while (widgetBarIdsCount--) {
                var widgetBarId = this._detailFormView.get_widgetBarIds()[widgetBarIdsCount];
                var widgetBar = $find(widgetBarId);
                if (widgetBar) {
                    widget = widgetBar.getWidgetByName(name);
                    break;
                }
            }
            return widget;
        },
    
        _getFieldControlByDataFieldName: function (dataFieldName) {
            return this._binder.getFieldControlByDataFieldName(dataFieldName);
        },
    
        _toggleSectionByName: function (name, hide) {
            var sectionIds = this._detailFormView.get_sectionIds();
            var sectionCount = sectionIds.length;
    
            for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
                var sectionId = sectionIds[sectionIndex];
                var section = $find(sectionId);
                if (section.get_name() == name) {
                    var sectionElm = jQuery(section.get_element());
                    if (hide) {
                        sectionElm.hide();
                    }
                    else {
                        sectionElm.show();
                    }
                    break;
                }
            }
        },
    
        _toggleWidgetByName: function (name, hide) {
            var widget = this._getWidgetByName(name);
    
            if (widget) {
                if (hide) {
                    jQuery(widget.get_element()).hide();
                }
                else {
                    jQuery(widget.get_element()).show();
                }
            }
        }
    }
    
    Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension.registerClass("Telerik.Sitefinity.Modules.Pages.Web.UI.DetailFormViewExtension", Sys.Component, Sys.IDisposable);