4

I need to add a custom button in the pwa Ribbon of Project Online at the Approval Center. I need this using Jquery

4
+50

In order to add a button, you need to run C# CSOM code, but only once, just to add a button. Of course you can also do that in javascript, but since it's one time operation, may be it's more convenient to use C# code. Besides I will provide you both options.

C#, CSOM:

  1. Create console application, install Microsoft.SharePointOnline.CSOM nuget package.
  2. Add ribbon.xml file with below content:
<CommandUIExtension>
    <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Tasks.Controls._children">
            <Button Id="Ribbon.ContextualTabs.TaskUpdates.Home.Tasks.Greetings"
                                    Command="ShowHelloWorldCommand"
                                    Sequence="55"
                                    Alt="Show Greetings"
                                    Description="Show Greetings"
                                    LabelText="Show Greetings"
                                    ToolTipTitle="Show Greetings"
                                    ToolTipDescription="Show Greetings"
                                        Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"
                    Image32by32Top="-68"
                    Image32by32Left="-272"
                                    TemplateAlias="o1" />
        </CommandUIDefinition>
        <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Scaling._children">
            <MaxSize Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.MaxSize"
                             Sequence="55"
                             GroupId="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup"
                             Size="Large" />
        </CommandUIDefinition>
        <CommandUIDefinition Location="Ribbon.Templates._children">
            <GroupTemplate Id="Custom.Templates">
                <Layout Title="Large">
                    <Section Type="OneRow">
                        <Row>
                            <ControlRef TemplateAlias="c1" DisplayMode="Large" />
                        </Row>
                    </Section>
                </Layout>
            </GroupTemplate>
        </CommandUIDefinition>
        <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Groups._children">
            <Group Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup"
                         Sequence="19"
                         Description="Custom Group Description"
                         Title="Custom Group"
                         Template="Custom.Templates">
                <Controls Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.Controls">
                    <Button Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.Greetings"
                                    Command="ShowHelloWorldCommand"
                                    Sequence="55"
                                    Alt="Show Greetings"
                                    Description="Show Greetings"
                                    LabelText="Show Greetings"
                                    ToolTipTitle="Show Greetings"
                                    ToolTipDescription="Show Greetings"
                                     Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"
                    Image32by32Top="-68"
                    Image32by32Left="-272"
                                    TemplateAlias="c1" />
                </Controls>
            </Group>
        </CommandUIDefinition>
    </CommandUIDefinitions>
    <CommandUIHandlers>
        <CommandUIHandler
         Command="ShowHelloWorldCommand"
         EnabledScript="return true;"
         CommandAction="javascript:MyApp.greetings()" />
    </CommandUIHandlers>
</CommandUIExtension>

ribbon.xml contains two custom button definitions - one in custom separate group, the other one in default group.
Here is how it looks like in UI:

enter image description here

  1. Put below code into your console app:
var actionName = "Project.Ribbon.Approval.MyButton";

var passWord = new SecureString();
foreach (char c in "your_password") passWord.AppendChar(c);

var creds = new SharePointOnlineCredentials("your_user", passWord);

var clientContext = new ClientContext("https://your_tenant.sharepoint.com/sites/pwa/");
clientContext.Credentials = creds;

clientContext.Load(clientContext.Web, web => web.UserCustomActions);
clientContext.ExecuteQuery();

var customAction = clientContext.Web.UserCustomActions.FirstOrDefault(uca => uca.Name == actionName);

//if exists just delete and replace with new version
if (customAction != null)
{
    customAction.DeleteObject();
    clientContext.ExecuteQuery();
}

customAction = clientContext.Web.UserCustomActions.Add();
customAction.Name = actionName;
customAction.Location = "CommandUI.Ribbon";
customAction.CommandUIExtension = System.IO.File.ReadAllText("ribbon.xml"); ; // CommandUIExtension xml
customAction.RegistrationType = UserCustomActionRegistrationType.None;
customAction.Sequence = 1000;

customAction.Update();
clientContext.Load(customAction);
clientContext.ExecuteQuery(); 
  1. Go to approval center, sites/pwa/Approvals.aspx, edit page and add script editor web part. Put the following code inside:
var MyApp = MyApp || {};
MyApp.greetings = function(){
 alert('Hello!');
} 
  1. Click on custom button and you will see the alert.

As promised, javascript (JSOM) version:

var xml = '<CommandUIExtension> <CommandUIDefinitions>      <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Tasks.Controls._children">            <Button Id="Ribbon.ContextualTabs.TaskUpdates.Home.Tasks.Greetings"                                 Command="ShowHelloWorldCommand"                                 Sequence="55"                                   Alt="Show Greetings"                                    Description="Show Greetings"                                    LabelText="Show Greetings"                                  ToolTipTitle="Show Greetings"                                   ToolTipDescription="Show Greetings"                                     Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"                    Image32by32Top="-68"                    Image32by32Left="-272"                                 TemplateAlias="o1" />       </CommandUIDefinition>      <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Scaling._children">           <MaxSize Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.MaxSize"                           Sequence="55"                           GroupId="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup"                          Size="Large" />        </CommandUIDefinition>      <CommandUIDefinition Location="Ribbon.Templates._children">         <GroupTemplate Id="Custom.Templates">               <Layout Title="Large">                  <Section Type="OneRow">                     <Row>                           <ControlRef TemplateAlias="c1" DisplayMode="Large" />                       </Row>                  </Section>              </Layout>           </GroupTemplate>        </CommandUIDefinition>      <CommandUIDefinition Location="Ribbon.ContextualTabs.TaskUpdates.Home.Groups._children">            <Group Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup"                         Sequence="19"                       Description="Custom Group Description"                      Title="Custom Group"                        Template="Custom.Templates">               <Controls Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.Controls">                   <Button Id="Ribbon.ContextualTabs.TaskUpdates.Home.CustomActionGroup.Greetings"                                 Command="ShowHelloWorldCommand"                                 Sequence="55"                                   Alt="Show Greetings"                                    Description="Show Greetings"                                    LabelText="Show Greetings"                                  ToolTipTitle="Show Greetings"                                   ToolTipDescription="Show Greetings"                                  Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"                    Image32by32Top="-68"                    Image32by32Left="-272"                                    TemplateAlias="c1" />               </Controls>         </Group>        </CommandUIDefinition>  </CommandUIDefinitions> <CommandUIHandlers>     <CommandUIHandler        Command="ShowHelloWorldCommand"         EnabledScript="return true;"        CommandAction="javascript:MyApp.greetings()" />    </CommandUIHandlers></CommandUIExtension>';

SP.SOD.executeOrDelayUntilScriptLoaded(function(){
    var clientContext = SP.ClientContext.get_current(); 
    var web = clientContext.get_web(); 
    var userActions = web.get_userCustomActions();
    clientContext.load(userActions);
    clientContext.executeQueryAsync(function(){
        var actions = userActions.getEnumerator();
        while(actions.moveNext()){
            var action = actions.get_current();

            if(action.get_name() === 'Project.Ribbon.Approval.MyButton'){
                //or skip removal and just return, if button exists
                action.deleteObject();
                clientContext.executeQueryAsync(function(){
                    addButton(clientContext, userActions);
                }, function(err){
                    alert(err);
                });
                return;
            }
        }

        addButton(clientContext, userActions);

    }, function(err){
        alert(err);
    });
}, 'sp.js');

function addButton(clientContext, userActions){
    var newUserCustomAction = userActions.add(); 
    newUserCustomAction.set_location('CommandUI.Ribbon'); 
    newUserCustomAction.set_commandUIExtension(xml);
    newUserCustomAction.set_sequence(100); 
    newUserCustomAction.set_name('Project.Ribbon.Approval.MyButton'); 
    newUserCustomAction.update();

    clientContext.executeQueryAsync(function(){
        alert('Action added!');
    }, function(err){
        alert(err);
    });
} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.