Search code examples
webosenyo

Flyweight VirtualRepeater containing IntegerPicker


In my Enyo app, I have a VirtualRepeater which produces Controls containing various text displays and an IntegerPicker.

I have two problems with this repeater:

1) If three rows are produced, clicking on the IntegerPicker in rows 1 and 2 brings up the drop-down picker UI over the top of the IntegerPicker in row 0.

2) I initialise each IntegerPicker with a max value using setMax(). However, if three rows are produced, the IntegerPickers in rows 0 and 1 will have the same max value as that in row 2.

It looks as if only one IntegerPicker is being created and is being used on the first row.

I tried replacing my VirtualRepeater with a Repeater, and changed my repeater row creation function to return a new instance of the item containing the IntegerPicker, instead of returning true. However this produces the error:

warning: enyo.Component.addComponent(): Duplicate component name "itemName" violates unique-name-under-owner rule, replacing existing component in the hash and continuing, but this is an error condition and should be fixed.

It seems that Repeaters need their delegates created inline, which seems quite inelegant.

This code sample illustrates the problem:

enyo.kind({
   name:"Test",
   kind:enyo.Control,
   components: [
      {
         kind: "VirtualRepeater",
         onSetupRow: "setupRow",
         components: [{
                name: "theIP", kind: "IntegerPicker", min:0
         }]
      }
   ],

   setupRow: function(inSender, inIndex) {
      if (inIndex < 3) {
         this.$.theIP.setMax(inIndex);
         return true;
      }
      return false;
   }
});

How can I create an arbitrary number of IntegerPickers in my app? Any help appreciated!


Solution

  • What you are doing with theIP in your setupRow function is accessing a specific IntegerPicker itself, which is a child component of the Virtual Repeater. To set the max value of a given IntegerPicker corresponding to the row, give your VirtualRepeater a name attribute, like "PickerList":

     kind: "VirtualRepeater",
     onSetupRow: "setupRow",
     name: "PickerList",
     components:[//this should be empty to begin with]
    

    Then you can access each row in the repeater like this:

    setupRow: function(inSender, pickerMax) {
    
       var newPicker = new IntegerPicker(pickerMax);
       this.$.PickerList.push(newPicker);
    

    To get a specific row in the VirtualRepeater you need to do it like this:

    this.$.PickerList[1];
    

    Here is an extended Enyo tutorial which makes use of the VirtualRepeater: https://developer.palm.com/content/resources/develop/extended_enyo_tutorial.html