Geeks With Blogs
David Jacobus SharePoint Consultant

 

Lets put together a Ribbon Project which demonstrates my last post.

Create an empty SharePoint Project, here named testRibbonCommunications:

 image

Add New Item

image

 

  1.  
  2.  
  3.  
  4.  

 

 

 

 

Choose Application Page (I named this TestRibbon.aspx)

 

image

 

image

Add the following code in a PageComponent.js file to your layouts folder and change the namespace to fit your project (testRibbonCommunications) just do a find / replace:

/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" /> 
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />  

function ULS_SP() {
  if (ULS_SP.caller) {
    ULS_SP.caller.ULSTeamName = "Windows SharePoint Services 4";
    ULS_SP.caller.ULSFileName = "/_layouts/testRibbonCommunications/PageComponent.js";
  }
}


Type.registerNamespace('testRibbonCommunications');

// RibbonApp Page Component
CaseSmartIntakeForm.PageComponent = function () {
  ULS_SP();
  CaseSmartIntakeForm.PageComponent.initializeBase(this);
}


CaseSmartIntakeForm.PageComponent.initialize = function () {
  ULS_SP();
  ExecuteOrDelayUntilScriptLoaded(Function.createDelegate(null, testRibbonCommunications.PageComponent.initializePageComponent), 'SP.Ribbon.js');
}


testRibbonCommunications.PageComponent.initializePageComponent = function () {
  ULS_SP();
  var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
  if (null !== ribbonPageManager) {
    ribbonPageManager.addPageComponent(testRibbonCommunications.PageComponent.instance);
    ribbonPageManager.get_focusManager().requestFocusForComponent(testRibbonCommunications.PageComponent.instance);
  }
}


testRibbonCommunications.PageComponent.refreshRibbonStatus = function () {
  SP.Ribbon.PageManager.get_instance().get_commandDispatcher().executeCommand(Commands.CommandIds.ApplicationStateChanged, null);
}


testRibbonCommunications.PageComponent.prototype = {
  getFocusedCommands: function () {
    ULS_SP();
    return [];
  },
  getGlobalCommands: function () {
    ULS_SP();
    return getGlobalCommands();
  },
  isFocusable: function () {
    ULS_SP();
   return true;
  },
  receiveFocus: function () {
    ULS_SP();
    return true;
  },
  yieldFocus: function () {
    ULS_SP();
    return true;
  },
  canHandleCommand: function (commandId) {
    ULS_SP();
    return commandEnabled(commandId);
  },
  handleCommand: function (commandId, properties, sequence) {
      ULS_SP();

    return handleCommand(commandId, properties, sequence);
  }
}


// Register classes
testRibbonCommunications.PageComponent.registerClass('testRibbonCommunications.PageComponent', CUI.Page.PageComponent);
testRibbonCommunications.PageComponent.instance = new testRibbonCommunications.PageComponent();


// Notify waiting jobs
NotifyScriptLoadedAndExecuteWaitingJobs("/_layouts/testRibbonCommunications/PageComponent.js");

 

 

 

 

 

 

 

 

 

 

 

 

 

In the code behind for your application page add the  ICallbackEventHandler Interface to the page code behind:

 

 

namespace testRibbonCommunications.Layouts.testRibbonCommunications
{
    public partial class TestRibbon : LayoutsPageBase, ICallbackEventHandler
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }


        public string GetCallbackResult()
        {
            throw new NotImplementedException();
        }

        public void RaiseCallbackEvent(string eventArgument)
        {
            throw new NotImplementedException();
        }
    }
}

The XML is terse but once you have done one tab and button you can do them all.

Add the following region to the code behind of the application page (A tab with a single button):

 

        #region tabxml
        private string mainTab = @"
    <Tab
        Id=""Ribbon.MyTab""
        Title=""Daves Tab""
        Description=""Daves Tab""
        Sequence=""1105"">

      <Scaling
        Id=""Ribbon.MyTab.Scaling"">
        <MaxSize
        Id=""Ribbon.MyTab.MaxSize""
        GroupId=""Ribbon.MyTab.MyGrp""
        Size=""OneLargeTwoMedium""/>
        <Scale
        Id=""Ribbon.MyTab.Scaling.CustomTabScaling""
        GroupId=""Ribbon.MyTab.MyGrp""
        Size=""OneLargeTwoMedium"" />
      
    </Scaling>
    <Groups Id=""Ribbon.MyTab.Groups"">

        <Group
        Id=""Ribbon.MyTab.MyGrp""
        Description=""Actions""
        Title=""Status""
        Sequence=""52""
        Template=""Ribbon.Templates.MyGrp"">
        <Controls>
          


            <Button
            Id=""Ribbon.MyTab.MyGrp.Save""
            Sequence=""56""
             Image32by32=""/_layouts/1033/images/formatmap32x32.png""
            Image32by32Top=""-416""
            Image32by32Left=""-256""
            Description=""Save Button""
            Command=""Ribbon.MyTab.MyGrp.Save.Click""
            LabelText=""""
            TemplateAlias=""cust2""/>


        </Controls>

        </Group>
      

    </Groups>
    </Tab>";

        private string contextualTabTemplate = @"
    <GroupTemplate Id=""Ribbon.Templates.MyGrp"">
    <Layout
        Title=""OneLargeTwoMedium"" LayoutTitle=""OneLargeTwoMedium"">
        <Section Alignment=""Top"" Type=""OneRow"">
        <Row>

 
            <ControlRef DisplayMode=""Large"" TemplateAlias=""cust2"" />
    
  
        </Row>
        </Section>

    </Layout>

    </GroupTemplate>";

        #endregion

 

Add the following region to the code behind of the application page:

 #region tabMethods
        private void AddRibbonTab()
        {
            // Gets the current instance of the ribbon on the page.
            SPRibbon ribbon = SPRibbon.GetCurrent(this.Page);

            //Prepares an XmlDocument object used to load the ribbon
            XmlDocument ribbonExtensions = new XmlDocument();

            //Load the contextual tab XML and register the ribbon.
            ribbonExtensions.LoadXml(this.mainTab);
            ribbon.RegisterDataExtension(ribbonExtensions.FirstChild,
                "Ribbon.Tabs._children");

            //Load the custom templates and register the ribbon.
            ribbonExtensions.LoadXml(this.contextualTabTemplate);
            ribbon.RegisterDataExtension(ribbonExtensions.FirstChild,
                "Ribbon.Templates._children");



            ribbon.Minimized = false;
            ribbon.CommandUIVisible = true;
            const string initialTabId = "Ribbon.MyTab";
            if (!ribbon.IsTabAvailable(initialTabId))
                ribbon.MakeTabAvailable(initialTabId);
            ribbon.InitialTabId = initialTabId;
        }



        private void AddTabEvents()
        {
            var commands = new List<IRibbonCommand>();

            // register the command at the ribbon. Include the callback to the server     // to generate the xml

            commands.Add(new SPRibbonCommand("Ribbon.MyTab.MyFormGrp.Save.Click", "setSave();", "true"));

        

            //Register initialize function
            var manager = new SPRibbonScriptManager();
            var methodInfo = typeof(SPRibbonScriptManager).GetMethod(
            "RegisterInitializeFunction",
            BindingFlags.Instance | BindingFlags.NonPublic);
            methodInfo.Invoke(manager, new object[] { 
        Page, "InitPageComponent", 
        "/_layouts/testRibbonCommunications/PageComponent.js", false, 
        "testRibbonCommunications.PageComponent.initialize()" });

            // Register ribbon scripts
            manager.RegisterGetCommandsFunction(Page, "getGlobalCommands", commands);
            manager.RegisterCommandEnabledFunction(Page, "commandEnabled", commands);
            manager.RegisterHandleCommandFunction(Page, "handleCommand", commands);
        }
        #endregion


 

 

 

Add the following region to the code behind of the application page:

#region pageEvents

protected void Page_Load(object sender, EventArgs e)
{


    if (!IsPostBack)
    {



    }
}

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);

    this.AddRibbonTab();

    AddTabEvents();



    String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");

    String callbackScript;

    callbackScript = "function CallServer(arg, context)" +

    "{ " + cbReference + ";}";

    Page.ClientScript.RegisterClientScriptBlock(this.GetType(),

    "CallServer", callbackScript, true);

}

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

}
#endregion

 

The above code blocks tie the ribbon pieces together

 

Add a JavaScript Page to the solution in the Layouts folder (PageScript.js):

 

function setSave() {
    //call server
    SP.UI.Notify.addNotification("You pressed Save, ", false);
    CallServer("Save", "");

}


// variable to hold the server data
var itemsXml;

// This function will receive the callback from the server with the data. 
function ReceiveServerData(arg, context) {
    itemsXml = arg;
}

Link the JavaScript file to the page by adding this to the page AdditionalPageHead section: use your page URL

 

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
    <SharePoint:ScriptLink Name="sp.js" LoadAfterUI="true" OnDemand="false" Localizable="false" runat="server" ID="ScriptLink1" />
    <SharePoint:ScriptLink Name="CUI.js" LoadAfterUI="true" OnDemand="false" Localizable="false" runat="server" ID="ScriptLink2" />
    <SharePoint:ScriptLink Name="/_layouts/testRibbonCommunications/PageComponent.js" LoadAfterUI="true" OnDemand="false" Localizable="false" runat="server" ID="ScriptLink3" />
    <SharePoint:ScriptLink Name="/_layouts/testRibbonCommunications/pageScript.js" LoadAfterUI="true" OnDemand="false" Localizable="false" runat="server" ID="ScriptLink4" />
   
 
</asp:Content>

 

 

Replace the ICallbackEventHandler methods with this region:

#region ICallbackEventHandler Members

      public string GetCallbackResult()
      {

          //I am returning nothing
          string returnData = "Call Back Results";
          return returnData;
      }

      public void RaiseCallbackEvent(string eventArgument)
      {


          if (eventArgument.Contains("Save"))
          {
              //handle the save event here

          }


      }
      #endregion

 

Deploy the solution and browse to the page:

 

image

Everything should be good to go!

 

 

Set a Breakpoint at the RaiseCallbackEvent(string eventArgument) and hit F5 Browse to the layouts page and click the save button, Notice the breakpoint get hit and enters the empty test.

image

There you have it!  Here is the solution for you to build on! TestRibbonCommunications

Posted on Friday, October 1, 2010 8:03 PM | Back to top


Comments on this post: Demo Ribbon Server Communications Project

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © David Jacobus | Powered by: GeeksWithBlogs.net