0

Dynamic loop button generation is always getting last event

Hi guys,

So i am playing with connectedtv, I have been able to generate a list of button based on a xml list, but I have a problem passing values to the select event view.

In the example below when I do this : KONtx.application.loadView('view-Sub2', { text:description.substr(1) });

it is always the last (always the same) description that appear in all the items

I suppose this has to do with how I create the buttons?

This make no sens to me, the listing is displaying fine, the description stored with the button object should be the one I created dynamically


CODE
	for(x=1;x<10;x++){
var title = myXML.evaluate( "string(rss/channel/item["+x+"]/title)" );
var description = myXML.evaluate( "string(rss/channel/item["+x+"]/description)" );
var offsetMove = 35*x;
var guidText = "news"+x;
this.controls = new KONtx.control.TextButton({
label: title.substr(1),
guid: guidText,
events: {
onSelect: function(event) {
KONtx.application.loadView('view-Sub2', { text:description.substr(1) });
}
},
styles: {
fontSize: KONtx.utility.scale(2),
width: Theme.viewSpecs.SIDE_BAR.width,
height: KONtx.utility.scale(35),
vOffset: KONtx.utility.scale(offsetMove),
}
}).appendTo(this);
}

by
11 Replies
  • The approach is good, but there are a few errors.

    -> You are not uniquely declaring your buttons in the "this.controls" object.
    -> I would suggest passing all the information you need to the button event needed in the next view. That way you do not need to go grab it when displaying the "view-sub2"

    Taking a look at the unique button elements in the controls object issue:
    CODE
    //You have
    this.controls = new KONtx.control.TextButton({}).appendTo(this);

    //Should be
    this.controls["button"+x] = new KONtx.control.TextButton({}).appendTo(this);


    Explanation: While looping through you are adding 10 buttons that are all linked together under the "this.controls" object. So when you reach the 10th item and set the this.controls.title, it is setting all the other buttons to the same value.

    Next is the passing the information into the event for the button
    CODE
    //You have
    KONtx.application.loadView('view-Sub2', { text:description.substr(1) });

    //New Loop Segment
    for(x=1;x<10;x++){
    //Put all your information into one object.
    var info = {title: myXML.evaluate( "string(rss/channel/item["+x+"]/title)" ), description: myXML.evaluate( "string(rss/channel/item["+x+"]/description)" ) };
    var offsetMove = 35*x;
    var guidText = "news"+x;

    //Set up each button as an object inside this.controls
    //Accesible by using this.controls.button1 and/or this.controls['button1']
    this.controls["button"+x] = new KONtx.control.TextButton({
    label: info.title.substr(1),
    guid: guidText,
    events: {
    onSelect: function(event) {
    //Wjhen the button is clicked it is using the information we attached below
    KONtx.application.loadView('view-Sub2', this.info);
    }
    },
    styles: {
    fontSize: KONtx.utility.scale(2),
    width: Theme.viewSpecs.SIDE_BAR.width,
    height: KONtx.utility.scale(35),
    vOffset: KONtx.utility.scale(offsetMove),
    }
    }).appendTo(this);
    //Attach the RSS Information before we move on -> Need this later in the button event
    this.controls["button"+x].info = info;
    }


    Explanation: By attaching the information to the button object, you are able to access the info through the event by referencing with "this.info". Also, you will now be able to grab all the RSS information you need in the next "sub-view2" by using "this.persist.info" by adding it to the "info" object in the loop. this.persist.info.title, this.persist.info.description, etc

    Also, might want to look at a Grid for running out list of buttons like this. You can customize the appearance and their is built in controls for fillping through pages of the list information.
    0
  • This make sense,

    I thought I couldn't define controls this way so I didn't bother trying to add a dynamic definition to it.

    I have no Idea how works the grid, but I will look at the doc, sounds like it is what I need in most case.

    Thank you for your help, this really help me out creating a small prototype.
    0
  • Excellent reply WidgetRealm!

    Thanks Brian!

    -Jeremy
    0
  • Thank you.

    Now I just need some replies to my email(s). :P
    0
  • Thank you! The controls[] trick answered one of the questions I meant to ask, although I am still stuck with the way I should handle events in my dynamically generated buttons. In a nutshell, I (now) have:

    CODEBOX
                for (item in result) {
    var info = result[item].title;
    view.controls["playlists" + item] = new KONtx.control.TextButton({
    title: result[item].title,
    label: result[item].title,
    guid: "playlist" + result[item].id,
    events: {
    onSelect: function(event) {
    log("Selected: " + this.info);
    }
    },
    });
    }


    Only to find out that this.info (as well as this.title, and any other stuff I could possibly think of) is undefined: as I need to have some information on which button was ckicked, I am pretty much stuck.

    I'm sure I'm doing something very stupid here, but the documentation has not been exactly helpful. Can I get a good slap on the wrist and a pointer to what I am doing wrong? Thanks in advance!
    0
  • It just needs to added to the button after it is created.
    CODE
                for (item in result) {
    var info = result[item].title;
    view.controls["playlists" + item] = new KONtx.control.TextButton({
    title: result[item].title,
    label: result[item].title,
    guid: "playlist" + result[item].id,
    events: {
    onSelect: function(event) {
    log("Selected: " + this.info);
    }
    },
    view.controls["playlists" + item].info = info; //You can not access it via this.info in your event
    });
    }

    Hope this helps.
    0
  • It just needs to be added to the button after it is created.
    CODE
                for (item in result) {
    var info = result[item].title;
    view.controls["playlists" + item] = new KONtx.control.TextButton({
    title: result[item].title,
    label: result[item].title,
    guid: "playlist" + result[item].id,
    events: {
    onSelect: function(event) {
    log("Selected: " + this.info);
    }
    },
    view.controls["playlists" + item].info = info; //You can now access it via this.info in your event
    });
    }

    Hope this helps.

    [RANT]These are worst forums I have every seen.... Why cannot you not edit a post your have put up?[/RANT]
    0
  • QUOTE (WidgetRealm @ Feb 1 2010, 08:03 AM) <{POST_SNAPBACK}>
    It just needs to be added to the button after it is created.


    You're a star! Thanks a ton - I was starting to bang my head against the wall. I owe you one.

    (oh, and just for the record, you had a minor mistake in your fix - my working version reads as follows:)

    CODEBOX
                for (item in result) {
    var info = result[item].title;
    view.controls["playlists" + item] = new KONtx.control.TextButton({
    title: result[item].title,
    label: result[item].title,
    guid: "playlist" + result[item].id,
    events: {
    onSelect: function(event) {
    log("Selected: " + this.info);
    }
    },
    });
    view.controls["playlists" + item].info = info; //You can now access it via this.info in your event
    }
    0
  • You are correct! Good catch. I am glad it worked for you.

    We have some great tools coming out for TV Widget Developers. We will be posting up some information soon!
    0
  • QUOTE (WidgetRealm @ Feb 1 2010, 08:48 AM) <{POST_SNAPBACK}>
    You are correct! Good catch. I am glad it worked for you.

    We have some great tools coming out for TV Widget Developers. We will be posting up some information soon!


    Give me an easy way to do unit tests, and I'll buy the team a couple of rounds!
    0
  • shoot an email to tvwidgets@widgetrealm.com :)
    0

Recent Posts

in General - Yahoo! TV Widgets