Reputation: 2210
I'm generating Panels from view>categories, so the number of panels is not known. I therefore can't assign specific I'd's to them.
When I expand a panel, I need to close all the others, so how can I determine how the other panels are identified to close them?
I can't use byId, so is there a JQuery search I could use instead?
<List id="idList" items="{view>/categories}">
<items>
<CustomListItem>
<Panel expandable="true" expanded="false" headerText="{view>categoryDesc}" onExpand="onExpand">
Upvotes: 0
Views: 3108
Reputation: 20852
@SergeiVavilov deserves the credit for pointing me in the right direction.
Here is an updated version of his accordion solution with full working code, that interlocks the expanded state of multiple panels and in addition makes the panel headers clickable too. This makes the accordion handling more intuitive.
Plunker demo:
https://embed.plnkr.co/TXXLm12UvlMKYm7biaWQ/
View:
<mvc:View xmlns="sap.m" xmlns:f="sap.f" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" controllerName="demo.controller.Home" displayBlock="true" async="true">
<Page id="homePage" title="Home">
<List id="idList" items="{accordion>/accodata}">
<items>
<CustomListItem>
<Panel expandable="true" expanded="{accordion>expanded}" expand="onPanelExpand">
<headerToolbar>
<Toolbar active="true" press="onPanelToolbar">
<content>
<Text text="{accordion>title}" />
</content>
</Toolbar>
</headerToolbar>
<content>
<Text text="{accordion>content}" />
</content>
</Panel>
</CustomListItem>
</items>
</List>
</Page>
</mvc:View>
Controller:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("demo.controller.Home", {
onInit: function() {
var oMyModel = new sap.ui.model.json.JSONModel({
accodata: [{
expanded: false,
title: 'Title A',
content: 'Content AAA'
}, {
expanded: true,
title: 'Title B (expanded on init)',
content: 'Content BBB'
}, {
expanded: false,
title: 'Title C',
content: 'Content CCC'
}, {
expanded: false,
title: 'Title D',
content: 'Content DDD'
}]
}
);
this.getView().setModel(oMyModel, "accordion");
},
onPanelExpand: function(oEvent) {
if (oEvent.getParameters().expand) {
var oModel = this.getView().getModel("accordion");
var aPath = oEvent.getSource().getBindingContext("accordion").getPath().split("/");
var selectedIndex = +aPath[aPath.length - 1];
var aAccordion = oModel.getProperty("/accodata");
for (var i = 0; i < aAccordion.length; i++) {
if (i !== selectedIndex) {
aAccordion[i].expanded = false;
}
}
oModel.updateBindings();
}
},
onPanelToolbar: function(oEvent) {
var oPanel = oEvent.getSource().getParent();
oPanel.setExpanded(!oPanel.getExpanded());
}
});
});
Upvotes: 0
Reputation: 393
I would do it via binding (add another property "expanded") to the category, something like that:
view:
<List id="idList" items="{view>/categories}">
<items>
<CustomListItem>
<Panel expandable="true" expanded="{view>expanded}" headerText="{view>categoryDesc}" expand="onExpand" />
controller:
onExpand: function(oEvent) {
if (oEvent.getParameters().expand) {
var oModel = this.getView().getModel("view");
var aPath = oEvent.getSource().getBindingContext("view").getPath().split("/");
var selectedIndex = +aPath[aPath.length - 1];
var aCategories = oModel.getProperty("/categories");
for (var i = 0; i < aCategories.length; i++) {
if (i !== selectedIndex) {
aCategories[i].expanded = false;
}
}
oModel.updateBindings();
}
},
and don't forget to initialize "expanded" property...
Upvotes: 3