How to make the application layout control dynamic in Xpages - xpages

I have been working on making the applicationLayout Custom Control more dynamic, so I can more build and extend Xpages apps more easily.
To that end I am now using the switch facet, which helps immensely.
I also want to soft code the Application Links, Title Links, and Navigation Entries.
I think I can build a data structure in which I just put the values I want and the majority of the app layout is loaded from this.
So I will have an array of appliances in a scope variable, like so:
“App 1”, “App 2”,”App 3” etc.
Then for the Title’s I will have to have something like this:
“App 1”,”Title Bar 1”,”Title Bar 2”,”Title Bar 3”,
“App 2”,”Title Bar 1”,”Title Bar 2”,”Title Bar 3”,”Title Bar 4"
“App 2”,”Title Bar 1”,
So the first Application Link will three title bars, the second 4, etc.
Then for the nav:
“App 1”,”Title Bar 1”,”Nav 1,”Nav 2"
“App 1”,”Title Bar 1”,”Nav 1,”Nav 2”,”Nav 3"
and so on.
If I do this then it will be very easy I think to layout an app.
My question is what data structure is best to use? And should I use three arrays or on 3-dimensial array?
===================================================================
Knut's answer is great, but I cannot seem to loop through the array.
var lenArr:Integer = sessionScope.apps.length;
for (i=0; i < lenArr;++i)
{sessionScope.apps[i].app}
When I do a length on the session.Scope variable it returns a 3, but when I loop through the array it returns null when i=2. There are only 2 items in my array, at least there should be. Here is my code for the sessionScope.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core"
rendered="false"
viewState="nostate"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.afterPageLoad><![CDATA[#{javascript:sessionScope.apps =
[
{ app: "xpApp1",
titleBars: [
{titleBar: "ccApp1Title1",
navs: ["ccNavApp11Title1Nav1"]
},
{titleBar: "ccApp1Title1",
navs: ["ccNavApp11Title1Nav2"]
}
]
},
{ app: "xpApp2",
titleBars: [
{titleBar: "ccApp2Title1",
navs: ["ccNavApp21Title1Nav1"]
},
{titleBar: "ccApp2Title2",
navs: ["ccNavApp21Title2Nav1"]
}
{titleBar: "ccApp2Title3",
navs: ["ccNavApp21Title3Nav1"]
}
]
},
];
//Now set the selected values
sessionScope.appSelected = "xpApp1";
sessionScope.titleSelected = "ccApp1Title1";
sessionScope.navSelected = "ccNavApp11Title1Nav1";
var uAgent = context.getUserAgent().getUserAgent();
if((uAgent.match("iPhone") !== null || param.platform=="iphone") ||
(uAgent.match("Android") !== null || param.platform=="android") ||
uAgent.match("iPad") !== null){
context.redirectToPage("/mobile.xsp", true);
}else{
context.redirectToPage("/xpApp1.xsp", true);
} }]]></xp:this.afterPageLoad>
</xp:view>
What am I doing wrong?

Use JavaScript's arrays and objects to define your application structure
sessionScope.apps =
[
{ app: "App 1",
titleBars: [
{titleBar: "Title Bar 1",
navs: ["Nav 1", "Nav 2", "Nav 3"]
},
{titleBar: "Title Bar 2",
navs: ["Nav 4", "Nav 5", "Nav 6"]
}
]
},
{ app: "App 2",
titleBars: [
{titleBar: "Title Bar 3",
navs: ["Nav 31", "Nav 32", "Nav 33"]
},
{titleBar: "Title Bar 4",
navs: ["Nav 41", "Nav 42"]
}
]
}
];
You can access the first app with
sessionScope.apps[0].app
the first app's first titleBar with
sessionScope.apps[0].titleBars[0].titleBar
and first app's first titleBar's second nav with
sessionScope.apps[0].titleBars[0].navs[1]
Use a for loop or forEach to get all elements of an array.

Related

Select data binding in SAPU15

I read the documentation https://sapui5.hana.ondemand.com/#/api/sap.m.Select and tried to do a small example. I created my value in my function onInit of my controller:
var oData = {
"SelectedProduct": "test1",
"ProductCollection": [
{
"ProductId": "test1",
"Name": "test 1"
},
{
"ProductId": "test2",
"Name": "test 2"
},
{
"ProductId": "test3",
"Name": "test 3"
}
]
};
var oModel = new JSONModel(oData);
this.getView().setModel(oModel, "myTest");
I want that my selectedProduct default value is test1 so I init it to test1.
In my xml file, i created my selector as following:
<Select
id="idSelect"
forceSelection="false"
selectedKey="{myTest>/SelectedProduct}"
change="_change"
items="{
path: 'myTest>/ProductCollection'
}">
<core:Item key="{myTest>/SelectedProduct}" text="{myTest>Name}" />
</Select>
So, everytime i change the value, my following code is made:
_change: function () {
console.log("_changeAblauf");
console.log(this.getView().byId("idAblaufbriefeSelect").getSelectedItem());
console.log(this.getView().byId("idAblaufbriefeSelect").getName());
},
My issue is that the print always display the content of my SelectedProduct from oData and not from the selector..
Why it don't take the value from the selector and how can i read my new value of the selector ?
In the key property of the Item you should bind myTest>ProductId: this value will populate your model SelectedProduct property every time the change event will be fired.

Tabulator - rowContextMenu - HowTo get which cell the mouse-rightclick is performed

Is it possible to get which cell the right-click context menu is performed with rowContextMenu?
rowContextMenu gives the data for all cells in the row, but I have not found how to get which cell the action happens.
Using contextMenu could be an option, but I want to build the columns-setup serverside as json and load the columns with
table.setColumns(columnsJson)
Setting columns contextmenu as a function is not a valid json,
columns": [
{ "title": "", "field": "age", "sorter": "string", "headerSort": false, "contextMenu": cellContextMenu}
]
And setting the "contextMenu" as a "string" fails with: error: "Uncaught TypeError: o.forEach is not a function"
columns": [
{ "title": "", "field": "age", "sorter": "string", "headerSort": false, "contextMenu": "cellContextMenu"}
]
Any tips on getting which cell the menu is trigged with rowContextMenu?
Or is there maybe a different/better solution builtin in Tabulator?
Reason for building the column setup serverside is that I want to have different context menu based on type of cell-data, and it will vary based on selection by user.
BR
Bjorn
If you want to get the cell that is being clicked on then you need to use the Cell Context Menu instead as this is passed the cell component that has been clicked.
You would then need to assign the menu per cell but this is easy if you define it as an array outside the table and then reference it on each column definition using the contextMenu property:
//define cell context menu
var cellContextMenu = [
{
label:"Reset Value",
action:function(e, cell){
cell.setValue("");
}
},
]
//add header menu in column definition
var table = new Tabulator("#example-table", {
columns:[
{title:"Name", field:"name",contextMenu:cellContextMenu},
{title:"Age", field:"age",contextMenu:cellContextMenu},
{title:"Address", field:"address",contextMenu:cellContextMenu},
]
});

Why is Tabulator textarea losing focus on every key press?

I have a simple Tablulator JS Fiddle at the link below that has 3 columns. The last column (TA Test) has both the formatter and editor set to 'textarea'. Any attempt to enter values into that field result in the cell immediately losing focus on any key press (at least I think that is what is happening). There are no console or other errors and from what I can tell all the Tabulator options are correct.
What am I missing here to make this cell editable as a textarea?
https://jsfiddle.net/gbvam5ck/2
var data = [
{
pid: 1001,
title: "Test One",
Q1: {qid: 1, value: 1},
Q2: {qid: 2, value: null},
},
{
pid: 1002,
title: "Test Two",
Q1: {qid: 1, value: 0},
Q2: {qid: 2, value: "Hello"},
},
];
var columns = [
{title: "PID", field: "pid"},
{title: "Title", field: "title"},
{title: "TA Test", field: "Q2.value",
formatter:"textarea",
editor: "textarea",
editorParams:{
elementAttributes:{
maxlength:"500",
}
},
}
];
var table = new Tabulator("#example-table", {
index:"pid",
height: "100%",
layout: "fitData",
columns,
data: data,
});
It looks to be a bug using the textarea with the table height option set to a percentage. If you use a pixel value, then it works as expected.
I would recommend you fill out a bug report against the github project. https://github.com/olifolkerd/tabulator/issues/new?assignees=&labels=Possible+Bug&template=bug_report.md&title=
The bug report template shows you what information is needed for the bug to be easy to replicate and fix.
(If you don't have a Github account, then I can create the bug report.)

lit-element update individual child properties efficently

I have the following components
my-app: contains a layout-toolbar and a layout-container
layout-container: contains one or more layout-pages
layout-page: contains one or more layout-elements
layout-element: component to visualize certain data, f.e. a styled numeric label.
The layout-container has an options property that is bound to the apps layoutContainerOptions property like this:
<layout-container .options="${this.layoutContainerOptions}"></layout-container>
layoutContainerOptions is initialized like this:
this.layoutContainerOptions = {
name: "Project 1",
pages: [
{
name: "Page 1",
elements: [
{
name: "Element 1",
color: "red"
},
{
name: "Element 2",
color: "yellow"
}
]
},
{
name: "Page 2",
elements: [
...
]
}
]
}
This correctly renders a layout with two pages and some elements. Now the user should be able to use the toolbar to interactively edit selected elements, f.e. to change the color of an element. How do I propagate a property change to a selected child element?
I could use something like
this.layoutContainerOptions.pages[0].elements[0].color = "blue";
this.layoutContainerOptions = Object.assign({}, layoutContainerOptions, { });
This works but seems to be very inefficient because there may be hundreds of elements which all get re-rendered (or don't they?)
What is the most efficient way to update properties of individual child elements?

get values of select option in angular 4+

Hi I have a question how to get the values from list in a select option.
I have this array
{
"C_ID": "Item044",
"Descripcion": "Item 1",
"ID": "044"
},
{
"C_ID": "Item045",
"Descripcion": "Item 2 ,
"ID": "045"
},
{
"C_ID": "Item046",
"Descripcion": "Item 4",
"ID": "046"
},
{
"C_ID": "Item047",
"Descripcion": "Item 5",
"ID": "047"
},
and I get this values in a select option with NgFor but I need when selected for example Item 1 get the ID and C_ID in a input text automatic
and I get this values in a select option with NgFor but I need when selected for example Item 1 get the ID and C_ID in a input text automatic
Wire an ng model to the select input. And then wire the backed field to the input. Now when the select changes the input text should change.

Resources