As the Table is now registered to the Engine
and the SelectionController
is assigned, you can start to enable the selection by adding the required state handling so that the SelectionController
can show the proper state to the user.
To be able to implement the desired behavior for personalization changes, the Engine
provides the stateChange
event. The event has the target control and the personalization state as parameters. To reflect the personalization changes on registered control instances, you need to attach to the according event in the P13nTable#_initP13n
method as follows:
P13nTable.prototype._initP13n = function () {
var aColumnsMetadata = [];
this.getColumns().forEach(function (oColumn, iIndex) {
aColumnsMetadata.push({
key: oColumn.getId(),
label: oColumn.getHeader().getText(),
path: this.getItems()[0].getCells()[iIndex].getBinding("text").getPath()
});
}.bind(this))
this.oHelper = new MetadataHelper(aColumnsMetadata)
Engine.register(this, {
helper: this.oHelper,
modification: new ModificationHandler(),
controller: {
Columns: new SelectionController({
control: this,
targetAggregation: "columns"
})
}
});
Engine.attachStateChange(function (oEvt) {
if (oEvt.getParameter("control") === this) {
this.onStateChange(oEvt.getParameter("state"));
}
}.bind(this));
};
Afterwards add the P13nTable#onStateChange
method. For now, just use a console log using JSON#stringify
to take a look at the state object and how it is retrieved by the Engine
.
P13nTable.prototype.onStateChange = function(oState) {
console.log(JSON.stringify(oState, null, 2));
};
Once you restart the application, use F12
to open the debugger. Switch to the console
tab of your browser. The state handling has been executed once and when you open the dialog and make changes, you can see how the SelectionController
reports the state. You can also try to open the dialog, deselect an entry, and reselect it again. If you now close the Popup, you notice that no state change event has been fired. One of the central functionalties of the SelectionController
is the state handling and detection of changes. This way, the Engine
and SelectionController
ensure, that events are only triggered when necessary changes have occured. The object looks similar to the following:
{
"Columns": [
{
"key": "container-ui5con.p13nApp---Mountains--countries"
},
{
"key": "container-ui5con.p13nApp---Mountains--coordinates"
},
{
"key": "container-ui5con.p13nApp---Mountains--name"
},
{
"key": "container-ui5con.p13nApp---Mountains--height"
},
{
"key": "container-ui5con.p13nApp---Mountains--first_ascent"
}
]
}
On the root level of the object you can again find the name you chose for the registration of the SelectionController
.
It refers to an array, containing objects for each entry of the registered SelectionController
, using the keys you defined in the MetadataHelper
. The order in the array reflects the same position as in the dialog and only selected entries are returned in this state.
Now that you understand the stateChange
event, add some customized handling for toggling the visibility of the columns. In addition, you want to reorder the columns and table items according to the selection state. Therefore replace the log method in the P13nTable#onStateChange
:
P13nTable.prototype.onStateChange = function(oState) {
this.getColumns().forEach(function(oColumn) {
// if the column is not in the state, it is not visible
oColumn.setVisible(!!oState.Columns.find(function(oStateItem) {
return oColumn.getId() === oStateItem.key;
}));
});
oState.Columns.forEach(this._moveColum, this);
};
P13nTable.prototype._moveColum = function(oStateColumn, iIndex) {
var oCol = sap.ui.getCore().byId(oStateColumn.key);
var iOldIndex = this.getColumns().indexOf(oCol);
if(iIndex != iOldIndex) {
this.removeColumn(oCol);
this.insertColumn(oCol, iIndex);
var fnMoveCells = function(oItem) {
if (oItem.isA("sap.m.ColumnListItem")) {
var oCell = oItem.removeCell(iOldIndex);
oItem.insertCell(oCell, iIndex);
}
};
fnMoveCells(this.getBindingInfo("items").template)
this.getItems().forEach(fnMoveCells);
}
};
Note: This is just an example implementation of how this event may be used. You can decide, depending on the requirements, how you would like to react on the state changes done.
The user is now able to add, remove and reorder columns using the button in the upper right corner of the application. Check out the example and adapt some personalization settings. You can observe, that the changes in the dialog are automatically reflected on the UI. If you are happy with the result, please proceed with Exercise 5.