I have a small issue. I want to add two controls(TextView and Button) in a single table column. I have tried concatenation, array type to pass two controls into template but failed. Anyone please help me to solve this.
this is my sample table.
You can create more complex column templates like this:
var nameColumnTemplate = new sap.ui.layout.HorizontalLayout({
content : [new sap.ui.commons.Button({text : "Click"}), new sap.ui.commons.TextView({text : "{lastName}"})]
});
tbl.addColumn(new sap.ui.table.Column({
label: "Last Name",
template: nameColumnTemplate
}));
JSBin example.
Related
Very recently a new type of column was add to smartsheet : multi drop down :
Is there any solution to create such column using the api ?
Is a new version of the api planned ?
As of Oct 1, you can actually create a column that supports the new multi-dropdown feature. The documentation is a little behind.
If you don't yet have a column, you'll have to Add a column first.
Once you have a columnId, you can send an Update Column request and specify "type" as "MULTI_PICKLIST".
To retrieve the correct type when you do a GET /sheets/{sheetId} or GET /{columnId}, you have to use a query parameter of ?level=3&include=objectValue.
It is possible to create a Dropdown (multi select) column via the API!
To briefly address the TEXT_NUMBER issue, this type is used for backwards-compatibility. If you are unaware of the ?level=2&include=objectValue suffix, the response will return a TEXT_NUMBER column type to avoid breaking any existing clients that aren't set up to handle the new column type.
In the following examples the double brace variables represent your targets:
{{environment}} is something like https://api.smartsheet.com/2.0/
{{sheetId}} is a sheet Id in the form 6264126827992742
{{columnId}} is the Id of your primary column in the form 2641268279927426
{{columnId2}} is the Id of your multi picklist column in the form 6412682799274262
To add a column with a MULTI_PICKLIST type to an existing sheet:
POST: {{environment}}/sheets/{{sheetId}}/columns/
{
"title": "I'm a new multi picklist column",
"type":"MULTI_PICKLIST",
"index": 1,
"options": ["opt1","opt2","opt3"]
}
To create a column on a brand new sheet, this example will create a sheet with a primary column, a MULTI_PICKLIST column, and then add a row with some data.
Then it will get the sheet using level 2 to avoid the backwards compatibility TEXT_NUMBER type.
To create a sheet with a MULTI_PICKLIST column:
POST: {{environment}}/sheets
{
"name":"API PL Sheet",
"columns":
[
{
"title":"My primary Column",
"primary":true,
"type":"TEXT_NUMBER"
},
{
"title":"My multi select column",
"type":"MULTI_PICKLIST",
"options":["options","in","this","form"]
}
]
}
To add a row on this sheet:
POST: {{environment}}/sheets/{{sheetId}}/rows?include=objectValue
[
{
"toTop": true,
"cells":
[
{
"columnId":{{columnId}},
"value": "1"
},
{
"columnId":{{columnId2}},
"objectValue":
{
"objectType":"MULTI_PICKLIST",
"values":["in", "form"]
}
}
]
}
]
To view the sheet with the MULTI_PICKLIST objectValue:
GET: {{environment}}/sheets/{{sheetId}}?level=2&include=objectValue
If you do not include the ?level=2&include=objectValue suffix then the JSON response will have columns that appear as though they are TEXT_NUMBER types.
For one final note, different endpoint groups require different levels. They are as follows:
GET Cell History is level 2
GET Sheets is level 2
GET Row is level 2
GET Column is level 2
POST Sort is level 2
GET Sights (dashboards) is level 3
GET reports is level 3
I have a classic situation - a table with two comboboxes (or, to be exact, sap.m.Select controls) and after select in the first one, I would like to have the values in the second one updated. This is my model, basically, the first combobox should contain the list of available states and once some is selected, the second sap.m.Select control should be populated by relevant cities
{
countries: [
{ country: 'France', cities: ['Paris', 'Marseille', 'Lyon']},
{ country: 'Germany', cities: ['Berlin', 'Bonn']}
]
}
The problem is that I dont know how to do it. I am able to get the id of the updated row using something like this.
onCountryChange: function (oEvent) {
const selectedItem = oEvent.getParameter("selectedItem");
var path = selectedItem.getBindingContext().getPath();
bindComboBox(path); // this should rebind the data, but not written yet
}
I know now I should rebind the data in the correct combobox, however, I don't know how to affect only that single combobox on the correct row and how to update it. Could someone advise me how to do it? The whole table is defined in the .xml view, can I do it also with a formatter or inline expression or is this scenario too difficult for that?
Thank you
You can use the bindAggregation method (from the ManagedObject) class to rebind the combo boxes' items.
onCountryChange: function (oEvent) {
const selectedItem = oEvent.getParameter("selectedItem");
var path = selectedItem.getBindingContext().getPath();
this.byId("combo2").bindAggregation("items", {
path: path + "/cities",
template: new sap.ui.core.Item({
key: "{}",
text: "{}"
})
});
}
Note: Replacing "combo2" with the id of your 2nd combo box/select control.
Edit: To get the correct combo box (assuming you have multiple created on a table, use the ID of the first combo box (oEvent.getSource().getId()) to generate the ID of the 2nd combo box. Without knowing more of the structure of the table (and how it's created) I can't offer more.
We have to bind a OData url to UI5's ODataModel
https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZCD204_EPM_DEMO_SRV/BusinessPartners('0100000000')/SalesOrders/?$expand=SalesOrderItems
We are able to bind root level items that belong to each SalesOrder. However, we are running into problem in case of binding data from SalesOrderItems which are a child to SalesOrder.
We are not able to bind SalesOrderItems' fields to any of our objects. We tried using {SalesOrderItems/results/QuantityUnit}, {SalesOrderItems/QuantityUnit} without much luck.
Can you please suggest any alternatives?
There is 1..m cardinality between SalesOrder and SalesOrderItem
// model of oData
var model = sap.ui.model.odata.ODataModel("proxy/https/sapes1.sapdevcenter.com/sap/opu/odata/sap/ZCD204_EPM_DEMO_SRV/",true,'username','password');
//app is defined in index.html here we are setting model to the app.
App.setModel(model);
// create a table
var pastOrder_S3= new sap.m.Table("PastOrder_S3",{
inset:true,
//visibleRowCount: 2,
firstVisibleRow: 2,
fixedColumnCount: 2,
columns:[
new sap.m.Column({
header:new sap.m.Label("item").setText("Items"),
hAlign:"Left",
width:"20px",
demandPopin:true,
popinDisplay:"Block",
minScreenWidth: sap.m.ScreenSize.Medium
}),
new sap.m.Column({
header:new sap.m.Label("orderdetail").setText("OrderDetails"),
hAlign:"Left",
width:"200px",
demandPopin:true,
popinDisplay:"Block",
minScreenWidth: sap.m.ScreenSize.Medium
})
});
//create a template to bind into the table using model.
var oTemplate_S3= new sap.m.ColumnListItem({
type: sap.m.ListType.Active,
cells: [
new sap.m.Text({
text:"{ProductName} \n {ProductID}"
}),
new sap.m.Text({
text:"OrderId: {SalesOrderID} \n {DeliveryDate} \n {TotalSum}{Currency}"
})
]
});
// bind into the table.
`pastOrder_S3.bindAggregation("items","BusinessPartners('BusinessPartnerId')/SalesOrders/?$expand=SalesOrderItems",oTemplate_S3);`
Here we have a child property named 'SalesOrderItems' we need to read the properties inside the salesorderitems.
When binding the aggregation to an OData collection, the expand parameter (and any other parameters for that matter) has to be given separately, not part of the collection URI.
In an nutshell, you will have to do the following:
oTable.bindAggregation("items", {
path: "/BusinessPartners('BusinessPartnerId')/SalesOrders",
template: oTemplate,
parameters: {
expand: "SalesOrderItems"
}
});
Check out the bindAggregation and the ODataListBinding constructor documentation for more details.
Another problem that you will face is that you have this 1:n cardinality between the SaleOrder and the SaleOrderItems. This means that you will only be able to use this navigation property to bind an aggregation and not directly a property (so you need to have something like a table inside another table).
You will have to clearly define what should be displayed from the SaleOrderItems to be able to 'flatten' it (e.g. do an aggregation, or pick the first one, etc). This will most likely imply that changes must be made in the OData service or you will have to use either a custom control in UI5 or a JSONModel instead of / together with the OData one.
This may be a basic question, but it's my first, so please be kind :-).
I have a sap.m.table with two models, one model with transaction data (trxModel) and another model that is used to display a sap.m.select list (reasonCodeModel). The table model is set to trxModel.
The selected value key from the dropdown needs to update a value (ReasonCodeID) in the trxModel when a value from the reason code list is selected.
I can retrieve the selected key in the change event as so
var selKey = evt.getParameter("selectedItem").getKey();
Is there a simple way to find the trxModel relevant model path from the table row Select list value I've just modified? Or is it possible to bind the ReasonCodeID from the trxModel to the ReasonCodeID field in the reasonCodeModel?
Just an extra piece of info, The current row is selected and is accessible
var selItem = dtlTable.getSelectedItem();
2nd question and I guess could be kind of related, is there a way of getting the table model path based on the selected item (highlighted row) of the table? And vice a versa?
More details on Select & Table binding.
var tabTemplate = new sap.m.ColumnListItem(
{
::
new sap.m.Select(
"idReasonCodeSelect",
{
enabled : false,
change : function(evt) {
oS4View.getController().changeReasonCodeSel(evt);
}
}
),
Bind the resource code Select to the Table
// bind the reason codes to the reason code model
sap.ui.getCore().byId("idReasonCodeSelect").setModel(
oReasonCodeModel);
sap.ui.getCore().byId("idReasonCodeSelect").bindAggregation("items", "/results",
new sap.ui.core.Item({
key : "{ReasCodeID}",
text : "{ReasCodeDesc}"
}));
Per Qualiture comment, how do I bind the Select key to the table model ReasonCodeID value?
I found an approach to tackle the first part of my question above
From the change function on the Select, I can find the path of the table model using the following.
var path = evt.getSource().getParent().getBindingContext().sPath;
2nd Update:
On the selectionChange event on the table, there's a couple of options to find the associated model path or model content.
// find the model path
oModelPath = selItem.getBindingContext().getPath();
// model values
oItem = oEvent.getParameter("listItem").getBindingContext().getObject();
So my only remaining issue, While I loop through the table model results (trxModel) and I want the Select List (using setSelectedKey) to reflect the ReasonCodeID value in the trxModel.
Can you please show me how to allow editing of cells within SAPUI5 table? I am using JSON model.
look at this examples in the SDK Table.html, both of the examples show how to set a json model, set the json model as a data source of a table control, how to bind rows of the json to rows of the table, and how to bind the values to cells, once you change the cells values the new value will be reflect in the model
var employeeData = [
{lastName: "Dente", name: "Al"},
{lastName: "Friese", name: "Andy"},
{lastName: "Mann", name: "Anita"},
{lastName: "Schutt", name: "Doris}
];
//create the JSON model and set your data
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({ Employees: employeeData });
//create table
var oTable = new sap.ui.table.Table();
//add a column for lastname and bind the value to an editable textview
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Last Name"}),
template: new sap.ui.commons.TextView().bindProperty("text", "lastName"),
});
//add a column for name and bind the value to an editable textview
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "First Name"}),
template: new sap.ui.commons.TextField().bindProperty("value", "name"),
}));
oTable.setModel(oModel);
oTable.bindRows("/Employees);
First your table template objects have to be editable. For a textfield either use the setEditable(true), bindProperty('editable',true) or directly in the construtor new TextField({editalbe:true}).
If it is editable ensure you have switched on two way binding in your model. For JSON models this is the default I think. Also ensure, that there are no formatters involved, because these will destroy two way binding.
The you can check in your debugger, if the changes on the UI are transfered to the model. In general this works fine and from this point it is up to you what to do with the model (send it to some oData save service).
I had the same issue with a table that had to be editable when the value was zero and non-editable when it was greater than zero.
Value1 is my dinamic value.
Value2 is zero
<Input type="Number" editable="{parts:[{path : 'Value1'}, {path : 'Value2'}], formatter:'sap.ui.app.model.formatter.CantEditable'}"/>
Inside the formatter i defined a function called CantEditable like this.
jQuery.sap.declare("sap.ui.app.model.formatter");
sap.ui.app.model.formatter =
{
function1: (Value1, Value2)
{
//If value 1 > Value 2 return editable
if (Value1>Value2)
{
return false;
}
else
{
return true;
}
};
Since its binded to the value of these two variables. Whenever my value one changes, the editable function will check if it meets the requeriments of the function. Then it will change the value of the editable property.
My sap.m.Table demo here:
http://plnkr.co/edit/qifky6plPEzFtlpyV2vb?p=preview
I am using data-sap-ui-theme="sap_belize", you can change it to sap_bluecrystal.
The basic idea is using editable property of sap.m.Input, and enabled property of sap.m.Select.
I opened an issue of ui5 to discuss this problem: https://github.com/SAP/openui5/issues/1646