locked
How can i set WinJS.UI.setoptions dynamically ? RRS feed

  • Question

  •  I have one custom control - auto complete text box.. i want to bind the data to the control dynamically. Please refer below code.

    <div id="contenthost" data-win-control="MyApp.UI.Autocomplete" >

    i  can able to specify " data-win-options " in the same page ( i.e.

    <div id="contenthost" data-win-control="MyApp.UI.Autocomplete" data-win-options="{options:.....}" >)

     but i want to add the data list dynamically using winjs.ui.setoptions. like below rating control

    // Do this instead: WinJS.UI.processAll().then(function () { var control = document.getElementById("ratingControlHost").winControl; WinJS.UI.setOptions(control, {list of options :values }); });

    after am doing this how it will reflect in auto complete text box. how can i bind the data dynamically in Win-JS ?

    Thanks,



    siva

    Thursday, January 24, 2013 11:22 AM

All replies

  • Hi,

    Could you post the custom control code?


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, January 25, 2013 9:36 AM
  • Hi Song,

    Thanks for your reply.

    Please download the sample from below link.

    auto complete text box sample.

    WinJSCustomControl.zip

    i want to pass the options series list , based on the series list options am going to modify some items in auto complete text box.

    please help me.

    Thanks,


    siva

    Friday, January 25, 2013 9:59 AM
  • Hi ,

    Any update ? 

    Thanks,


    siva

    Monday, January 28, 2013 5:06 AM
  • i have asked this question already in another thread . but no one provided the solution .please check it.

    http://social.msdn.microsoft.com/Forums/en-US/winappswithhtml5/thread/8ac5b845-c48d-4acb-9e31-83a0ddfbb985/?prof=required

    please reply asap.

    Thanks,


    siva

    • Merged by Song Tian Monday, January 28, 2013 8:31 AM
    Monday, January 28, 2013 5:07 AM
  • Hi,

    I reproduce that on my side. And add the follow code in home.js

    var control = document.getElementById("txtCities").winControl;
                WinJS.UI.setOptions(control, { optionList: Data.cities, });

    I can see the data in custom control when debugging.

    I will involve more experts to investigate it.


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    • Edited by Song Tian Monday, January 28, 2013 8:55 AM
    Monday, January 28, 2013 8:22 AM
  • Hi,

    Can you please send the sample for your last update ?

    Thanks,


    siva

    Monday, January 28, 2013 8:35 AM
  • Hi,

    I just add the code as above.


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, January 28, 2013 8:41 AM
  • Hi Song,

    I can't understand your solution. i want to add some more options in java script since "Data.cities" is already added in html tag itself. 

    please check the below code.


            <section aria-label="Main content" role="main">
                <p>Content goes here.</p>
                <input type="text" name="txtCities" id="txtCities" data-win-control="MyApp.UI.Autocomplete" data-win-options="{ optionList: Data.cities }"/>
            </section>

    i want to pass another option list in java script  not Data.cities , based on the option am going to filter the cities . could you please provide the correct direction to do this ?

    Thanks,


    siva

    Monday, January 28, 2013 8:45 AM
  • Hi,

    Actually, I have delete that in home.html before I add the above code in home.js.

    The code just as follow:

    home.html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>homePage</title>
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
    
        <link href="/css/default.css" rel="stylesheet" />
        <link href="/pages/home/home.css" rel="stylesheet" />
        <script src="/pages/home/home.js"></script>
        <script src="/js/data.js"></script>
        <script src="/js/autocomplete.js"></script>
    </head>
    <body>
        <!-- The content that will be loaded and displayed. -->
        <div class="fragment homepage">
            <header aria-label="Header content" role="banner">
                <button class="win-backbutton" aria-label="Back" disabled type="button"></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Welcome to WinJSCustomControl!</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                <p>Content goes here.</p>
                <input type="text" name="txtCities" id="txtCities" data-win-control="MyApp.UI.Autocomplete" />
            </section>
        </div>
    
        
    </body>
    </html>

    home.js

    (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) {
                // TODO: Initialize the page here.
                var control = document.getElementById("txtCities").winControl;
                WinJS.UI.setOptions(control, { optionList: Data.cities, });
    
            }
        });
    })();
    


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, January 28, 2013 8:55 AM
  • Hi Song,

    Thank you very much for quick reply.

    Actually our requirement is as follows.

    1.  we will create the custom control (fully client side rendering). then customer can able to set the options in his sample html page not in source. your last solution is setting the options in home.js file. i want to add the options in same home.html file.,not in source level.

    For your reference please check the below link.

    http://helpcentral.componentone.com/nethelp/c1winjs/#!Documents/linechartmarkupandsc.htm

    from above link customer can able to set the options through script as well as "data-win-options" in same html page. could you please understand my requirement ?

    Thanks,


    siva

    Monday, January 28, 2013 9:08 AM
  • Hi Siva,

    Yes, I got you. But you should define that in autocomplete.js first.


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, January 28, 2013 9:21 AM
  • Hi Song,

    Thanks again for your quick reply.

    Please consider the below scenario.

    1. I want to pass the another options called serieslist in default.html file.


        <script type="text/javascript">
            WinJS.UI.processAll();
            WinJS.Utilities.ready(function () {
                
                var control = document.getElementById("contenthost").winControl;
                WinJS.UI.setOptions(control, {
                    seriesList: [{
                        label: "s1",
                        legendEntry: true,
                        data: { x: [1, 2, 3, 4, 5], y: [-5, -3, 1, 7, 2] }
                    }, {
                        label: "s2",
                        legendEntry: true,
                        data: { x: [1, 2, 3, 4, 5], y: [-2, -6, 2, 4, 3] }
                    }, {
                        label: "s3",
                        legendEntry: true,
                        data: { x: [1, 2, 3, 4, 5], y: [-3, -5, 3, 2, 5] }
                    }]
                });
            }, true).done();
        </script>    

      (function (WinJS) {
        WinJS.Namespace.define("MyApp.UI", {
            Autocomplete: WinJS.Class.define(function (element, options) {

      // here i want to get the series list and assign it to some other object.

    this.seriesList={};

    this.seriesList=options.seriesList;

    //based on the series list am going to filter the cities

    ----------------------------------------------------

    ---------------------------------------------------------------------------------

    }}

    so i want to pass the serieslist options from default.html file and get the options in autocomplete.js then assign it new object and then will do our filter option.

    we don't know how to pass the serieslist option in javacsript before win control is rendered. please provide the sample code or sample if possible.

    Thanks,


    siva

    Monday, January 28, 2013 9:33 AM
  • Hi ,

    Any update ?

    Thanks,


    siva

    Monday, January 28, 2013 12:02 PM
  • Hi siva,

    I think you can save the data in local file from default.html. For example, Data Storage, IndexDB. And then you can handle the data in custome control.

    For data access, please refer to the blog: http://blogs.msdn.com/b/win8devsupport/archive/2012/12/19/using-html5-javascript-in-windows-store-apps-data-access-and-storage-mechanism-i.aspx .


    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, January 29, 2013 8:48 AM
  • Hi Song,

    Thanks for your reply.

    I think you guys misunderstood  our requirement . i will explain in simple terms. rating control there in Win -JS . Please check the below code.

    <div id="ratingControlHost" data-win-control="WinJS.UI.Rating"></div> <script type="text/javascript"> WinJS.UI.processAll().done(function () { var control = document.getElementById("ratingControlHost").winControl; control.averageRating = 3; }); </script>

    from above code averageRaing value is passed from script instead of adding in "data-win-options" , same way we need to pass the collection

    using WinJS.UI.setOptions through script ?

    could you please understand now itself ?

    Thanks,


    siva

    Tuesday, January 29, 2013 9:15 AM
  • Hi Siva Rajini,

    I have downloaded your custom WinJS control (autocomplete) code and here are some of my finding and suggestion on it:

    According to your code, you did use the WinJS.class.define to declare the winJS control class. However, you only expose one public property "element". For other properties like "_optionList", "_setOptionList", you used them as internal variable or functions (which is only called by other functions defined on your control class). Actually, the reasonable approach is as below:


    * When you use the following syntax to set control options:


    <input type="text" name="txtCities" id="txtCities" data-win-control="MyApp.UI.Autocomplete" data-win-options="{ optionList: Data.cities }"/> 


    it actually invoke the constructor of the control (which takes an options parameter) so that you can manually assign the passed options to the property control properties in constructor code.

    * When you want to programmtically assign some control properties (after the control is constructued) such as


    var control = document.getElementById("autocomplete1").winControl;
    control.optionList =xxxx;


    Then, what you need to do is directly declare a property on your control class and give it "getter" and "setter" (especially the setter) pairs. e.g.



    WinJS.Namespace.define("MyApp.UI", {
            Autocomplete: WinJS.Class.define(function (element, options) {debugger
             .......
            },
                {
                    optionList:{
       get: function(){ ...},
       set: function( options){...}
      }
                })
        });

     


    * In the setter method above (for the "optionList" property), you can add code to refresh/update the HTML dom element or element attributes according to the new option/values assigned.

    To better understand the ideas I mentioned, I suggest you take a look at the following custom WinJS control sample which mentioend using custom control property (with getter and setter):

    #Building a custom control using the Windows Library for JavaScript (WinJS)
    http://blogs.msdn.com/b/windowsappdev/archive/2012/10/11/building-a-custom-control-using-the-windows-library-for-javascript-winjs.aspx

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, January 30, 2013 11:02 AM
    Moderator
  • Hi Steven,

    Thank you very much for your prompt response.0

    Actually we don't like this kind of approach. but we have doubt when can i get the wincontrol (i.e. in which method is used to get the wincontrol)  

    we tried in Winjs.UI.processAll fucntion, it returns the wincontrol but autocomplete.js is called before that function.

    so i want to set more number options before that autocomplete.js called in script side using

    WinJS.Ui.Setoptions {......

    }

    var control = document.getElementById("autocomplete1").winControl;
    control.optionList =xxxx;

    because we have so many number of properties and collection values (i.e. more number of JSON data)

    so using winjs.ui.setoptions we can pass more number of collections from script side and then we will get this in autocomplete.js file like that

    WinJS.Namespace.define("MyApp.UI", {
            Autocomplete: WinJS.Class.define(function (element, options) {debugger
             .......
            },

    from options parameter we can get all the JSON objects and then we will perform the operation .Please refer below link for your reference.

    http://helpcentral.componentone.com/nethelp/c1winjs/#!Documents/linechartmarkupandsc.htm

    Please provide better solution.


    siva

    Wednesday, January 30, 2013 11:22 AM
  • Hi Siva,

    I'm a bit confused about why you'd not take that approach (defining the "optionList" as a control property with getter, setter methods), that's the best practice for defining control properties so that you can set it both in html markup (via "data-win-option" attribute) or programmtically in code. And if you read the following custom WinJS controls samples carefully, you'll find that they both use such approaches for defining custom properties. And that way, you will get your custom control work like those built-in WinJS controls.

    #Building a custom control using the Windows Library for JavaScript (WinJS)
    http://blogs.msdn.com/b/windowsappdev/archive/2012/10/11/building-a-custom-control-using-the-windows-library-for-javascript-winjs.aspx

    #Building and Using Controls in Windows Store Apps with JavaScript
    http://msdn.microsoft.com/en-us/magazine/jj721594.aspx

    And for the "winControl" property, it is initialized in the control constructor (you define it). And the WinJS.UI.ProcessAll will help find all controls in page .html file and call their constructors. So after that you can get the winControl property from the hosting html/dom element. And if you're using WinJS navigation page (Page Control), the navigation framework should have helped you called processAll, so you can just find the certain DOM element and access its "winControl" property.

    Anyway, I've modified your sample solution's code and add a test.html page to demonstrate how you can make your autocomplete control be intialized programmtically (instead of using "data-win-option" in .html markup) and update its property later in other event handlers.

    --- autocomplete.js(modified)---

    (function (WinJS) {
        WinJS.Namespace.define("MyApp.UI", {
            Autocomplete: WinJS.Class.define(function (element, options) {
                if (!element || element.tagName.toLowerCase() !== "input") throw "input type must be provided";
                options = options || {};
                this._setElement(element);
                this._element.winControl = this;
    
                WinJS.UI.setOptions(this, options);
    
            },
                {
    
                    //Private members
                    _datalistElement: null,
                    _element: null,
                    _optionList: null,
                    _setElement: function (element) {
                        this._element = element;
                    },
                    _setOptionList: function (optionList) {
                        optionList = optionList || [];
                        this._optionList = optionList;
                    },
                    _createDataList: function () {
                        
                        if(this._datalistElement){
                            document.body.removeChild(this._datalistElement);
                            this._datalistElement = null;
                        }
    
                        var dl = document.createElement('datalist');
                        dl.id = 'dl' + this._element.id; 
    
                        var i = 0,
                            len = this._optionList.length;
                            
                        this._element.setAttribute("list", dl.id);
                        for (; i < len; i += 1) {
                            var option = document.createElement('option');
                            option.value = this._optionList[i];
                            dl.appendChild(option);
                        }
    
                        this._datalistElement = dl;
                        document.body.appendChild(this._datalistElement);
                       
                    },
    
    
                    //Public members
                    optionList: {
                        get: function () {
                            return this._optionList || [];
                        },
                        set: function (list) {
                            this._optionList = list || [];
    
                            this._createDataList();
                        }
                    },
                    element: { 
                        get: function () {
                            
                            return this._element;
                        }
                    }
    
                })
        });
    }(WinJS));
    


    --- test.html ---

    <section aria-label="Main content" role="main">
                
                <p>Content goes here.</p>
                <input type="text" name="txtCities" id="txtCities" data-win-control="MyApp.UI.Autocomplete" />
                <button id="btnChangeOptions">Change Option List</button>
            </section>


    --- test.js ---

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/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.
    
    
                // Init the autocomplete control in code (instead of html markup)
                WinJS.UI.setOptions(
                    document.getElementById("txtCities").winControl,
                    { optionList: Data.cities }
                );
    
                // Wrap the button click handler for switching optionList of the autocomplete control
                document.getElementById("btnChangeOptions").addEventListener("click", function () {
    
                    var options = [];
                    var i = Math.floor((Math.random() *1000) % 4);
    
                    switch (i) {
                        case 0:
                            options = Data.cities1;
                            break;
                        case 1:
                            options = Data.cities2;
                            break;
                        case 2:
                            options = Data.cities3;
                            break;
                        default:
                            options = Data.cities;
                            break;
                    }
    
                    var acControl = document.getElementById("txtCities").winControl;
                    WinJS.UI.setOptions(acControl, { optionList: options });
    
                });
    
            },
    
            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.
            }
        });
    })();
    



    So by defining optionList as a property with getter & setter(in your control class) directly, you can use any of the following means to initialize or update it:

    1. use "data-win-option" in html markup
    2. use WinJS.UI.setOptions() in code
    3. use xxx.winControl.optionList = xxx to access the individual property directly

     

     

     

     

     

     

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, January 30, 2013 2:52 PM
    Moderator
  •  Hi Steven,

    Thanks again for your reply and your code snippet.

    i got some idea from your code. but i have some doubt, how can i specify or pass the options in same html page (i.e) with in the script tag. In you last response u did that in test.js file . but i want perform that in  same test.html file with in the script tag like below code.

    test.html file

    <section aria-label="Main content" role="main">
                
                <p>Content goes here.</p>
                <input type="text" name="txtCities" id="txtCities" data-win-control="MyApp.UI.Autocomplete" />
                <button id="btnChangeOptions">Change Option List</button>
            </section>

    <script type="text/javascript">

    ----------------------------------------

     WinJS.UI.setOptions(
                    document.getElementById("txtCities").winControl,
                    { optionList: Data.cities }
                );

    </script>

    Please check the below link .

    Componentone

    how they are doing this ? Any idea ?

    Thanks,



    siva

    Wednesday, January 30, 2013 5:37 PM
  • Thanks for your reply Siva,

    No, you should not put the WinJS control init code directly in html file's <script> tag because the code there is executed when the html page is loaded into app and it is not guaranteed to be executed at the right point (after the Page Control is initialized and all the necessary Control processing code is called). That's why I use a separate test.html page to show you the code and demonstrate that the "ready" event (of the Page Control) is the correct place to put initializing things (for WinJS controls on page such as assign properties, wrap event handlers ...) and in the "unload" event you can do some clean up works. You can put some helper/utility methods in the html inline <script> tags, but I'd recommend you always encapsulate them in .js file and reference them in page.

    Generally, just follow those samples and coding patterns since they demonstrate the recommended approach which works with the WinJS programming model. You can consider changing it or use your own one unless you completely understand how it works and what's the impact if you change it.

    The following book is recommened for programming windows store app with html5 + js. It explains many things about the app lifecycle and programming model:

    #Free ebook: Programming Windows 8 Apps with HTML, CSS, and JavaScript
    http://blogs.msdn.com/b/microsoft_press/archive/2012/10/29/free-ebook-programming-windows-8-apps-with-html-css-and-javascript.aspx


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, January 31, 2013 2:48 AM
    Moderator