Friday, April 28, 2017

Part VI: Examples of Ribbons Customization in SharePoint / Office 365 - Send Email notification as reminder

As a follow up of my collection of examples regarding ribbons examples, i would like to share another simple example where you can make simple post-it note "reminder" to your email when you are in the SharePoint Office 365 environment and you don't need to be redirected to other page.


Before the example i would like to share the collection of SharePoint Ribbons examples from my articles:

Creation of the Ribbon

For this example was used the SharePoint Ribbon Manager app for the XML structure and Code generation, don't worry i will shared bellow. 

Using the Ribbon Designer reused an existing XML structure to add new options that will be available in my SharePoint Site, as shown in the example Add Custom Ribbon Button in Site Page to Popup all SharePoint Apps.


The first thing i did was to create a new Tab and group area and then create the new Ribbon Button where the code was included in the Action area.

 The Ribbon Code Editor provide the support for the javascript Code for the associated action and then you just need to click save to be available in you SharePoint Portal.

XML Structure for the Ribbon

The XML for the ribbon can be access bellow where is defined the Tab/Group and Button and associated code to send the email notification.

<CommandUIExtension xmlns=\"http://schemas.microsoft.com/sharepoint/\">\n<CommandUIDefinitions>\n<CommandUIDefinition Location=\"Ribbon.Tabs._children\">\n<Tab Id=\"Email.Notification\" Title=\"Email Notification\" Description=\"Email Notification\">\n<Scaling Id=\"Email.Notification.Scaling\">\n<MaxSize Id=\"Notifications.Scaling.MaxSize\" GroupId=\"Notifications\" Size=\"LargeLarge\" />\n<Scale Id=\"Notifications.Scaling.Scale\" GroupId=\"Notifications\" Size=\"LargeLarge\" />\n</Scaling>\n<Groups Id=\"Email.Notification.Groups\">\n<Group Id=\"Notifications\" Title=\"Notifications\" Description=\"Notifications\" Template=\"Ribbon.Templates.Flexible2\">\n<Controls Id=\"Notifications.Controls\">\n<Button Id=\"Email.Button\" LabelText=\"Email Notification\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-510\" Image32by32Top=\"-410\" ToolTipTitle=\"Email Notification\" Command=\"Email.Button.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</Group>\n</Groups>\n</Tab>\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=\"Email.Button.Command\" CommandAction=\"<Code>\" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code:

javascript:
function processSendEmails() {
   var from = _spPageContextInfo.userEmail,
        to = _spPageContextInfo.userEmail,
        subject =  _spPageContextInfo.webTitle + " - " + _spPageContextInfo.userDisplayName ;
  
 var body = prompt("Please enter Email Body!", "");
if (body != null)
    {
     sendEmail(from, to, body + "<br/><a href='"+_spPageContextInfo.webAbsoluteUrl+_spPageContextInfo.webServerRelativeUrl+"'>link</a>", subject);
    }
}
function sendEmail(from, to, body, subject) {
    //Get the relative url of the site
    var siteurl = _spPageContextInfo.webServerRelativeUrl;
    var urlTemplate =  "/_api/SP.Utilities.Utility.SendEmail";
    var shouldNotDisappearAfterTimeout = false;
    var obj; var waitDialog;
    $.ajax({
        contentType: 'application/json',
        url: urlTemplate,
        beforeSend : function(){
            waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose("Loading", "Please wait");
            obj = SP.UI.Notify.showLoadingNotification(shouldNotDisappearAfterTimeout);
        },
        type: "POST",
        data: JSON.stringify({
            'properties': {
                '__metadata': {
                    'type': 'SP.Utilities.EmailProperties'
                },
                'From': from,
                'To': {
                    'results': [to]
                },
                'Body': body,
                'Subject': subject
            }
        }),
        headers: {
            "Accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose",
            "X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
        },
        success: function(data) {
           waitDialog.close();  
           SP.UI.Notify.removeNotification(obj);
           SP.UI.Notify.addNotification('Email Sent Successfully', false);
        },
        error: function(err) {
            alert('Error in sending Email: ' + JSON.stringify(err));
        }
    });
}
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', processSendEmails);

How the solution will looks like

After the Ribbon is created, you can access to your SharePoint Site and a new Tab is available with a option email notification.


When you click in the button a prompt option will appear with a text option, there you can send some text that will appear in your office 365 email .


in your right corner of office 365 you will receive an alert regarding the send email in SharePoint site with  the box added in the prompt text area.

Done and very simple, you can create a simple reminder with this example.

I hope you like this example.
Best regards, 
André Lage 

Wednesday, March 16, 2016

Google Chart examples in Office 365 Sites and SharePoint

Some days ago i was playing around with the Google api and found the Google Charts and was surprise how different are from the older version....
But yes, everyone is talking about SP2016, Power BI for Data and visualization, but decide to give a try and make some examples integrating the Chart API with SharePoint List "Classic"... 
For this example i use the html from the chart to inject in the SharePoint Modal Dialog and not any support page to generate the reports, i try to keep very simple in the architectural approach.

There is another interesting Chart call "Org Chart" that make my attention and of course i will try to integrate in the user profile "another classic" but that is another article.
Right now i like to play with this API and make some example in JavaScript and of course my favorite topic create Custom Ribbons Actions. :)

Here the link from the Google Charts API.
https://developers.google.com/chart/ 

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

For other Examples of Ribbons Customization in SharePoint/Office 365 i would like the recommend the following link:
http://aaclage.blogspot.ch/2016/03/part-v-examples-of-ribbons.html

Configuration of the Chart Examples

To support the example was created a custom List with the Columns "Country, Sales". 
where should display the amount of sales by country.
For the Ribbons was create an FlyoutAnchor where are listed the different Ribbons Options "Bar Chart, Pie Chart and All Charts", when selected should popup the SharePoint Modal Dialog with the chart's associated.
If you make changes on the list using Quick Edit the Chart will reflect the changes without need of refresh the page.


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.List.Settings.Controls._children\">\n<FlyoutAnchor Id=\"Chart Example\" LabelText=\"Chart Examples\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-0\" Image32by32Top=\"-407\" Command=\"Chart Example.Command\" TemplateAlias=\"o1\">\n<Menu Id=\"Chart Example.Menu\">\n<MenuSection Id=\"Charts\" DisplayMode=\"Menu32\">\n<Controls Id=\"Charts.Controls\">\n<Button Id=\"barChart\" LabelText=\"Bar Chart\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-271\" Image32by32Top=\"-35\" ToolTipTitle=\"Bar Chart\" Command=\"barChart.Command\" TemplateAlias=\"o1\" />\n<Button Id=\"PieChart\" LabelText=\"Pie Chart\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-272\" Image32by32Top=\"-170\" ToolTipTitle=\"Pie Chart\" Command=\"PieChart.Command\" TemplateAlias=\"o1\" />\n<Button Id=\"AllCharts\" LabelText=\"All charts\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png\" Image32by32Left=\"-474\" Image32by32Top=\"-69\" ToolTipTitle=\"All charts\" Command=\"AllCharts.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</MenuSection>\n</Menu>\n</FlyoutAnchor>\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"Chart Example.Command\" CommandAction=\"\" />\n<CommandUIHandler Command=\"barChart.Command\" CommandAction=\"<CodeBar>\" />\n<CommandUIHandler Command=\"PieChart.Command\" CommandAction=\"<CodePie>\" />\n<CommandUIHandler Command=\"AllCharts.Command\" CommandAction=\"<CodeAllCharts>\" />\n</CommandUIHandlers>\n</CommandUIExtension>


Bar Chart Example

The Ribbon Custom Action "Bar Chart" read the List items from the Custom List and display in a html SharePoint Modal Dialog as Bar Chart.


Code Bar charts:

javascript:
    function DialogApps(element) {
        SP.UI.ModalDialog.showModalDialog({
            html: element,
            title: "Google Chart Example",
            allowMaximize: false,
            showClose: true,
            autoSize: true,
            height: 600,
            width: 600,
        });
    }

function drawStuff(array) {
    var data = new google.visualization.arrayToDataTable(array);

    var options = {
        title: 'Chart Example',
        width: 600,
        height: 600,
        legend: {
            position: 'none'
        },
        chart: {
            subtitle: 'Sales by Country'
        },
        bars: 'horizontal',
        axes: {
            x: {
                0: {
                    side: 'top',
                    label: 'Sales'
                } // Top x-axis.
            }
        },
        bar: {
            groupWidth: "90%"
        }
    };
    var element = document.createElement('div');
    element.setAttribute("id", "top_x_div");
    var chart = new google.charts.Bar(element);
    chart.draw(data, google.charts.Bar.convertOptions(options));
    DialogApps(element);
}

function ChartLoad() {
    google.charts.load('current', {
        'packages': ['bar', 'corechart']
    });
    google.charts.setOnLoadCallback(GetListItems);
}

function GetListItems() {
    var ctx = new SP.ClientContext.get_current();
    var targetList = ctx.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
    var query = SP.CamlQuery.createAllItemsQuery();

    var queryResults = targetList.getItems(query);
    ctx.load(queryResults);

    ctx.executeQueryAsync(function getDocsAllItemsSuccess(sender, args) {
            var array = [];
            array.push(['Country', 'Sale']);
            var listEnumerator = queryResults.getEnumerator();
            while (listEnumerator.moveNext()) {
                array.push([listEnumerator.get_current().get_item("Title"), listEnumerator.get_current().get_item("Sales")]);
            }
            drawStuff(array);
        },
        function getDocsAllItemsFailure(sender, args) {
            alert('Failed to get list items. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
        });
}

SP.SOD.registerSod("Chart", "//www.gstatic.com/charts/loader.js");
SP.SOD.executeFunc('Chart', false, ChartLoad);
GetListItems();

Pie Chart Example

The Ribbon Custom Action "Pie Chart" read the List items from the Custom List and display in a html SharePoint Modal Dialog as Pie Chart.


Code Pie charts:

javascript:
    function DialogApps(element) {
        SP.UI.ModalDialog.showModalDialog({
            html: element,
            title: "Google Chart Example",
            allowMaximize: false,
            showClose: true,
            autoSize: true,
            height: 600,
            width: 600,
        });
    }

function drawStuff(array) {
    var data = new google.visualization.arrayToDataTable(array);

    var options = {
        title: 'Chart Example',
        width: 600,
        height: 600
        
    };
    var element = document.createElement('div');
    element.setAttribute("id", "top_x_div");
    var chart = new google.visualization.PieChart(element);
    chart.draw(data, options);
    DialogApps(element);
}

function ChartLoad() {
    google.charts.load('current', {'packages': ['bar','corechart']});
    google.charts.setOnLoadCallback(GetListItems);
}

function GetListItems() {
    var ctx = new SP.ClientContext.get_current();
    var targetList = ctx.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
    var query = SP.CamlQuery.createAllItemsQuery();

    var queryResults = targetList.getItems(query);
    ctx.load(queryResults);

    ctx.executeQueryAsync(function getDocsAllItemsSuccess(sender, args) {
            var array = [];
            array.push(['Country', 'Sale']);
            var listEnumerator = queryResults.getEnumerator();
            while (listEnumerator.moveNext()) {
                array.push([listEnumerator.get_current().get_item("Title"), listEnumerator.get_current().get_item("Sales")]);
            }
            drawStuff(array);
        },
        function getDocsAllItemsFailure(sender, args) {
            alert('Failed to get list items. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
        });
}

SP.SOD.registerSod("Chart", "//www.gstatic.com/charts/loader.js");
SP.SOD.executeFunc('Chart', false, ChartLoad);
GetListItems();

Bar and Pie Charts in Modal Dialog

The Ribbon Custom Action "All Charts" read the List items from the Custom List and display in a html SharePoint Modal Dialog as Bar Chart and Pie Chart.


Code All charts:

javascript:
    function DialogApps(element) {
        SP.UI.ModalDialog.showModalDialog({
            html: element,
            title: "Google Chart Example",
            allowMaximize: false,
            showClose: true,
            autoSize: true,
            height: 650,
            width: 1200,
        });
    }

function drawStuff(array) {
    var data = new google.visualization.arrayToDataTable(array);

 var optionsPie = {
        title: 'Chart Example',
        width: 600,
        height: 600
        
    };
    var elementPie = document.createElement('div');
    elementPie.setAttribute("id", "top_Pie_div");
    var chartPie = new google.visualization.PieChart(elementPie);
    chartPie.draw(data, optionsPie);

    var optionsBar = {
        title: 'Chart Example',
        width: 600,
        height: 600,
        legend: {
            position: 'none'
        },
        chart: {
            subtitle: 'Sales by Country'
        },
         bars: 'horizontal',
        axes: {
            x: {
                0: {
                    side: 'top',
                    label: 'Sales'
                } 
            }
        },
        bar: {
            groupWidth: "90%"
        }
    };
    var elementBar = document.createElement('div');
    elementBar.setAttribute("id", "top_Bar_div");
    var chartBar = new google.charts.Bar(elementBar);
    chartBar.draw(data, google.charts.Bar.convertOptions(optionsBar));
    var element =  document.createElement('div');
    element.appendChild(elementBar);
    element.appendChild(elementPie);
    
    var x = document.createElement("TABLE");
    x.setAttribute("id", "myTable");

    var y = document.createElement("TR");
    y.setAttribute("id", "myTr");
    x.appendChild(y);

    var z = document.createElement("TD");
    z.appendChild(elementBar);
    y.appendChild(z);
    
    z = document.createElement("TD");
    z.appendChild(elementPie);
    y.appendChild(z);
    
    DialogApps(x);
}

function ChartLoad() {
    google.charts.load('current', {'packages': ['bar','corechart']});
    //google.charts.load('current', {'packages': ['bar']});
    google.charts.setOnLoadCallback(GetListItems);
}

function GetListItems() {
    var ctx = new SP.ClientContext.get_current();
    var targetList = ctx.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
    var query = SP.CamlQuery.createAllItemsQuery();

    var queryResults = targetList.getItems(query);
    ctx.load(queryResults);

    ctx.executeQueryAsync(function getDocsAllItemsSuccess(sender, args) {
            var array = [];
            array.push(['Country', 'Sale']);
            var listEnumerator = queryResults.getEnumerator();
            while (listEnumerator.moveNext()) {
                array.push([listEnumerator.get_current().get_item("Title"), listEnumerator.get_current().get_item("Sales")]);
            }
            drawStuff(array);
        },
        function getDocsAllItemsFailure(sender, args) {
            alert('Failed to get list items. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
        });
}

SP.SOD.registerSod("Chart", "//www.gstatic.com/charts/loader.js");
SP.SOD.executeFunc('Chart', false, ChartLoad);
GetListItems();

After the creation of this example you are able to make more chart and integrated other type of content and display in custom Ribbon Actions.

I hope you like this article, 
Kind regards, 
Andre Lage

Thursday, March 10, 2016

Part V: Examples of Ribbons Customization in SharePoint 2013/Office 365

As a follow up of my other article i would like to share another groups of custom Ribbons that could help business users using Charts or Developers in the analysis of SharePoint Objects (Web and List). This new Ribbons Custom Actions are "Web Properties,List Properties and Google Chart" examples.
The first 2 are for development analysis and not for end user usability, the Google chart example can be more interesting for business users when they want to generate KPI or Charts base in SharePoint List, this example just displays the chart with JSON dummy Data but not from a SharePoint List, that is a topic for another article.....

Here the collection and compilation of SharePoint Ribbon Custom Actions examples from my Articles:
All this Ribbons were made using the following tool "Processlynx Ribbon Manager"
http://aaclage.blogspot.ch/2014/06/sharepoint-app-processlynx-custom.html

List Properties

This example creates a new Ribbon Action in the Document Library "Settings area".
When the custom Action is selected the SharePoint List Properties are displayed in SharePoint Modal Dialog. 
Sub Object from the Object SP.List are not displayed, this is a example on how to get the List properties and not to display all the object dependency like the SharePoint Client Browser solution.

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<Button Id=\"ListProperties\" LabelText=\"List Properties\" Image16by16=\"/_layouts/15/1033/images/formatmap16x16.png?rev=33\" Image16by16Left=\"-0\" Image16by16Top=\"-294\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-0\" Image32by32Top=\"-408\" ToolTipTitle=\"List Properties\" Command=\"ListProperties.Command\" TemplateAlias=\"o1\" />\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"ListProperties.Command\" CommandAction=\"<Code>\" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code
This JavaScript code Lists properties and not they sub objects from the SharePoint SP.List Object.

CommandAction:
javascript:
    function runCode(ListId) {
        var clientContext = new SP.ClientContext.get_current();
        var targetList = clientContext.get_web().get_lists().getById(ListId.replace(/[{}]/g, ""));
        clientContext.load(targetList);
        clientContext.executeQueryAsync(function() {
            var stringHtml = '';
            var methods = getMethods(targetList);
            for (var i = 0; i < methods.length; i++) {
                if (methods[i].indexOf('get_') > -1 && methods[i].indexOf('$') == -1) {
                    try {
                        if (methods[i].replace("get_", "") != 'customActionElements') {
                            var object= targetList[methods[i]]();
                            stringHtml += '<div><b>' + methods[i].replace("get_", "") + '</b></br>' + JSON.stringify(object) + '</div>';
                        }
                    } catch (e) {}
                }
            }
            DialogApps(stringHtml);
        }, Function.createDelegate(this, this.onQueryFailed));
    }

function onQueryFailed(sender, args) {
    alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}

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

function getMethods(obj) {
    var res = [];
    for (var m in obj) {
        if (typeof obj[m] == "function") {
            res.push(m)
        }
    }
    return res;
}
runCode('{ListId}');

Web Properties

This example creates a new Ribbon Action in the Wiki Page.
When the custom Action is selected the SharePoint Web Properties are displayed in SharePoint Modal Dialog. 
Sub Object from the Object SP.Web are not displayed, this is a example on how to get the Web properties and not to display all the object dependency.

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.WikiPageTab.Groups._children\">\n<Group Id=\"Web.Site.Properties\" Title=\"Web Site Properties\" Description=\"Web Site Properties\" Template=\"Ribbon.Templates.Flexible2\">\n<Controls Id=\"Web.Site.Properties.Controls\">\n<Button Id=\"Web.Properties\" LabelText=\"Web Properties\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-0\" Image32by32Top=\"-409\" ToolTipTitle=\"Web Properties\" Command=\"Web.Properties.Command\" TemplateAlias=\"o1\" />\n</Controls>\n</Group>\n</CommandUIDefinition>\n<CommandUIDefinition Location=\"Ribbon.WikiPageTab.Scaling._children\">\n<MaxSize Id=\"Web.Site.Properties.Scaling.MaxSize\" GroupId=\"Web.Site.Properties\" Size=\"LargeMedium\" />\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=\"Web.Properties.Command\" CommandAction=\"<Code>\" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code
This JavaScript code List properties and not they sub objects from the SharePoint SP.Web Object.

CommandAction:
javascript:
    function runCode(ListId) {
        var clientContext = new SP.ClientContext.get_current();
        var targetList = clientContext.get_web();
        clientContext.load(targetList);
        clientContext.executeQueryAsync(function() {
            var stringHtml = '';
            var methods = getMethods(targetList);
            for (var i = 0; i < methods.length; i++) {
                if (methods[i].indexOf('get_') > -1 && methods[i].indexOf('$') == -1) {
                    try {
                        if (methods[i].replace("get_", "") != 'customActionElements') {
                            stringHtml += '<div><b>' + methods[i].replace("get_", "") + '</b></br>' + JSON.stringify(targetList[methods[i]]()) + '</div>';
                        }
                    } catch (e) {}
                }
            }
            DialogApps(stringHtml);
        }, Function.createDelegate(this, this.onQueryFailed));
    }

function onQueryFailed(sender, args) {
    alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}

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

function getMethods(obj) {
    var res = [];
    for (var m in obj) {
        if (typeof obj[m] == "function") {
            res.push(m)
        }
    }
    return res;
}
runCode();

Popup Google Chart

This example provides a example on how you can create a custom Ribbon Action and make call to Google Chart API and display the content in a SharePoint Modal Dialog.

Here the code Google Chart Example using in my Ribbon Action:
https://developers.google.com/chart/interactive/docs/gallery/columnchart#dual-y-charts

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<Button Id=\"CallChart\" LabelText=\"Chart\" Image16by16=\"/_layouts/15/1033/images/formatmap16x16.png?rev=33\" Image16by16Left=\"-0\" Image16by16Top=\"-294\" Image32by32=\"/_layouts/15/1033/images/formatmap32x32.png?rev=33\" Image32by32Left=\"-270\" Image32by32Top=\"-169\" ToolTipTitle=\"Chart\" Command=\"CallChart.Command\" TemplateAlias=\"o1\" />\n</CommandUIDefinition>\n</CommandUIDefinitions>\n<CommandUIHandlers>\n<CommandUIHandler Command=\"<Code>\" />\n</CommandUIHandlers>\n</CommandUIExtension>

Code
This JavaScript code adds the support Script "https:///www.gstatic.com/charts/loader.js" and generate the Chart in a Element, that is included in a SharePoint Modal Dialog.

CommandAction:
javascript:
 function DialogApps(element) {
    SP.UI.ModalDialog.showModalDialog({
        html: element,
        title: "Google Chart Example",
        allowMaximize: false,
        showClose: true,
        autoSize: true,
          height: 600,
          width: 600,
    });
}
function drawStuff() {
        var data = new google.visualization.arrayToDataTable([
          ['Move', 'Percentage'],
          ["King's pawn (e4)", 44],
          ["Queen's pawn (d4)", 31],
          ["Knight to King 3 (Nf3)", 12],
          ["Queen's bishop pawn (c4)", 10],
          ['Other', 3]
        ]);

        var options = {
          title: 'Chess opening moves',
          width: 600,
    height: 600,
          legend: { position: 'none' },
          chart: { subtitle: 'popularity by percentage' },
          axes: {
            x: {
              0: { side: 'top', label: 'White to move'} // Top x-axis.
            }
          },
          bar: { groupWidth: "90%" }
        };
   var element = document.createElement('div');
   element.setAttribute("id", "top_x_div");
  var chart = new google.charts.Bar(element);
        chart.draw(data, google.charts.Bar.convertOptions(options));
  DialogApps(element);
      }
   function ChartLoad(){
       google.charts.load('current', {'packages':['bar']});
     google.charts.setOnLoadCallback(drawStuff);
   }
SP.SOD.registerSod("Chart","//www.gstatic.com/charts/loader.js");
SP.SOD.executeFunc('Chart', false, ChartLoad);
drawStuff();

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

Best regards, 
André Lage