locked
JavaScript runtime errors about undefined or nulll refences

    Question

  • I have implemented a SettingsFlyout. From the view of this flyout, my app collection some info from user (firsname) and want to store it in roaming settings. This information get stored when user clicks a button the settings view and retrieved when in the beforeShow event for the flyout. These two events are setup in the ready function of the SettingsFlyout itself but for some reason I am getting following error. 

    0x800a138f - JavaScript runtime error: Unable to get property 'winControl' of undefined or null reference

    on following line

    var divtest = document.getElementById"test").winControl;.

    Similarly I also get

    0x800a138f - JavaScript runtime error: Unable to set property 'onclick' of undefined or null reference.

    Do you see anything I am doing wrong causing these issues?

    Here is what I have in default.html

    app.onsettings = function (e) {
    
            e.detail.applicationcommands = {
                "test": {
                    href: "/pages/settings/test/test.html",
                    title: "Test"
                }
            }
    
            WinJS.UI.SettingsFlyout.populateSettings(e);
        };

    Here is the test.html itself.

    <!DOCTYPE html> <html> <head> <title></title> <link href="/pages/settings/test/test.css" rel="stylesheet" />

    <script src="/pages/settings/test/test.js"></script>

    </head> <body> <div data-win-control="WinJS.UI.SettingsFlyout" data-win-options="{settingsCommandId:'test', width:'narrow'}"> <div class="win-header"> <div class="win-label">test</div> </div> <div class="win-content"> First Name: <input id="firstname" /> <br /> <input type="submit" value="Save" /> </div> </div> </body> </html>

    Here is the test.js file.

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/settings/test/test.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) {
                // TODO: Initialize the page here.
                var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;
                var divtest = document.getElementById("test").winControl;
                var firstname = document.getElementById("firstname");
    
                document.getElementById("submit").onclick = function (e) {
                    //alert('hi');
                    roamingSettings.values["firstname"] = firstname.value;
                }
    
                divtest.addEventListener("beforeshow", function () {
                    firstname.value = roamingSettings.values["firstname"];
                });
            },
    
            unload: function () {
                // TODO: Respond to navigations away from this page.
            },
    
            updateLayout: function (element, viewState, lastViewState) {
                /// <param name="element" domElement="true" />
    
                // TODO: Respond to changes in viewState.
            }
        });
    })();

    Friday, June 28, 2013 3:07 PM

Answers

  • Hi, you're using getElementById, but some of your elements are missing IDs.

    In test.html set id='test' on your WinJS.UI.SettingsFlyout div and set id='submit' on the input element.

    Also, I think you can remove the onbeforeshow handler and just set firstname.value directly in the ready function in test.js. Set it after you retrieve the firstname element.

    Joel

    Monday, July 1, 2013 7:45 PM
  • Your HTML file lacks the IDs, it should be:

    <body>
            <div id="test"
                data-win-control="WinJS.UI.SettingsFlyout"  data-win-options="{settingsCommandId:'test',  width:'narrow'}">
                <div class="win-header">       
                    <div class="win-label">test</div>
                </div>
                <div class="win-content">
                    First Name: <input id="firstname" />
                    <br />
                    <input id="submit" type="button" value="Save" />
                </div>
            </div>  
        </body>

    Also, you don't really need to use a "beforeShow" handler, the code inside the "ready:" handler is called when all the HTML elements are ready to be initialized, so it should work like this:

    ready: function (element, options) {
    	// TODO: Initialize the page here.
    	var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;
    	
    	document.getElementById("submit").onclick = function (e) {
    		//alert('hi');
    		roamingSettings.values["firstname"] = firstname.value;
    	}
    
    	if(roamingSettings.values["firstname"]){ //check to see if the value exists
    		document.getElementById("firstname").value = roamingSettings.values["firstname"];
    	}
    },
    You could also implement the same code that saves the roamingSettings on the "blur" event using addEventListener, so the user just needs to modify the value and not click or tap any button.

    Monday, July 1, 2013 8:02 PM

All replies

  • Hi, you're using getElementById, but some of your elements are missing IDs.

    In test.html set id='test' on your WinJS.UI.SettingsFlyout div and set id='submit' on the input element.

    Also, I think you can remove the onbeforeshow handler and just set firstname.value directly in the ready function in test.js. Set it after you retrieve the firstname element.

    Joel

    Monday, July 1, 2013 7:45 PM
  • Your HTML file lacks the IDs, it should be:

    <body>
            <div id="test"
                data-win-control="WinJS.UI.SettingsFlyout"  data-win-options="{settingsCommandId:'test',  width:'narrow'}">
                <div class="win-header">       
                    <div class="win-label">test</div>
                </div>
                <div class="win-content">
                    First Name: <input id="firstname" />
                    <br />
                    <input id="submit" type="button" value="Save" />
                </div>
            </div>  
        </body>

    Also, you don't really need to use a "beforeShow" handler, the code inside the "ready:" handler is called when all the HTML elements are ready to be initialized, so it should work like this:

    ready: function (element, options) {
    	// TODO: Initialize the page here.
    	var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;
    	
    	document.getElementById("submit").onclick = function (e) {
    		//alert('hi');
    		roamingSettings.values["firstname"] = firstname.value;
    	}
    
    	if(roamingSettings.values["firstname"]){ //check to see if the value exists
    		document.getElementById("firstname").value = roamingSettings.values["firstname"];
    	}
    },
    You could also implement the same code that saves the roamingSettings on the "blur" event using addEventListener, so the user just needs to modify the value and not click or tap any button.

    Monday, July 1, 2013 8:02 PM