Tuesday, December 15, 2015

Part II: Examples of Ribbons Customization in SharePoint 2013


Yes i am alive and still blogging.... My current work blocked a lot of my time and wasn't  SharePoint related.... yep, Management is blood sucker for development skills...
But is Christmas time and i want to make something nice for you SharePoint readers for that i reviewed my analytic charts to see what people people requested in my blog and saw that Ribbon Customization was one of the top, the other other main one is "how to add links in document library"....
I know is important and people really struggle with this topic, even today, but let's be serious i don't want to make a part 2 of "how to add links in document library" unless i create some scenario, maybe can be a topic for another article.

As talked and making a follow up of my extensive article regarding about,
Examples of Ribbons Customization in SharePoint 2013
http://aaclage.blogspot.ch/2014/04/examples-of-customization-of-ribbons-in.html

I would like to provide some new common Ribbons Action examples that people requested and can be used in a daily base:

  • Manage List/Library Visibility  in Site Content
  • Display in Modal dialog Hidden Lists/Libraries
  • Hidden  Document/Folder in Explorer Viewer
  • Delete all Items to Recycle Bin

Here are my compilation of useful Ribbon Actions and XML structure made in my blog:
Add Custom Ribbon Button in Site Page to Popup all SharePoint Apps
http://aaclage.blogspot.ch/2015/03/add-custom-ribbon-button-in-site-page.html
How to create Custom Ribbon Button to Move Documents in Library with Metadata/versions
http://aaclage.blogspot.ch/2014/07/how-to-create-custom-ribbon-button-to.html
OneNote Custom Actions to support Create/Move Pages and Sections and conversion to Folder in SharePoint
http://aaclage.blogspot.ch/2014/07/onenote-custom-actions-to-support.html

All this Ribbons were made using the following tool "Processlynx Ribbon Manager"
http://aaclage.blogspot.ch/2014/06/sharepoint-app-processlynx-custom.html

Manage List/Library Visibility 

This Custom Ribbon Action Manage the visibility of current List using the JSOM object SP.List.hidden, the site owner can hide or enable the List in the site Content using this Object.

SP.List.hidden property (sp.js)

For this example i create a custom Action in the Document Library "Documents" where is accessible by Site Content.

The new Ribbon option appears in the Ribbon.Library.Settings area as FlyoutAnchor.


After the option is selected the Document Library don't appear in the Site Content.
The Library "Documents" is hidden from Site Content
The Ribbon Manager provides a user experience for the XML complexity associated with the creation of the Ribbon.
Processlynx Ribbon Manager XML visualization
For the XML structure of the Ribbon Configuration you can use the following:
<CommandUIExtension xmlns=\"http://schemas.microsoft.com/sharepoint/\">\n<CommandUIDefinitions>\n<CommandUIDefinition Location=\"Ribbon.Library.Settings.Controls._children\">\n<FlyoutAnchor Id=\"Manage.Visibility.List\" LabelText=\"Manage Visibility List\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-34\" Image32by32Top=\"-443\" ToolTipTitle=\"Manage Visibility List\" Command=\"Manage.Visibility.List.Command\" TemplateAlias=\"o1\">\n<Menu Id=\"Manage.Visibility.List.Menu\">\n<MenuSection Id=\"Manage.Visibility.List\" DisplayMode=\"Menu32\">\n<Controls Id=\"Manage.Visibility.List.Controls\">\n<Button Id=\"Enable.List.Visibility\" LabelText=\"Enable List\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-171\" Image32by32Top=\"-69\" ToolTipTitle=\"Enable List\" Command=\"Enable.List.Visibility.Command\" TemplateAlias=\"o1\" />\n<Button Id=\"Disable.Visibility.List\" LabelText=\"Hide List\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-169\" Image32by32Top=\"-69\" ToolTipTitle=\"Hide List\" Command=\"Disable.Visibility.List.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</MenuSection>\n</Menu>\n</FlyoutAnchor>\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"Manage.Visibility.List.Command\" CommandAction=\"\" />\n<CommandUIHandler Command=\"Enable.List.Visibility.Command\" CommandAction=\"<Code>" />\n<CommandUIHandler Command=\"Disable.Visibility.List.Command\" CommandAction=\"<Code>" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code

This JavaScript code manage the Hidden property List Object with true or false to List became visible in the Site Content.

Enable visibility List in site Content:
Action:
javascript:
function HideList(Listid) {
    Listid = Listid.replace("{", "");
    Listid = Listid.replace("}", "");
    var clientContext = new SP.ClientContext.get_current();
    var oWebsite = clientContext.get_web();
    targetList = oWebsite.get_lists().getById(Listid);
    targetList.set_hidden(false);
    targetList.update();
    clientContext.load(targetList);
    clientContext.executeQueryAsync(function(){
        var listInfo = '';
        SP.UI.Notify.addNotification('Hidden: ' + targetList.get_hidden(), false);
         SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
        }, Function.createDelegate(this, this.onQueryFailed));
}
function onQueryFailed(sender, args) {
                alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            }
HideList('{ListId}');

Hide visibility List in Site Content 
Action:
javascript:
function HideList(Listid) {
    Listid = Listid.replace("{", "");
    Listid = Listid.replace("}", "");
    var clientContext = new SP.ClientContext.get_current();
    var oWebsite = clientContext.get_web();
    targetList = oWebsite.get_lists().getById(Listid);
    targetList.set_hidden(true);
    targetList.update();
    clientContext.load(targetList);
    clientContext.executeQueryAsync(function(){
        var listInfo = '';
        SP.UI.Notify.addNotification('Hidden: ' + targetList.get_hidden(), false);
         SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
        }, Function.createDelegate(this, this.onQueryFailed));
}
function onQueryFailed(sender, args) {
                alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
            }
HideList('{ListId}');

Display in Modal dialog Hidden Lists/Libraries

This Custom Ribbon Action displays all Hidden Lists from the Web Site, for this example i used one old article but made different filter to retrieve all Lists with the JSOM SP.List.hidden property.


SP.List.hidden property (sp.js)

Add Custom Ribbon Button in Site Page to Popup all SharePoint Apps
http://aaclage.blogspot.ch/2015/03/add-custom-ribbon-button-in-site-page.html

For this example a new Ribbon was created in the Ribbon.WikiPageTab Area to list all Hidden Lists.


After selection of the Ribbon option the Modal Dialog appears with the Hidden Lists/Libraries:


The Ribbon Manager provides a user experience for the XML complexity associated with the creation of the Ribbon.


For the XML structure of the Ribbon Configuration you can use the following:
<CommandUIDefinitions>\n<CommandUIDefinition Location=\"Ribbon.WikiPageTab.Groups._children\">\n<Group Id=\"List.Hidden\" Title=\"List Hidden Lists\" Description=\"List Hidden Lists\" Template=\"Ribbon.Templates.Flexible2\">\n<Controls Id=\"List.Hidden.Controls\">\n<Button Id=\"List.Hidden\" LabelText=\"List Hidden Lists\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-168\" Image32by32Top=\"-69\" ToolTipTitle=\"List Hidden Lists\" Command=\"List.Hidden.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</Group>\n</CommandUIDefinition>\n<CommandUIDefinition Location=\"Ribbon.WikiPageTab.Scaling._children\">\n<MaxSize Id=\"List.Hidden.Scaling.MaxSize\" GroupId=\"List.Hidden\" Size=\"LargeLarge\" />\n</CommandUIDefinition>\n<CommandUIDefinition Location=\"Ribbon.Templates._children\"><GroupTemplate Id=\"Ribbon.Templates.Flexible2\"><Layout Title=\"LargeLarge\" LayoutTitle=\"LargeLarge\"><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o1\" Type=\"OneRow\" /><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o2\" Type=\"OneRow\" /></Layout><Layout Title=\"LargeMedium\" LayoutTitle=\"LargeMedium\"><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o1\" Type=\"OneRow\" /><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout><Layout Title=\"LargeSmall\" LayoutTitle=\"LargeSmall\"><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o1\" Type=\"OneRow\" /><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout><Layout Title=\"MediumLarge\" LayoutTitle=\"MediumLarge\"><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o2\" Type=\"OneRow\" /></Layout><Layout Title=\"MediumMedium\" LayoutTitle=\"MediumMedium\"><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout><Layout Title=\"MediumSmall\" LayoutTitle=\"MediumSmall\"><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout><Layout Title=\"SmallLarge\" LayoutTitle=\"SmallLarge\"><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Large\" TemplateAlias=\"o2\" Type=\"OneRow\" /></Layout><Layout Title=\"SmallMedium\" LayoutTitle=\"SmallMedium\"><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Medium\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout><Layout Title=\"SmallSmall\" LayoutTitle=\"SmallSmall\"><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o1\" Type=\"ThreeRow\" /><OverflowSection DisplayMode=\"Small\" TemplateAlias=\"o2\" Type=\"ThreeRow\" /></Layout></GroupTemplate></CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"List.Hidden.Command\" CommandAction=\"<Code>" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code

This JavaScript code Get all Lists from the SharePoint Web Object and filter by property (Hidden== true) to get the one not visible by the Site content and displays in the Modal Dialog.
For the  retrieving of the Url List i extend the RootFolder Object to get the property serverRelativeUrl.

SP.List.rootFolder property (sp.js)
https://msdn.microsoft.com/en-us/library/office/jj245992.aspx

Action:
javascript:

function GetHiddenLists() {
    var ctx = new SP.ClientContext.get_current();
    var web = ctx.get_web();
    var lists = web.get_lists();
    ctx.load(lists, 'Include(Title,Hidden,ImageUrl,RootFolder)');
    ctx.executeQueryAsync(
        function () {
        var listEnumerator = lists.getEnumerator();
        var listInfo = '';
        while (listEnumerator.moveNext()) {
            var oList = listEnumerator.get_current();
            var rootFolder = oList.get_rootFolder();
        if (oList.get_hidden() == true)
        {
            listInfo +='<div><img src=\''+ oList.get_imageUrl() +'\' ><a href=\'' +rootFolder.get_serverRelativeUrl() + '\'>' + oList.get_title() + '</a></div>';
        }
 }
    DialogApps(listInfo);
}
,
        function (sender, args) {
            alert('failed to get list. Error:' + args.get_message());
        });

    return false;
}
function DialogApps(stringHtml) {
            var element = document.createElement('div');
            element.innerHTML = stringHtml;
            SP.UI.ModalDialog.showModalDialog({
                html: element,
                title: "Hidden Lists/Libraries",
                allowMaximize: false,
                showClose: true,
                autoSize: true
            });

        }
GetHiddenLists();

Enable/Disable Folder in Explorer Viewer 

This Custom Ribbon Action Manage the visibility of items when the option Explorer Viewer is selected, this Action Manage item Propertybag [vti_winfileattribs] to manage the visibility.

Hide/Show Underscore (_) Folders in Explorer Viewer using (JSOM/REST) in LisItem PropertyBags
http://aaclage.blogspot.ch/2014/05/hideshow-underscore-folders-in-explorer.html

The new Ribbon option appears in the Ribbon.Documents.Manage area as FlyoutAnchor where the Ribbon actions manage the visibility of the item in the Explorer Viewer option.
The following images appear after the Propertybag option of the item is changed with the visibility of the selected Folder.


The Ribbon Manager provides a user experience for the XML complexity associated with the creation of the Ribbon.

For the XML structure of the Ribbon Configuration you can use the following:
<CommandUIExtension xmlns=\"http://schemas.microsoft.com/sharepoint/\">\n<CommandUIDefinitions>\n<CommandUIDefinition Location=\"Ribbon.Documents.Manage.Controls._children\">\n<FlyoutAnchor Id=\"Manage.ExplorerViewer\" LabelText=\"Manage Explorer Viewer\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-204\" Image32by32Top=\"-307\" ToolTipTitle=\"Manage Explorer Viewer\" Command=\"Manage.ExplorerViewer.Command\" TemplateAlias=\"o1\">\n<Menu Id=\"Manage.ExplorerViewer.Menu\">\n<MenuSection Id=\"Mamage.ExplorerViewer\" DisplayMode=\"Menu32\">\n<Controls Id=\"Mamage.ExplorerViewer.Controls\">\n<Button Id=\"Hidden.ExplorerViewer\" LabelText=\"Hidden Explorer Viewer Folder\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-169\" Image32by32Top=\"-69\" ToolTipTitle=\"Hidden Explorer Viewer Folder\" Command=\"Hidden.ExplorerViewer.Command\" TemplateAlias=\"o1\" />\n<Button Id=\"Enable.ExplorerViewer\" LabelText=\"Enable Explorer Viewer Folder\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-169\" Image32by32Top=\"-101\" ToolTipTitle=\"Enable Explorer Viewer Folder\" Command=\"Enable.ExplorerViewer.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</MenuSection>\n</Menu>\n</FlyoutAnchor>\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"Manage.ExplorerViewer.Command\" CommandAction=\"\" EnabledScript=\"<Code>" />\n<CommandUIHandler Command=\"Hidden.ExplorerViewer.Command\" CommandAction=\"<Code>\" />\n<CommandUIHandler Command=\"Enable.ExplorerViewer.Command\" CommandAction=\"<Code>" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code

This JavaScript code updates the MetaInfo info Column of the ListItem with the Property Bag "vti_winfileattribs:SW|00000016" or "vti_winfileattribs:SW|null" to enable or disable the document in the Explorer Viewer option.
PS:The code can be improved using the propertyBag[vti_winfileattribs] code of the item.

Disable item in Explorer Viewer
Action:
javascript:
function updateListItem(Listid) {
    Listid = Listid.replace("{", "");
    Listid = Listid.replace("}", "");
    var values = SP.ListOperation.Selection.getSelectedItems();
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getById(Listid);
    this.oListItem = oList.getItemById(values[0].id); 
    oListItem.set_item('MetaInfo', 'vti_winfileattribs:SW|00000016');
    oListItem.update();
    clientContext.executeQueryAsync(function(){
    SP.UI.Notify.addNotification("Folder hidden from Explorer Viewer.", false);
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
       
    }, Function.createDelegate(this, this.onQueryFailed));
}

function onQueryFailed(sender, args) {
    SP.UI.Notify.addNotification('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace(), false);
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
updateListItem('{ListId}');


Enable item in Explorer Viewer
Action:
javascript:
function updateListItem(Listid) {
    Listid = Listid.replace("{", "");
    Listid = Listid.replace("}", "");
    var values = SP.ListOperation.Selection.getSelectedItems();
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getById(Listid);
    this.oListItem = oList.getItemById(values[0].id); 
    oListItem.set_item('MetaInfo', 'vti_winfileattribs:SW|null');
    oListItem.update();
    clientContext.executeQueryAsync(function(){
    SP.UI.Notify.addNotification("Folder visible from Explorer Viewer.", false);
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
       
    }, Function.createDelegate(this, this.onQueryFailed));
}

function onQueryFailed(sender, args) {
    SP.UI.Notify.addNotification('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace(), false);
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
updateListItem('{ListId}');

Delete all Items toRecycle Bin

This Custom Ribbon Action deletes all items from the List/Library using the JSOM objects SP.CamlQuery.createAllItemsQuery to List all Items and loop one by one and sends to Recycle bin using the JSOM object SP.ListItem.recycle.

SP.ListItem.recycle Method (sp.js)
SP.CamlQuery.createAllItemsQuery Method (sp.js)
https://msdn.microsoft.com/en-us/library/office/jj838380.aspx



For the XML structure of the Ribbon Configuration you can use the following:
<CommandUIExtension xmlns=\"http://schemas.microsoft.com/sharepoint/\">\n<CommandUIDefinitions>\n<CommandUIDefinition Location=\"Ribbon.Documents.Manage.Controls._children\">\n<Button Id=\"DeleteAllItems\" LabelText=\"Delete all Items\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-1\" Image32by32Top=\"-33\" ToolTipTitle=\"Delete all Items\" ToolTipDescription=\"Delete all Items\" Command=\"DeleteAllItems.Command\" TemplateAlias=\"o1\" />\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"DeleteAllItems.Command\" CommandAction=\"<Code>" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code

This JavaScript code makes an CAML query for all items and sends to Recycle bin one by one, simple like that.
PS:Please validate all risks associated with the action deletion of all items before you implement.

Action:
javascript:
function DeleteItems() {
    if (confirm("Are you sure you want to delete all items to recycle bin in this list ?")) {
        var notificationid = SP.UI.Notify.addNotification("In progress...", true);
        var context = new SP.ClientContext.get_current();
        var web = context.get_web();
        var ListGUID = SP.ListOperation.Selection.getSelectedList();
        if (ListGUID != null) {
            var List = web.get_lists().getById(ListGUID);
            var query = SP.CamlQuery.createAllItemsQuery();
            var Items = List.getItems(query);
            context.load(Items );
            context.executeQueryAsync(function(){
       var itemsToRecycle = new Array();
       var listItemEnumerator = Items.getEnumerator();
       while (listItemEnumerator.moveNext()) {
        var item = listItemEnumerator.get_current();
        itemsToRecycle.push(item);
       }

       for (var i = itemsToRecycle.length - 1; i >= 0; i--) {
        itemsToRecycle[i].recycle();
       }
       context.executeQueryAsync(function(){
           SP.UI.Notify.removeNotification(notificationid);
            SP.UI.Notify.addNotification("Done.", false);
            SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
          
       }, Function.createDelegate(this, this.onQueryFailed));
   }, Function.createDelegate(this, this.onQueryFailed));
        }
    }
}
function onQueryFailed() {
    SP.UI.Notify.addNotification("Failed.", false);
    SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
DeleteItems();

As you can see very easy. :)
I hope you like this article,

Best regards, 
André Lage