Quickstart: Adding item containers

[ 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 add an ItemContainer object to your Windows app using JavaScript. The ItemContainer creates a simple interactive element without very much HTML markup or JavaScript code. The items created with this control match the look and feel of Windows in animation, swipe, drag and drop, and hover.

In this quickstart article, you build a simple customer data display using a Repeater control and an ItemContainer control. You also learn how to create a data entry form in a Windows app using JavaScript using an HTML <form> element that incorporates two ItemContainer controls.

Prerequisites

Create a new project by using the Navigation App template

  1. Start Microsoft Visual Studio.

  2. From the Start Page tab, click New Project. The New Project dialog opens.

  3. In the Installed pane, expand Templates and JavaScript, and click the Windows Store app template type. The available project templates for JavaScript are displayed in the center pane of the dialog.

  4. In the center pane, pick the Navigation App project template.

  5. In the Name text box, type ItemContainer demo.

  6. Click OK to create the project.

Add the HTML with the ItemContainer controls

The ItemContainer provides a robust, multi-purpose control to be used when another control (for example, the ListView control) may not be appropriate. The ItemContainer works well as a richer version of a toggle button. It can also be used as a drop target, similar to a shopping cart user interface. More importantly, the ItemContainer can be used in conjunction with other controls, most notably the Repeater. You can use the ItemContainer and Repeater together to bind dynamic data to the ItemContainer.

The ItemContainer can be defined either declaratively in an HTML page or at runtime using JavaScript loaded with the page. This example creates the ItemContainer declaratively in the HTML markup, with one example hosted within a Repeater control.

  1. Open up the home.js file (/pages/home/home.html) and add the following HTML markup.

    
    <!-- Create an entry form for new customer data. -->
    <div id="customerInput">
        <h2>Customer entry</h2><br />
        <form id="inputContainer"
            class="itemContainer">
            <input id="firstName" type="text" placeholder="First name" required /><br />
            <input id="lastName" type="text" placeholder="Last name" required /><br />
            <input id="phoneNumber" type="tel" placeholder="Phone number" /><br />
            <input id="email" type="email" placeholder="E-mail" required /><br /><br />
            <div id="contactByEmail"
                class="selectionItem"
                data-win-control="WinJS.UI.ItemContainer"
                data-win-options="{
                    tapBehavior: directSelect
                }">Contact by e-mail</div><br />
            <div id="contactByPhone"
                class="selectionItem"
                data-win-control="WinJS.UI.ItemContainer"
                data-win-options="{
                    tapBehavior: directSelect
                }">Contact by phone</div><br />
            <button type="submit">Submit</button>
            <button type="reset">Clear</button>
        </form>
    </div>
    
    <!-- Create a display for existing customer data -->
    <div id="customerList">
        <h2>Customer list</h2><br />
        <div id="entryContainer"
            class="itemContainer"
            data-win-control="WinJS.UI.Repeater"
            data-win-options="{
                data: CustomerData.data
        }">
            <div class="customerListItem"
                data-win-control="WinJS.UI.ItemContainer">
                <b>Name:</b> <span data-win-bind="textContent: name"></span><br />
                <b>E-mail:</b> <span data-win-bind="textContent: email"></span><br />
                <b>Phone: </b> <span data-win-bind="textContent: phoneNumber"></span><br />
                <b>Contact by: </b><span data-win-bind="textContent: contactPreference"></span><br />
            </div> 
        </div>
    </div>
    

    This markup defines two parts of the user interface within the app: a customer data entry form and a display for existing customer data. The customer data entry form contains two ItemContainer controls within a <form> element, where the ItemContainer controls act like rich checkbox controls. The customer data display section contains a Repeater that includes an ItemContainer for displaying individual customer data entries.

  2. Open home.css (/pages/home/home.css) and add the following code.

    
    /* Style the page so that the entry form and
    display are in two separate parts of a grid. */
    .maincontent {
        padding: 50px;
        display: -ms-grid;
        -ms-grid-columns: 1fr 1fr;
        -ms-grid-rows: inherit;
    }
    
    #customerInput {
        -ms-grid-column: 1;
    }
    
    #customerList {
        -ms-grid-column: 2;
    }
    
    #entryContainer {  
        overflow-y: auto;
    }
    
    .itemContainer {
        width: 500px;
        height: 350px;
    }
    
    .selectionItem {
        width: 300px;
        border: 10px;
        height: 50px;
    }
    
    /* Create a solid gray border around items
    in the customer display list. */
    .customerListItem {
        width: 450px;
        margin-top: 10px;
        margin-bottom: 10px;
        border-style: solid;
        border-color: gray;
    }
    

    This styling creates a two-part grid to contain the customer data entry and the customer data display parts of the app. The customer data entry form appears on the left side of the app and the customer data display on the right.

Apply JavaScript event handlers to the controls

This app takes information entered into the form and then displays it in the list of customer data. When the form is submitted, the data from the form is converted into a single JavaScript object. The object is then added to the list of displayed customer data.

  1. Right-click the js folder and then click Add > New JavaScript File. In the Add New Item dialog box, name the file data.js and click Add. Add a reference to the new script in default.html.

    <script src='/js/data.js'></script>
    
  2. Open data.js (/js/data.js) and add the following code.

    (function () {
        "use strict";
    
        var customers = [];
        var customerList = new WinJS.Binding.List(customers);
    
        function Customer(customerInfo) {
            this.name = customerInfo.lastName + ", " + customerInfo.firstName;
            this.email = customerInfo.email;
            this.phoneNumber = customerInfo.phone;
            this.contactPreference = "Does not wish to be contacted";
    
            if (customerInfo.contactByPhone && customerInfo.contactByEmail) {
                this.contactPreference = "Contact by e-mail and phone"
            }
            else if (customerInfo.contactByPhone) {
                this.contactPreference = "Contact by phone only"
            }
            else if (customerInfo.contactByEmail) {
                this.contactPreference = "Contact by email only"
            }
        }
    
        WinJS.Namespace.define("CustomerData", {
            data: customerList,
            Customer: Customer
        });
    })();
    

    This code defines a new namespace, CustomerData, that exposes two members: Customer, an object for storing customer data; and data, a List that stores Customer objects.

  3. Open home.js (/pages/home/home.js) and replace the existing code with the following.

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/home/home.html", {
            // This function is called whenever a user navigates to this page. It
            // populates the page elements with the app's data.
            ready: function (element, options) {
    
                // Apply an event handler to when the user
                // submits the form.
                var form = document.forms[0];
                form.onsubmit = function (evt) {
    
                    // Prevent the form from refreshing the page.
                    evt.preventDefault();
    
                    // Get the customer input data from the form.
                    var entryForm = evt.target;
                    var entry = {
                        firstName: entryForm.firstName.value,
                        lastName: entryForm.lastName.value,
                        phone: entryForm.phoneNumber.value,
                        email: entryForm.email.value,
                        contactByEmail: entryForm.children.contactByEmail.winControl.selected,
                        contactByPhone: entryForm.children.contactByPhone.winControl.selected
                    };
    
                    // Submit the new Customer data to the list of customers.
                    var customer = new CustomerData.Customer(entry);
                    var entryList = document.querySelector("#entryContainer").winControl;
                    entryList.data.push(customer);
    
                    // Clear the entry form.
                    entryForm.querySelector("button[type='reset']").click();
                }
    
                // Add additional clean-up work when the user 
                // clicks the Reset button.
                form.onreset = function (evt) {
                    var entryForm = evt.target;
    
                    // Remove any selection from the item containers.
                    entryForm.children.contactByEmail.winControl.selected = false;
                    entryForm.children.contactByPhone.winControl.selected = false;
                }
    
                // Release memory from the 'form' variable after 
                // event handlers have been applied.
                form = null;
            }
        });
    })();
    

    This code adds event handlers to the two buttons declared in the <form> element. When the Submit button is clicked, the code gets the data from the customer entry form, adds a new Customer object to the data source for the Repeater control, and then clears the form. The event handler applied to the Reset button clears the selection of the two ItemContainer controls included within the form.

  4. Press F5 to run the sample. When the app runs, enter data into the Customer entry form and then click Submit. A new ItemContainer appears under the Customer list, displaying the information for that customer. With the app still running, enter some more data into the form and then click Reset. The form is cleared and all selections are removed from the two ItemContainer controls in the form.

Summary and next steps

In this quickstart, you learned how to use ItemContainer controls in a couple of ways: as rich checkbox controls for user selections, and as nested controls within a Repeater control. You also learned how to use an HTML <form> element within a Windows app using JavaScript.

ItemContainer controls can also be used as both drag and drop targets. However, this article does not demonstrate how to do that.

To learn more about how to use the Repeater control, see Quickstart: adding repeater controls.

To learn more about how to create drag and drop functionality, see How to enable reordering, dragging, and dropping in a ListView.