Showing posts with label Custom Action. Show all posts
Showing posts with label Custom Action. Show all posts

October 19, 2016

How to create Custom action to deploy with Sharepoint Add-ins(Apps)

There are two basic types of SharePoint Apps/Add-ins: SharePoint Hosted and Provider Hosted. Here, I will show how we can create custom action in host web document library through SharePoint Add-ins and open a model popup on click. Follow below steps:

Step 1:
Open your SharePoint App project in Visual Studio Solution. Add New Item, select Ribbon Custom action and give it name and click on Add.


Step 2:
Now in second dialog box, we have to set properties for custom action. In Dialog box. Select appropriate option based on requirement. Here, I have selected custom action scope to "List Template" and custom action scope location set to "Document Library" and click on Next.

You can select any type like Custom List, Calendar, Form Library etc.


Step 3:
Now in third dialog box, we have to specify the settings to generate a button control for ribbon. Here, I have selected "Ribbon.Documents.EditCheckout" as control location (Ribbon group where you would like to put the Control), "Demo Modal" as button control text (Name of your Control), and provide default page URL where button control navigates. Click on Finish. Now, custom action is created.


Step 4: 
Open Elements.xml file and add following attributes in <CustomAction> tag.

                HostWebDialog="TRUE"
                HostWebDialogWidth="600"
                HostWebDialogHeight="400" 


Your Elements.xml file looks like below

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="26a48039-5fc9-45fc-aabb-287b3ccedd3f.Demo_Modal"
                RegistrationType="List"
                RegistrationId="101"
                Location="CommandUI.Ribbon"
                Sequence="10001"
                HostWebDialog="TRUE"
                HostWebDialogWidth="600"
                HostWebDialogHeight="400"
                Title="Demo Modal">
    <CommandUIExtension>      
      <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.Documents.EditCheckout.Controls._children">
          <Button Id="Ribbon.Documents.EditCheckout.Demo_ModalButton"
                  Alt="Demo_Modal"
                  Sequence="100"
                  Command="Invoke_Demo_ModalButtonRequest"
                  LabelText="Demo_Modal"
                  TemplateAlias="o1"
                  Image32by32="_layouts/15/images/placeholder32x32.png"
                  Image16by16="_layouts/15/images/placeholder16x16.png" />
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler 
          Command="Invoke_Demo_ModalButtonRequest"
          CommandAction="~appWebUrl/Pages/Default.aspx?{StandardTokens}&amp;
          SPListItemId={SelectedItemId}&amp;SPListId={SelectedListId}&amp;SPListURLDir=      {ListUrlDir}&amp;SPSource={Source}"/>
      </CommandUIHandlers>
    </CommandUIExtension >
  </CustomAction>
</Elements>

Step 5:
Now open navigation page (App Page - default.aspx) of custom action and add below code:
<WebPartPages:AllowFraming ID="AllowFraming" runat="server"/>

All done! 
 
Now, we can deploy app in SharePoint and custom action will be created. It will open Modal Popup on click of "Demo_Modal".
 
Deployed app will looks like above Image. This is a great way to extend functionality of SharePoint.

If you have any questions you can reach out our SharePoint Consulting team here.

September 8, 2016

Injecting Javascript file through SharePoint Hosted App

A requirement came across was to execute a JavaScript on all the pages of SharePoint Site. Here, option of achieving the functionality by developing custom master page was eliminated as we were dealing with a SharePoint Hosted App. It is also easy to achieve through server side but need to find solution on client side as SharePoint Hosted App has everything on client side. Finally, we found a solution to inject the JavaScript using Custom Action.

JavaScript Object Model (JSOM) allows us to programmatically register Custom Action with Host Web in a way similar to declarative approach used with Farm or Sandboxed Solution. In order to register a Custom Action using JSOM, your app requires the Full Control permission on the Site/Site Collection where you want to register it.

To achieve this, we need to perform two steps as below:
  1. Provisioning the JavaScript file from App web to Host web
  2. Registering the Custom action with the file path referring to that JavaScript file in the Host web.

1. Provisioning the JavaScript file from app web to host web:

function uploadFileToHostWebViaCSOM(serverRelativeUrl, filename, contents) {      
        var executor = new SP.RequestExecutor(window.appWebUrl);
        executor.executeAsync(
                {
                    url: window.appWebUrl + "/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + serverRelativeUrl + "')/Files?@target='" + window.hostWebUrl + "'",
                    method: "GET",
                    headers: { "Accept": "application/json; odata=verbose" },
                    success: function (data) {
                        var jsonObject = JSON.parse(data.body);
                        var createInfo = new SP.FileCreationInformation();
                        createInfo.set_content(new SP.Base64EncodedByteArray());
                        for (var i = 0; i < contents.length; i++) {
                            createInfo.get_content().append(contents.charCodeAt(i));
                        }
                       createInfo.set_url(filename);
                       createInfo.set_overwrite(true);
                       var files = hostWebContext.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();
                       var isexist = false;
                        jsonObject.d.results.forEach(function (item, index) {
                            if (item.Name == filename)
                                isexist = true;
                        });
                        if (isexist)
                            files.getByUrl(filename).checkOut();
                        var file = files.add(createInfo);
                        file.checkIn('Add-in deployment.');
                        file.publish('Add-in deployment.');

                        appWebContext.load(file);
                        appWebContext.executeQueryAsync(success, function (sender, args) {
                            alert(args.get_message());
                        });
                    },
                    error: function (data, errorCode, errorMessage) {
                        console.log("error");
                    }
                });
    };


Here, we are first fetching the file from app web and checking that whether it exists in host web or not. If the file exists then we will update the existing file, check in and publish it. If the file does not exist then we just add the file, check in and publish it.

2. Registering the custom action with the file path:

var context = web.get_context();
var webs = web.get_webs();
var actions = web.get_userCustomActions();
context.load(actions);
context.load(webs, 'Include(Title,Webs)');
context.executeQueryAsync(function () {

  var newAction = actions.add();
  // the 'description' is what we'll use to uniquely identify our custom action
  newAction.set_description(actionDescription);
  newAction.set_location('ScriptLink');
  newAction.set_scriptBlock(getScripts(window.hostWebUrl + '/Style Library/EasyNav/Scripts/tinysort.min.js'));
  newAction.set_sequence(1004);
  newAction.update();

  context.executeQueryAsync(function () { }, fail);
}, fail);

The above code adds a custom action on a web object in Host web. Wherein,
set_location specifies it is a script registration action,
set_scriptBlock indicates the JavaScript file's path in host web,
set_sequence specifies the sequence in which the files are to be loaded if there is more than one.

Once above code will be executed through custom action, we can see all JavaScript files loaded on all the pages of the SharePoint Site.

If you have any questions you can reach out our SharePoint Consulting team here.