Part 1: Create a "Hello, world" app (Windows Phone Store apps using JavaScript)
[ 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 ]
This tutorial teaches you how to create a simple "Hello, world" Windows Phone Store app using JavaScript. This is the first tutorial in a 3-part series that teaches you everything you need to know to build apps using JavaScript and HTML.
In this tutorial, you learn how to:
- Create a new project.
- Add HTML content to your start page.
- Handle user input.
- Switch between the light and dark style sheets.
- Create your own custom styles.
- Use a Windows Library for JavaScript control.
Before you start...
- To complete this tutorial, you need Windows 8.1 and Microsoft Visual Studio Express 2013 Update 2 for Windows. Get the tools.
- You also need a developer license. Get a developer license.
Step 1: Create a new project in Visual Studio
To get started with your app, you'll need to create a new project in Visual Studio.
To create a new project in Visual Studio
In Visual Studio, on the File menu select , click New Project.
In the left pane of the New Project dialog, expand Installed, expand Templates, expand JavaScript, expand Store Apps, and then select the Windows Phone Apps template type. The center pane displays a list of JavaScript project templates.
In the center pane, select the Blank App template.
Note that although this series focuses on how to create a Windows Phone Store app, you can easily create an app for both Windows and Windows Phone at the same time using the Universal template. To learn more, we suggest you finish this tutorial series first, and then check out this article on how to Build a universal Windows app.
The Blank App template creates a minimal app that compiles and runs, but does not contain user interface controls or data. You'll add controls and data to the app over the course of these tutorials.
In the Name text box, type "HelloWorld", and then click OK to create the project.
Each new project contains these essential files:
- A manifest file, package.appxmanifest, which describes your app—its name, description, tile, start page, splash screen, and so on—and lists the files that your app contains.
- A set of large and small logo images to display in the start screen (logo.png and smalllogo.png), an image to represent your app in the Store (storelogo.png), and a splash screen to show when your app starts (storelogo.png).
- The Windows Library for JavaScript (WinJS) inside the References folder.
- A set of Cascading Style Sheets (CSS) files to give your app the modern Windows look and feel.
- A start page, default.html, and an accompanying JavaScript file, default.js, which both run when your app starts.
To view and edit a file, double-click the file in Solution Explorer.
Step 2: Launch the app
At this point, you've created a very simple app. If you want to see what it looks like, press F5 to build, deploy, and start your app using the Windows Phone 8.1 emulator. If you're starting the emulator for the first time, it may take a few minutes to load. A default splash screen appears first. The splash screen is defined by an image, splashscreen.png, and a background color, which is specified in your app's manifest file. To learn how to further customize your splash screen, see Adding a splash screen.
After the splash screen, your app appears. It contains a black screen with the text "Content goes here".
To stop the app, click the stop symbol on the Visual Studio toolbar. This stops your app, but leaves the emulator open so you can quickly edit, deploy, and launch your app on the emulator again (you can't edit an app while it's running in the emulator).
Your app doesn't do much—yet—but congratulations, you've built your first app!
Step 3: Modify the start page
One of the files Visual Studio created for you is default.html, your app's start page. When the app runs, it displays the content of its start page. The start page also contains references to the app's code files and style sheets. Here's the default start page Visual Studio created:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HelloWorld</title>
<!-- WinJS references -->
<link href="/css/ui-themed.theme-light.css" rel="stylesheet" />
<script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
<script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
<!-- HelloWorld references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
</head>
<body>
<p>Content goes here</p>
</body>
</html>
Now, add some new content to your default.html file. Just as you would add content to any other HTML file, add your content inside the body element. You can use HTML5 elements to create your app (with a few exceptions). For example, you can use h1, p, button, div, and img.
To modify the start page
Replace the existing content in the body element with a first-level heading that says "Hello, world!", some text that asks the user's name, an input element to accept the user's name, a button element, and a div element. Assign IDs to the input, button, and div elements.
<body> <h1>Hello, world!</h1> <p>What's your name?</p> <input id="nameInput" type="text" /> <button id="helloButton">Say "Hello"</button> <div id="greetingOutput"></div> </body>
Press F5 to run the app.
You can write in the input element, but right now, clicking the button doesn't do anything. Some objects, such as button, can send messages when certain events occur. The event messages give you the opportunity to take some action in response to the event.
In the next steps, you create an event handler for the button that displays a personalized greeting. Then you'll add your event handler code to the default.js file.
Step 4: Create an event handler
One of the files Visual Studio creates in every new project is /js/default.js. This file contains code for handling your app's life cycle, a concept that we explain in Part 2: Manage app life cycle and state. This file also is where you write additional code that provides interactivity for your default.html file.
Before you start adding your own code, open default.js and take a look at the first and last few lines of code in the file:
(function () {
"use strict";
// Omitted code
})();
These lines of code wrap the rest of the default.js code in a self-executing anonymous function. Wrapping your code in a self-executing anonymous function makes it easier to avoid naming conflicts or situations where you accidentally modify a value that you didn't intend to modify. It also keeps unnecessary identifiers out of the global namespace, which helps performance. It looks a little strange, but it's a good programming practice.
The second line of code turns on strict mode for your JavaScript code. Strict mode provides additional error checking for your code. For example, it prevents you from using implicitly declared variables or assigning a value to a read-only property.
The rest of the code in default.js handles your app's activated and checkpoint events. We go into more detail about these events later. For now, it's just important to know that the activated event fires when your app starts.
Next, you need to define an event handler for your button. Your new event handler gets the user's name from the nameInput
input control and uses it to output a greeting to the greetingOutput
div element that you created in the previous section.
To create the event handler
In default.js, after the app.oncheckpoint event handler and before the call to app.start, create a click event handler function named
buttonClickHandler
that takes a single parameter namedeventInfo
.function buttonClickHandler(eventInfo) { }
Inside your event handler, retrieve the user's name from the
nameInput
input control and use it to create a greeting. Use thegreetingOutput
div to display the result.function buttonClickHandler(eventInfo) { // Get the user's name input var userName = document.getElementById("nameInput").value; // Create the greeting string and set the greeting output to it var greetingString = "Hello, " + userName + "!"; document.getElementById("greetingOutput").innerText = greetingString; }
Now you need to register your event handler.
Step 5: Register the event handler when the app launches
The only thing you need to do now is register the event handler with the button. The recommended way to register an event handler is to call addEventListener from your code. A good place to register the event handler is when your app is activated. Fortunately, Visual Studio generated some code in your default.js that contains the app.onactivated event handler. This handles app activation.
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
args.setPromise(WinJS.UI.processAll());
}
};
Inside the onactivated handler, the code checks to see what type of activation occurred. There are many types of activations. For example, your app is activated when the user launches your app and when the user wants to open a file that is associated with your app. (For more info, see Application life cycle.)
What you want to use in your app is the launch activation. An app is launched whenever it is not running and then a user activates it.
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
If the activation is a launch activation, the code checks to see how the app was shut down the last time it ran.
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
Then it calls WinJS.UI.processAll.
args.setPromise(WinJS.UI.processAll());
}
};
It calls WinJS.UI.processAll regardless of whether the app had been shut down in the past or if this is the very first time it's being launched. The WinJS.UI.processAll is enclosed in a call to the setPromise method, which makes sure the splash screen appears until the app's page is ready.
Tip The WinJS.UI.processAll function scans your default.html file for WinJS controls and initializes them. So far, you haven't added any of these controls, but it's a good idea to keep this code in case you want to add them later. To learn more about WinJS controls, see Quickstart: Adding WinJS controls and styles.
A good place to register event handlers for other types of controls is just after the call to WinJS.UI.processAll.
To register your event handler
In the onactivated event handler in default.js, retrieve
helloButton
and use addEventListener to register your event handler for the click event. Add this code after the call to WinJS.UI.processAll.app.onactivated = function (args) { if (args.detail.kind === activation.ActivationKind.launch) { if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { // TODO: This application has been newly launched. Initialize // your application here. } else { // TODO: This application has been reactivated from suspension. // Restore application state here. } args.setPromise(WinJS.UI.processAll()); // Retrieve the button and register our event handler. var helloButton = document.getElementById("helloButton"); helloButton.addEventListener("click", buttonClickHandler, false); } };
Here's the complete code for your updated default.js file:
// For an introduction to the Blank template, see the following documentation:
// https://go.microsoft.com/fwlink/p/?linkid=232509
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
args.setPromise(WinJS.UI.processAll());
// Retrieve the button and register your event handler.
var helloButton = document.getElementById("helloButton");
helloButton.addEventListener("click", buttonClickHandler, false);
}
};
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state
// that needs to persist across suspensions here. You might use the
// WinJS.Application.sessionState object, which is automatically
// saved and restored across suspension. If you need to complete an
// asynchronous operation before your application is suspended, call
// args.setPromise().
};
function buttonClickHandler(eventInfo) {
// Get the user's name input
var userName = document.getElementById("nameInput").value;
// Create the greeting string and set the greeting output to it
var greetingString = "Hello, " + userName + "!";
document.getElementById("greetingOutput").innerText = greetingString;
}
app.start();
})();
Run the app. When you enter your name in the text box and click the button, the app displays a personalized greeting.
Note For more info about why you use addEventListener to register your event in code rather than setting the onclick event in your HTML, see Coding basic apps.
Step 6: Style your start page
It's easy to customize the look and feel of your app using Cascading Style Sheets, Level 3 (CSS3), much like you would a website.
The default.html file that Visual Studio created contains a reference to the WinJS style sheet:
<!-- WinJS references -->
<link href="/css/ui-themed.css" rel="stylesheet" />
A style sheet provides these benefits:
- A set of styles that automatically give your app the modern Windows look and feel. Just including the style sheet makes your controls look great.
- Automatic switching between light and dark themes to match the phone's background theme.
- Automatic support for high-contrast modes. These styles were designed with high contrast in mind, your app displays properly when your app runs on a device in high-contrast mode.
- Automatic support for other languages. The WinJS style sheets automatically select the correct font for every language that Windows Phone 8.1 supports. You can even use multiple languages in the same app, and they all display properly.
- Automatic support for other reading orders. Style sheets automatically adjusts HTML and WinJS controls, layouts, and styles for languages that read from right to left.
By default, each HTML page in your project contains a reference to ui-themed.css, which matches the user's background theme. By default, the Windows Phone emulator uses the dark theme. See what happens when you switch to the light theme.
To switch to the light theme
In the emulator, press the home button to go to the home screen, then swipe your mouse from right to left to open the list of apps. Scroll down and click Settings, then click start+theme. Change the background selection to light.
Relaunch your app from Visual Studio (if your app was already running, you'll need to shut down and relaunch it before the theme will change). Your app now uses the light style sheet.
The way this works is that when you created your project, Visual Studio automatically generated four CSS files:
- default.css
- ui-themed.css
- ui-themed.theme-dark.css
- ui-themed.theme-light.css
When you reference ui-themed.css, the WinJS automatically checks the theme on the user's device when your app runs. Then it applies either ui-themed.theme-dark.css style or ui-themed.theme-light.css, depending on the user's preference. If you want to manually design your app to use a particular theme, replace the reference to ui-themed.css with a specific reference to either the light or dark theme. For example, to use the dark theme:
<!-- HelloWorld references -->
<link href="/css/ui-themed.theme-dark.css" rel="stylesheet" />
Creating your own styles
If you want to customize the look and feel of your app, you don't have to throw out the WinJS styles and start from scratch. It's easy to make incremental changes by overriding the styles you want to change.
In fact, it's better to override the WinJS styles instead of creating your own. When your app runs in high-contrast mode, any changes to the colors in the default styles are automatically overridden by a color scheme that supports high-contrast.
You can override any style in the default style sheet by creating your own style sheet and including it after the WinJS style sheet. The Blank App template does this for you. It creates a style sheet named default.css that you can use to create your own styles.
<!-- HelloWorld references -->
<link href="/css/default.css" rel="stylesheet" />
To create your own styles
First, add div elements and classes to your HTML to make it easier to set styles.
In Visual Studio, open the default.html file.
Set your page header's class attribute to "headerClass". Create a div element and use it to contain your page's main content. Give it a class setting of "mainContent".
<body> <h1 class="headerClass">Hello, world!</h1> <div class="mainContent"> <p>What's your name?</p> <input id="nameInput" type="text" /> <button id="helloButton">Say "Hello"</button> <div id="greetingOutput"></div> </div> </body>
To define your styles, open the default.css file.
Right now it's mostly blank:
body { }
Add some CSS classes to manage the three main sections that currently exist in your app: the header, the main content, and the greeting output. First, add some padding so they aren't right up against the border of the screen. Then, set the greeting output to use a larger font so it's more visible to the user.
body { } .headerClass { padding:10px; } .mainContent { padding:15px; } #greetingOutput { font-size:x-large; }
Run the app. Notice the change in spacing.
Apps support CSS3, so there's a lot you can do to customize your app. (For more info about styling your app, see Quickstart: Styling controls.)
Step 7: Add a Windows Library for JavaScript control
In addition to standard HTML controls, you can use many of the controls in the WinJS in your app, for example, the WinJS.UI.FlipView, WinjS.UI.ListView, and WinJS.UI.ToggleSwitch controls.
Unlike HTML controls, WinJS controls don't have dedicated markup elements: you can't create a ToggleSwitch control by adding a <toggle />
element, for example. To add a WinJS control, you create a div element and use the data-win-control attribute to specify the type of control you want. Then you can specify any properties of the element using the data-win-options attribute.
Now, add a ToggleSwitch control, with which a user can easily select between two options: "On" and "Off". Set the title attribute of the ToggleSwitch so you can indicate the purpose of your switch to the user.
To add a Windows Library for JavaScript control
In your default.html file, add a label and a ToggleSwitch control after the
greetingOutput
div.<body> <h1 class="headerClass">Hello, world!</h1> <div class="mainContent"> <p>What's your name?</p> <input id="nameInput" type="text" /> <button id="helloButton">Say "Hello"</button> <div id="greetingOutput"></div> <br /> <div id="toggleControlDiv" data-win-control="WinJS.UI.ToggleSwitch" data-win-options="{title: 'Greeting Color'}"></div> </div> </body>
Your page must call WinJS.UI.processAll for the ToggleSwitch to load. Because your app is using a Visual Studio template, the default.js file already includes a call to WinJS.UI.processAll, described in Step 5, so you don't have to add any code.
Run the app and take a look at the new ToggleSwitch control.
Right now, flipping the ToggleSwitch doesn't do much. You need to add an event handler to do something when the user changes the switch's state.
Step 8: Register an event handler for a Windows Library for JavaScript control
Registering an event handler for a WinJS control is a little different than registering an event handler for a standard HTML control. As noted earlier, the onactivated event handler calls the WinJS.UI.processAll method to initialize WinJS in your markup. The WinJS.UI.processAll is enclosed in a call to the setPromise method.
args.setPromise(WinJS.UI.processAll());
If ToggleSwitch was a standard HTML control, you could add your event handler after this call to WinJS.UI.processAll. But it's a little more complicated for a WinJS control like your ToggleSwitch. Because WinJS.UI.processAll creates the ToggleSwitch control, you can't add the event handler to ToggleSwitch until after WinJS.UI.processAll has finished processing.
If WinJS.UI.processAll was a typical method, we could register the ToggleSwitch event handler right after we call it. But the WinJS.UI.processAll method is asynchronous, so any code that follows it might run before WinJS.UI.processAll completes. What you do is use a Promise object to receive notification when WinJS.UI.processAll completes.
Like all asynchronous WinJS methods, WinJS.UI.processAll returns a Promise object. A Promise is a "promise" that something will happen in the future; when that thing happens, the Promise is said to have completed.
Promise objects have a then method that takes a "completed" function as a parameter. The Promise calls this function when it completes.
By adding your code to a "completed" function and passing it to the Promise object's then method, you can be sure your code executes when WinJS.UI.processAll is completed.
To register an event handler for a Windows Library for JavaScript control
Change the style of the greeting based on whether the toggle switch is set to "On" or "Off". In your css file, add a new CSS class to represent this different style you'll apply if the switch is on with the id "toggle-style". For this example, we'll change the color of the text to blue.
.toggle-on { color:blue; }
In your default.js file, create an event handler for the ToggleSwitch control's change event named
toggleChanged
. Tell the event handler to check the status of the toggle control and, depending on its state, apply or remove the new CSS class.function toggleChanged(eventInfo) { // Get the toggle control var toggleControl = document.getElementById("toggleControlDiv").winControl; // Get the greeting output var greetingOutput = document.getElementById("greetingOutput"); // Set the CSS class for the greeting output based on the toggle's state if (toggleControl.checked == true) { greetingOutput.setAttribute("class", "toggle-on"); } else { greetingOutput.removeAttribute("class", "toggle-on"); } }
Update the code in your onactivated event handler that calls WinJS.UI.processAll by adding a call to the then method and passing it a completed function. In the completed function, retrieve the
toggleControlDiv
element that hosts the ToggleSwitch control. Then use the winControl property to retrieve the actual ToggleSwitch control. This example defines thecompleted
function inline.args.setPromise(WinJS.UI.processAll().then(function completed() { // Retrieve the div that hosts the Toggle control. var toggleControlDiv = document.getElementById("toggleControlDiv"); // Retrieve the actual Toggle control. var toggleControl = toggleControlDiv.winControl; // Register the event handler. toggleControl.addEventListener("change", toggleChanged); }));
Although it's OK to register event handlers for HTML controls after the call to WinJS.UI.processAll, you also can register them inside your
completed
function. For simplicity, move all your event handler registrations inside the then event handler.Here's your updated onactivated event handler:
app.onactivated = function (args) { if (args.detail.kind === activation.ActivationKind.launch) { if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { // TODO: This application has been newly launched. Initialize // your application here. } else { // TODO: This application has been reactivated from suspension. // Restore application state here. } args.setPromise(WinJS.UI.processAll().then(function completed() { // Retrieve the div that hosts the Toggle control. var toggleControlDiv = document.getElementById("toggleControlDiv"); // Retrieve the actual Toggle control. var toggleControl = toggleControlDiv.winControl; // Register the event handler. toggleControl.addEventListener("change", toggleChanged); // Retrieve the button and register our event handler. var helloButton = document.getElementById("helloButton"); helloButton.addEventListener("click", buttonClickHandler, false); })); } };
Run the app. When you flip the ToggleSwitch, the style of content inside the "greetingOutput" div changes.
This example is simple and only touches on the basics of what you need to know to start using WinJS controls. You can easily add more complex logic and controls to your app using the same principles to accomplish much more. To see a list of all available controls, see Quickstart: Adding WinJS controls and styles.
Summary
Congratulations, you've completed the tutorial! You learned how to add content to an app, how to add interactivity to your app, and how to style the app.
Download the sample
Need help, or want to check your work? Download the Getting started with JavaScript sample.
Next steps
In the Part 2 of this series, you can learn more about how the app life cycle works and how to save app state. Go to Part 2: Manage app life cycle and state.