Navigate in hide panels

Hi,

I'm a newbie and i'm testing the framework enyo/moonstone an in my example i have a moon.panels with 4 moon.panel.

The moon.panel with index 3 is hide "this.$.panels.getPanels()[2].hide();" and my expectation would be not navigate for this panel.

The navigation expectable for me would be .fromindex=0 -> .toindex=1, .fromindex=1 -> .toindex=2 .fromindex=2 -> .toindex=4, but the panel hidden are "spotlighted", and the transition is .fromindex=2 -> .toindex=3.

What have best approach to implementation the navigation only in panels "show/visible".

Comments

  • Hi @vem_castro, can you share how you are navigating to the "next" panel in your code? Are you just calling next on the panels control?
  • Thanks aarontam.


    Explicitly in the code I'm not invoke the next. What I'm doing just use the behavior navigation default of moonstone / spotlight.

    My expectation was that a hidden panel did not get focus, and that focus it was assigned to the next visible panel. When step 2 of the panel to the panel 3 the focus is lost, thus losing the visual navigation.

    What wanted to do was navigate only on visible panels, can help me on the best approach to do?

    enyo.kind({
    name: "test",
    kind: "moon.Panels",
    pattern: "activity",
    classes: "moon enyo-fit enyo-unselectable",

    published: {
    panel1Collection: null,
    panel2Collection: null,
    panel3Collection: null,
    panel4Collection: null,
    },
    components: [
    {name: "globalPanel", kind: "moon.Panels", classes: "enyo-fill moon-16h", arrangerKind: "CarouselArranger", fit: true,

    components: [
    {kind: "moon.Panel", name: "panel1", classes: "moon main-panel",
    components: [{
    name: "DatalistPanel1", kind: "moon.DataList",
    components: [
    {components: [
    {kind: "moon.Item", name: "menuitem"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.menuitem.content"},
    {from: ".model.id", to: ".$.menuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel2", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel2", kind: "moon.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel3", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel3", kind: "moon.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel4", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel4", kind: "enyo.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    ]
    }
    ],
    bindings: [
    {from: ".panel1Collection", to: ".$.DatalistPanel1.collection"},
    {from: ".panel2Collection", to: ".$.DatalistPanel2.collection"},
    {from: ".panel3Collection", to: ".$.DatalistPanel3.collection"},
    {from: ".panel4Collection", to: ".$.DatalistPanel4.collection"},
    ],

    create: function() {
    this.inherited(arguments);
    this.panel1Collection = new enyo.Collection();
    this.panel2Collection = new enyo.Collection();
    this.panel3Collection = new enyo.Collection();
    this.panel4Collection = new enyo.Collection();
    this.$.panel3.hide();
    this.fetchMainMenu();

    },

    fetchMainMenu: function() {
    var records=[];
    for (var i = 0; i < 2; i++) {
    records[i] = new enyo.Model({id: i, text: "Item " + i});
    }
    this.panel1Collection.add(records);

    var records1=[];
    for (var i = 0; i < 3; i++) {
    records1[i] = new enyo.Model({id: i, text: "Item submenu " + i});
    }
    this.panel2Collection.add(records1);
    this.panel3Collection.add(records1);
    this.panel4Collection.add(records1);
    },
    });

  • My approach was to overrides the next, and then go through all the panels, looking for the next visible.

    However, I have a problem if the panel hidden was the last panel the navigation is made, wrong for what I want.

    next: function () {
    var nextIndex = this.index+1;
    if (this.wrap && nextIndex >= this.getPanels().length) {
    nextIndex = 0;
    }

    for (var i=nextIndex; i < this.getPanels().length; i++){
    if (this.getPanels()[i].showing){
    nextIndex = i;
    break;
    }
    }

    this.setIndex(nextIndex);
    },
  • edited December 2015
    Hi @vem_castro, what do you want to happen if the last panel is hidden, and the user presses 5-way right? Should there be no navigation? In any case, to prevent the navigation, you can do something like this (refactored your next method a little bit, was trying to avoid completely overriding the built-in next, but that may not be possible if we want to preserve the wrapping feature):

    next: function () {
    var panels = this.getPanels(),
    len = panels.length,
    nextIndex = -1,
    startIndex = this.index + 1;

    if (this.wrap && startIndex >= len) {
    startIndex = 0;
    }

    for (var i = startIndex; i < len; i++){
    if (panels[i].get('showing')) {
    nextIndex = i;
    break;
    }
    }

    if (nextIndex > -1) this.setIndex(nextIndex);
    }
    I did notice Spotlight still disappears in this scenario as the container has already processed the event, which leads me to...

    Taking a step back, what is the scenario where you need to hide panels? I'm curious if there is a more ideal solution to what you are trying to accomplish, if we can understand the context.
  • Thanks aarontam for your help.

    My scenario is have the initial panel with options and depending de selected option show/hide the other panels.

    My final objective is navigate only in panels shows. Your refactored code to next, works fine, with exception, if the last panel is hide, its possible to navigate for him, i pretending if navigate 5-way right, staying in same panel for this specific case.

  • Hi @vem_castro, when these options are set in the initial panel, will you need to potentially change them again, later? If not, it might be easier to determine which panels need to be shown/hidden after the options are set, and then remove (rather than hide) the unnecessary panels, to allow for the logical ordering of the panels to be used. If this is not the case, you will probably need to override the handlers for the onSpotlightLeft and onSpotlightRight events, in addition to next and previous. I have written up how something like that might look like (I created a custom kind that subkinds moon.Panels) - it is not really recommended as it is somewhat hacky to overwrite event handlers which are private, but I tried to overwrite as little as possible of the original code, for future compatibility. I also made separate methods for the next/previous valid index computation, for clarity, so this clearly can be further optimized/tweaked:

    enyo.kind({
    name: 'GlobalPanels',
    kind: 'moon.Panels',
    spotlightLeft: function (sender, ev) {
    var index = this.computePrevValidIndex();
    if (index > -1) this.inherited(arguments);
    },
    spotlightRight: function (sender, ev) {
    var index = this.computeNextValidIndex();
    if (index > -1) this.inherited(arguments);
    },
    previous: function () {
    var prevIndex = this.prevValidIndex;
    if (prevIndex > -1) this.setIndex(prevIndex);
    },
    next: function () {
    var nextIndex = this.nextValidIndex;
    if (nextIndex > -1) this.setIndex(nextIndex);
    },
    computeNextValidIndex: function () {
    var panels = this.getPanels(),
    len = panels.length,
    nextIndex = -1,
    startIndex = this.index + 1,
    i;

    if (this.wrap && startIndex >= len) {
    startIndex = 0;
    }

    for (i = startIndex; i < len; i++){
    if (panels[i].get('showing')) {
    nextIndex = i;
    break;
    }
    }

    this.nextValidIndex = nextIndex;
    return nextIndex;
    },
    computePrevValidIndex: function () {
    var panels = this.getPanels(),
    len = panels.length,
    prevIndex = -1,
    startIndex = this.index -1,
    i;

    if (this.wrap && startIndex < 0) {
    startIndex = len - 1;
    }

    for (i = startIndex; i >= 0; i--){
    if (panels[i].get('showing')) {
    prevIndex = i;
    break;
    }
    }

    this.prevValidIndex = prevIndex;
    return prevIndex;
    }
    });

    enyo.kind({
    name: "myapp.MainView",
    kind: "moon.Panels",
    pattern: "activity",
    classes: "moon enyo-fit enyo-unselectable",

    published: {
    panel1Collection: null,
    panel2Collection: null,
    panel3Collection: null,
    panel4Collection: null,
    },
    components: [
    {name: "globalPanel", kind: "GlobalPanels", classes: "enyo-fill moon-16h", arrangerKind: "CarouselArranger", fit: true,

    components: [
    {kind: "moon.Panel", name: "panel1", classes: "moon main-panel",
    components: [{
    name: "DatalistPanel1", kind: "moon.DataList",
    components: [
    {components: [
    {kind: "moon.Item", name: "menuitem"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.menuitem.content"},
    {from: ".model.id", to: ".$.menuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel2", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel2", kind: "moon.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel3", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel3", kind: "moon.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    {kind: "moon.Panel", name: "panel4", classes: "main-panel moon", joinToPrev: true,
    components: [{
    name: "DatalistPanel4", kind: "moon.DataList",
    components: [
    {components: [
    {name: "submenuitem", kind: "moon.Item"}
    ],
    bindings: [
    {from: ".model.text", to: ".$.submenuitem.content"},
    {from: ".model.id", to: ".$.submenuitem.idMenu"},
    ],
    }],
    }]
    },
    ]
    }
    ],
    bindings: [
    {from: ".panel1Collection", to: ".$.DatalistPanel1.collection"},
    {from: ".panel2Collection", to: ".$.DatalistPanel2.collection"},
    {from: ".panel3Collection", to: ".$.DatalistPanel3.collection"},
    {from: ".panel4Collection", to: ".$.DatalistPanel4.collection"},
    ],

    create: function() {
    this.inherited(arguments);
    this.panel1Collection = new enyo.Collection();
    this.panel2Collection = new enyo.Collection();
    this.panel3Collection = new enyo.Collection();
    this.panel4Collection = new enyo.Collection();
    this.$.panel3.hide();
    this.fetchMainMenu();

    },

    fetchMainMenu: function() {
    var records=[];
    for (var i = 0; i < 2; i++) {
    records[i] = new enyo.Model({id: i, text: "Item " + i});
    }
    this.panel1Collection.add(records);

    var records1=[];
    for (var i = 0; i < 3; i++) {
    records1[i] = new enyo.Model({id: i, text: "Item submenu " + i});
    }
    this.panel2Collection.add(records1);
    this.panel3Collection.add(records1);
    this.panel4Collection.add(records1);
    },
    });
Sign In or Register to comment.