Customise "Send for approval" button for page edit

Posted by sfdev on 20-Jul-2019 08:11

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.

All Replies

Posted by sfdev on 23-Jul-2019 01:16

Anyone?

Posted by sfdev on 30-Jul-2019 07:26

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.

Posted by tsaneva on 30-Jul-2019 09:01

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?

Posted by sfdev on 30-Jul-2019 14:02

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?

Posted by jread on 30-Jul-2019 15:36

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

Posted by sfdev on 31-Jul-2019 05:25

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.

Posted by jread on 31-Jul-2019 11:32

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

Posted by sfdev on 01-Aug-2019 03:41

Hi jread, I am using Version 10.2.x

Posted by jread on 08-Aug-2019 15:06

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);

This thread is closed