1

I am basically new to JavaScript and WinJs stuff. Following this tutorial to learn it.

My default.html is below

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>HelloWorld</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<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" />
        <label for="ratingControlDiv">
            Rate this greeting:
        </label>
        <div id="ratingControlDiv" data-win-control="WinJS.UI.Rating" />
        <div id="ratingOutput" />
    </div>
</body>
</html>

My default.js is as follows

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    WinJS.Binding.optimizeBindingReferences = true;

    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().then(function completed() {

                // Retrieve the div that hosts the Rating control.
                var ratingControlDiv = document.getElementById("ratingControlDiv");

                // Retrieve the actual Rating control.
                var ratingControl = ratingControlDiv.winControl;

                // Register the event handler. 
                ratingControl.addEventListener("change", ratingChanged, false);

                // Retrieve the button and register our 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) {
        var userName = document.getElementById("nameInput").value;
        var greetingString = "Hello, " + userName + "!!!";
        document.getElementById("greetingOutput").innerText = greetingString;

    }

    function ratingChanged(eventInfo) {

        var ratingOutput = document.getElementById("ratingOutput");
        ratingOutput.innerText = eventInfo.detail.tentativeRating;
    }

    app.start();
})();

I am getting ratingOutput as null in ratingChanged. Any ideas why?

GotDibbs
  • 2,490
  • 1
  • 17
  • 27
crazy novice
  • 1,617
  • 2
  • 14
  • 32

1 Answers1

3

As the other comments indicate, be sure to use to close, as self-closed div's are not valud HTML5. In the link that Jeffrey gave, there's this quote from a validator, I believe: "Self-closing syntax (/>) used on a non-void HTML element. Ignoring the slash and treating as a start tag."

The problem is not the ratingOutput div, but the one before it that's used for the Rating control. I dropped your code into a new project and reproduced your results, and could see in Visual Studio's DOM Explorer that the ratingOutput div was not present in the DOM at all.

Why would this be? It's a combination of the quote above plus the way WinJS.UI.processAll creates a WinJS control within the ratingControlDiv. The WinJS instantiation process (within processAll) is effectively seeing ratingOutput as a child of ratingControlDiv, and replacing it with the real control contents.

Put another way, the behavior you're seeing is exactly as if you wrote this markup:

<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
    <div id="ratingOutput"></div>
</div>

Unless a WinJS control explicitly says that it works a certain way with child element (like the semantic zoom control), there's no guarantee that child elements will be retained.

So ratingOutput is getting removed from the DOM by the rating control instantiation.

Using proper close tags, solves the problem:

<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating"></div>
<div id="ratingOutput"></div>

Great question--I'll add this note to the second edition that I'm working on now.

Kraig (Author, Programming Windows 8 Apps with HTML, CSS, and JavaScript, free ebook from Microsoft Press)

  • Thanks Kraig for the help. On Jeffery's comment I only changed on div but not all. Now when I fixed other Div's too, everything works fine. – crazy novice Apr 25 '13 at 16:17
  • The void elements that don't need it are: area, base, br, col, embed, hr, img, input, keygen, link, menuitem, meta, param, source, track, wbr. The self closing '/' is ignored on these items. It is used on foreign elements though to note self closing, and those are ONLY MathML and SVG namespace tags. Everything else requires a closing tag. I have a brief blurb on a blog entry for this, I'll update shortly. – Adam Tuliper - MSFT Apr 25 '13 at 22:48