Quickstart: Using a pivot control for layout and navigation

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

Learn how to use a WinJS.UI.Pivot control for layout and navigation in your Windows Phone 8.1 app.

The Pivot provides a quick way to manage, present, and quickly navigate through sections of content in your app by panning left or right—continuously wrapping like a carousel. Use it for filtering large datasets, viewing multiple data sets, or switching app views.

Example of Pivot implementation.

For help choosing the best navigation pattern for your app, see Navigation patterns.

Also, you can see the Flat navigation and Hierarchical navigation patterns in action as part of our App features, start to finish series.

Prerequisites

Instructions

1. Create a new project by using the Pivot App (Windows Phone) template

You can also use the Hub/Pivot App (Universal Apps) template to create a Universal Windows app. For this example, we'll use the Pivot App (Windows Phone) template.

Pivot App template in Visual Studio

  1. Start Microsoft Visual Studio 2013 Update 2.

  2. Choose File > New Project or click New Project from the Start Page tab. The New Project dialog box opens.

  3. In the Templates pane on the left, expand Installed => Templates => JavaScript => Store Apps.

  4. Select the Windows Phone Apps template type. The available project templates for JavaScript are displayed in the center pane of the dialog box.

  5. In the center pane, select the Pivot App (Windows Phone) project template.

  6. In the Name text box, type a name for your project. The examples in this topic use PivotDemo.

  7. Click OK to create the project.

2. Add a new section (PivotItem)

Each section within a Pivot is defined by a PivotItem control. The template includes four demo sections that you can modify or delete, as required. Here we'll show you how to add a fifth section.

The base file structure of the template looks like this in Solution Explorer.

Note   For consistency with Universal Windows apps, the template uses the hub-section-detail/item model of the Hierarchical navigation pattern for the file naming convention.

 

Files in the new Hub/Pivot App solution.

  1. The Pivot and each PivotItem are declared in hub.html in the pages\hub folder.

    Here, the template includes a single Pivot control (hub) with four PivotItem controls (sections) that contain both static (section1, section2, section4) and data-driven (section3) content.

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>hubPage</title>
    
      <link href="/css/phone.css" rel="stylesheet" />
      <link href="/pages/hub/hub.css" rel="stylesheet" />
      <link href="/pages/hub/hubphone.css" rel="stylesheet" />
      <script src="/js/data.js"></script>
      <script src="/pages/hub/hub.js"></script>
      <script src="/pages/hub/section1Page.js"></script>
      <script src="/pages/hub/section2Page.js"></script>
      <script src="/pages/hub/section3Page.js"></script>
      <script src="/pages/hub/section4Page.js"></script>
    </head>
    <body>
      <div class="hubpage fragment">
        <header aria-label="Header content" role="banner">
          <button class="titlearea backbutton" 
            data-win-control="WinJS.UI.BackButton">
          </button>
          <h1 class="titlearea win-type-ellipsis">
            <span class="pagetitle">PivotDemo</span>
          </h1>
        </header>
    
        <section aria-label="Main content" role="main">
          <!-- Customize the Hub control by modifying the 
               HubSection controls here. -->
    
          <div class="hub" data-win-control="WinJS.UI.Pivot">
    
            <div class="section1 section" 
              data-win-control="WinJS.UI.PivotItem" 
              data-win-options="{ isHeaderStatic: true }" 
              data-win-res="{ winControl: {'header': 'Section1'} }">
              <div class="sectioncontrol" 
                id="section1contenthost" 
                data-win-control="HubApps_SectionControls.Section1Control">
              </div>
            </div>
    
            <div class="section2 section" 
              data-win-control="WinJS.UI.PivotItem" 
              data-win-options="{ isHeaderStatic: true }" 
              data-win-res="{ winControl: {'header': 'Section2'} }">
              <div class="added pivot-item-viewport" >
                <div class="added pivot-item-surface" >
                  <div class="sectioncontrol" 
                    id="section2contenthost" 
                    data-win-control="HubApps_SectionControls.Section2Control">
                  </div>
                </div> 
              </div> 
            </div>
    
            <div class="section3 section" 
              data-win-control="WinJS.UI.PivotItem" 
              data-win-res="{ winControl: {'header': 'Section3'} }">
              <div class="section3contenthost sectioncontrol" 
                id="section3contenthost" 
                data-win-control="HubApps_SectionControls.Section3Control"
                data-win-options="{
                  dataSource: select('.pagecontrol').winControl.section3DataSource,
                  layout: {type: WinJS.UI.ListLayout},
                  oniteminvoked: select('.pagecontrol').winControl.section3ItemNavigate}">
              </div>
            </div>
    
            <div class="section4 section" 
              data-win-control="WinJS.UI.PivotItem" 
              data-win-options="{ isHeaderStatic: true }" 
              data-win-res="{ winControl: {'header': 'Section4'} }">
                <div class="sectioncontrol" 
                  id="section4contenthost" 
                  data-win-control="HubApps_SectionControls.Section4Control">
                </div>
            </div>
          </div>
        </section>
      </div>
    </body>
    </html>
    

    Declare additional pages by simply copying and pasting one of the existing sections. Modify the new section specification as required.

    Here, we declare a fifth section based on section4.

    <div class="section4 section" 
      data-win-control="WinJS.UI.PivotItem" 
      data-win-options="{ isHeaderStatic: true }" 
      data-win-res="{ winControl: {'header': 'Section4'} }">
      <div class="sectioncontrol" 
        id="section4contenthost" 
        data-win-control="HubApps_SectionControls.Section4Control">
      </div>
    </div>
    
    <div class="section5 section" 
      data-win-control="WinJS.UI.PivotItem" 
      data-win-options="{ isHeaderStatic: true }" 
      data-win-res="{ winControl: {'header': 'Section5'} }">
         <div class="sectioncontrol" 
        id="section5contenthost" 
        data-win-control="HubApps_SectionControls.Section5Control">
      </div>
    </div>
    
  2. Each PivotItem declared in hub.html must have its layout and functionality defined in corresponding HTML, JavaScript, and, possibly, Cascading Style Sheets (CSS) and resources files.

    For our example, we add section5Page.html and section5Page.js to the pages/hub folder.

    • section5Page.html—specifies the content of the section.

      Here, we just display a text link to an item page.

      <!DOCTYPE html>
      <html>
      <head>
         <title></title>
         <link href="/pages/hub/hub.css" rel="stylesheet" />
         <script src="/pages/hub/section5Page.js"></script>
      </head>
      <body>
         <div class="fragment section1page">
            <section aria-label="Main content" role="main">
              <a href="/pages/item/section5Item1.html">Link</a>
            </section>
         </div>
      </body>
      </html>
      
    • The header strings for each section are defined in resources.resjson in the strings/en-US folder.

      Here, we add another name-value pair for Section 5.

          "Section5": "Section 5",
          "Section5Description": "",
      
    • section5Page.js—specifies behavior that's associated with the section.

      Here, we call a basic ready function for the page and expose the section5Page as a custom control for display on the hub. We also have a click handler for the text link that initiates the navigation to an item page.

      (function () {
         "use strict";
      
         var ControlConstructor = 
           WinJS.UI.Pages.define("/pages/hub/section5Page.html", {
             // This function is called after the page control contents 
             // have been loaded, controls have been activated, and 
             // the resulting elements have been parented to the DOM. 
             ready: function (element, options) {
               options = options || {};
      
               // Retrieve the page 2 link and register the event handler. 
               // Don't use a button when the action is to go to another 
               // page; use a link instead. 
               // See Guidelines and checklist for buttons at 
               // https://go.microsoft.com/fwlink/p/?LinkID=313598
               // and Quickstart: Using single-page navigation at 
               // https://go.microsoft.com/fwlink/p/?LinkID=320288.
               WinJS.Utilities.query("a").listen(
                 "click", linkClickHandler, false);
            },
         });
      
         // The following lines expose this control constructor as a global. 
         // This lets you use the control as a declarative control inside 
         // the data-win-control attribute. 
      
         WinJS.Namespace.define("HubApps_SectionControls", {
            Section5Control: ControlConstructor
         });
      
         function linkClickHandler(eventInfo) {
            var link = eventInfo.target;
            eventInfo.preventDefault();
            if (link.href.indexOf("ms-appx") > -1) {
              WinJS.Navigation.navigate(link.href);
            }
            else if (link.href.indexOf("http") > -1) {
              // Create a Uri object from a URI string 
              var uri = new Windows.Foundation.Uri(link.href);
              var options = new Windows.System.LauncherOptions();
              // Launch the URI with a warning prompt
              options.treatAsUntrusted = true;
              // Launch the URI
              Windows.System.Launcher.launchUriAsync(uri, options).then(
                 function (success) {
                    if (success) {
                      // URI launched
                    } else {
                      // URI launch failed
                    }
                 });
            }
         }
      })();
      

    A reference to section5Page.js must also be added to hub.html in the pages/hub folder.

    <head>
       <meta charset="utf-8" />
       <title>hubPage</title>
    
       <link href="/css/phone.css" rel="stylesheet" />
       <link href="/pages/hub/hub.css" rel="stylesheet" />
       <link href="/pages/hub/hubphone.css" rel="stylesheet" />
       <script src="/js/data.js"></script>
       <script src="/pages/hub/hub.js"></script>
       <script src="/pages/hub/section1Page.js"></script>
       <script src="/pages/hub/section2Page.js"></script>
       <script src="/pages/hub/section3Page.js"></script>
       <script src="/pages/hub/section4Page.js"></script>
       <script src="/pages/hub/section5Page.js"></script>
    </head>
    
  3. Run the app. Choose Debug > Start Debugging, or choose F5 (choose SHIFT + F5 to stop debugging and return to Microsoft Visual Studio).

    Here is a screen shot of the Phone app with the new section.

    The pivot example showing the new Section 5.

3. Create a Universal Windows app with the Hub/Pivot App (Universal Apps) template

Use the Hub/Pivot App (Universal Apps) template to create a Universal Windows app for Windows and Windows Phone.

  1. Start Visual Studio 2013 Update 2.

  2. Choose File > New Project or click New Project from the Start Page tab. The New Project dialog box opens.

  3. In the Templates pane on the left, expand Installed => Templates => JavaScript => Store Apps.

  4. Select the Universal Apps template type. The available project templates for JavaScript are displayed in the center pane of the dialog box.

  5. In the center pane, select the Hub/Pivot App (Universal Apps) project template.

  6. In the Name text box, type a name for your project.

  7. Click OK to create the project.

  8. Your new Hub/Pivot App solution contains three projects. One for Windows-specific files, one for Phone-specific files, and one for code that is shared. Set the StartUp Project to Windows or WindowsPhone project, as required for testing.

4. Add a new section for Universal Windows apps

As in the Pivot App (Windows Phone) template, the Hub/Pivot App template includes four demo sections that you can modify or delete, as required.

The base file structure of the template looks like this in Solution Explorer.

Files in the new Hub/Pivot App solution.

Each corresponding HTML, JavaScript, CSS, and resource file can be universal across both Windows and Phone projects or unique to the specific platform (see the various projects in the template demo).

Run the app. Choose Debug > Start Debugging, or choose F5 (choose SHIFT + F5 to stop debugging and return to Visual Studio).

Remember: Set the WindowsPhone project as the StartUp Project.

Here is a screen shot of the Phone app with the new section.

The pivot example showing the new Section 5.

And here's a screen shot of the new section in the Windows app.

The universal pivot example showing the new Section 5.

Summary

In this quickstart, you reviewed the Pivot App (Windows Phone) template and the Hub/Pivot App (Universal Apps) universal template included with Visual Studio 2013 Update 2. You added a new section with the PivotItem control and a simple handler function for the click event on the text link included in the section content.

For developers

Your first app - Part 3: PageControl objects and navigation

Quickstart: Using single-page navigation

WinJS.Navigation Namespace

WinJS.UI.Pivot

WinJS.UI.PivotItem

HTML Pivot control sample

Navigation and navigation history sample

For designers

Guidelines for Pivots

Navigation patterns

Command patterns

Layout