A page component is a client-side object that tells the ribbon on the page which commands it can handle. This object needs to be added to the page and is not directly coupled with the ribbon UX customizations.
This is what tripped me up. I couldn't figure out how to get the page component "registered." It actually was a lot more straightforward than I thought it would be. Once the script is added to the page, you add some commands that create a new instance of the page component and register it with the ribbon on the page.
Why Use a Page Component?
As you'll quickly see, creating a page component requires more work than the alternative. However, there are times when you'll want to create a page component. First of all, and probably the most important, anything that needs to be implemented with a ton of script will be hard to maintain in the XML file.
The second reason is because the page component is an actual client object, you have all the power of an object such as private methods and fields if you need to store state.
Building a Page Component
The process of building a page component can be broken down into a few steps once you've written the UX customization pieces (the stuff that creates tabs/groups/buttons):
1. Build the page component
2. Make sure any script dependencies your page component needs are on the page
3. Add the page component to the page
4. Initialize the page component
The command I walk through in this post is the page component equivalent to the declarative one I have blogged about.
The first thing you need to do is create a new script file and add something that will register the object on the page:
// register the page component object
Next, write a few methods that will act as the helpers for setting up the component (see Figure 1).
OK, now it's time to create the page component (see Figure 2).
Now, create the initialization portion of the page component. This method, init(), will do a few things. I want my page component to respond to a specific command:
The way I'm doing this is I'm adding it to an array and wiring up that name with a method in my page component named onApplyDocPrefixPageComponent(). I'm going to do the same thing that will be called to check to see if the command is available. The SharePoint SDK talks about a few other ways of doing this, but I prefer this option in Figure 3.
Two more parts of page components are the getFocusedCommands() and getGlobalCommands() methods. I'll cover these in a later post, but for now my command will be a global command (see Figure 4).
So now you need to implement the two methods that check to see if the command is available (canHandleCommand()) and the one that handles the commands (handleCommand()). These use the array I created earlier and call the associated methods (see Figure 5).
Now, implement the methods that do the work of handling the command (see Figure 6). I'll spare you the one that checks if it is available.
Last but certainly not least is the piece that actually initializes and registers the page component with the ribbon on the page (see Figure 7).
Here's a link to the complete *.JS file if you're having trouble looking at the figures.
Implementing a Page Component
First, you get a reference to the ribbon on the page and then make sure all the necessary scripts have been loaded before you add your page component (as there are dependencies in it). Then you add the page component to the page.
Figure 8 shows how I did this with a page component that added buttons to the Document tab when users are in the document library. It is in a server control that I registered on all pages in a particular site by adding the server control to the AdditionalPageHead placeholder control.
Once the page component has been added to the page, it will run the init statements in the script file that load create a instance of the page component and register it with the ribbon on the page.
Why I Prefer Page Components
Sure, there's a lot more work, but I like the page component option a lot more. Why? I just don't feel right putting my script in XML files. I find it easier to manage the script in a separate file. A side benefit here is that the external library can be cached downstream, but that isn't really a reason I like it because it's such a small file usually.
While there's a lot more script to write, I do like the added control the page component gives me. Your page component can receive focus and only respond to events when it is focused (more on this in another post).
Not only do I prefer them, but in my informal survey, three out of four doctors do as well.