sharepointoffice365sharepoint-onlinesharepoint-addin

Can Custom Action Buttons run javascript in handler? Sharepoint add-in


I created a Custom Action Ribbon button for sharepoint online and i want to run a javascript code when the button is clicked.

Sharepoint documentation even provides an example of it: https://learn.microsoft.com/en-us/sharepoint/dev/schema/commanduihandler-element?redirectedfrom=MSDN#example

but when i'm trying it always returns an error Custom action urls must start with "http:", "https:", "~appWebUrl" or "~remoteAppUrl".

Another part of the documentation says that it is not possible https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/sharepoint-add-ins-ux-design-guidelines?redirectedfrom=MSDN#figure-4-a-custom-action-in-the-contextual-menu

So how do i make it work? is not possible anymore and only can do redirections? or it deppends of the location? i have it defined as <CommandUIDefinition Location="Ribbon.Documents.Actions.Controls._children"> so it is displayed in the command bar.


Solution

  • is it possible? ... I suppose no

    Unfortunately it is not possible to add a custom ribbon action with a javascript logic with a provider hosted add-in πŸ€”. I think the articles/links where you found it is possible refer to the Server ribbon xml custom action that could be modified using sandbox solutions (like the old school SharePoint days 😊), but now the sandbox is rather not supported in SP online.

    For the Ribbon custom actions that are added with the add-in you should specify the direct link. This is already what needs to be specified when we add a Ribbon action in VS to the Add-in project (we should specify were we navigate to) enter image description here

    I also found this MSDN article (quite up to date - from 2020) where we may find:

    CustomAction cannot contain JavaScript: Any UrlActions or CommandActions must be a URL to navigate to. (...)

    So I am like 95% sure it should πŸ˜‰ not be possible... but I leave the 5% as I am not like an SP PRO (I think it is hard to be one as it is like sooooo much to know πŸ˜‹)

    possible solution you might take

    What you might do is to add the custom Ribbion xml using PowerShell and attach any javascript logic to it also using PowerShell πŸ˜‹. The only drawback is that the javascript file needs to be also somehow added to the page (like it could be stored in the SiteAssets library).

    So to do that we need to:

    1. create an xml file locally with our Ribbon command button like:
    <CommandUIExtension>
        <CommandUIDefinitions>
            <CommandUIDefinition Location="Ribbon.Library.ViewFormat.Controls._children">
                <Button Id="Ribbon.Library.ViewFormat.About"
                    Command="TestButton"
                    LabelText="Test"
                    Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"
                    Image32by32Top="-273"
                    Image32by32Left="-1"
                    Description="Test"
                    TemplateAlias="o1" />
            </CommandUIDefinition>
        </CommandUIDefinitions>
        <CommandUIHandlers>
            <CommandUIHandler
                Command="TestButton"
                CommandAction="javascript:test({SelectedItemId});"
                EnabledScript="javascript:checkOneItemSelected();" />
        </CommandUIHandlers>
    </CommandUIExtension>
    

    the output of the above will be a button like this

    enter image description here

    1. Next create a js file (also locally) with functions for the CommandAction and EnabledScript (so we need a test() function and checkOneItemSelected()). So the contents like
    function test(itemId) {
        alert(itemId);
    }
    
    function checkOneItemSelected() {
        return (SP.ListOperation.Selection.getSelectedItems().length == 1)
    }
    

    ... so locally I have two files

    enter image description here

    1. Now we need to connect to the site we want to add the Ribbon button using PowerShell (best would be to use PnP Powershell πŸ‘)

    so the output is (the file in the library)

    enter image description here

    $ribbon = Get-Content .\CustomRibbonButton.xml
    $ribbon = [string]$ribbon
    Add-PnPCustomAction -Name "RibbonTester" -Title "RibbonTester" -Description "-" -Group "Tester" -Location "CommandUI.Ribbon" -CommandUIExtension $ribbon -RegistrationType ContentType -RegistrationId 0x0101
    

    so the output of the above will be our button in the ribbon (also we need to turn on classic UI /off modern UI, to see the ribbon πŸ˜‰)

    enter image description here

    and the output is like

    enter image description here

    did you considerπŸ€”

    Also did you consider to use spfx extensions and modern UI to be more up to date? In extensions you may use JS and maybe do some http request to some endpoint you want to target with the ids array (but this is only a suggestion)

    hope my post will be of any help πŸ‘ BR