I am trying to add an icon to my table column. The icon should be selected depending on the value. Therefore I implemented some formatter function which is based in the model/formatter.js file.
Here is the code I try to add the the table column:
new sap.ui.layout.VerticalLayout({
content: [
new sap.m.Label({text:"{Items>Status}"}),
new sap.ui.core.Icon({
src: {
parts: [
"Items>Status"
],
formatter: Formatter.formatStatusIcon
},
size: "1rem",
color: {
parts: [
"Items>Status"
],
formatter: Formatter.formatStatusIconColor
}
})
]
})
The label does display the correct value. The icon is not displayed. The formatter function has as input value always null even though the values exist and are not null. I am using SAPUI5 version 1.61.2. I already tried different syntaxes of the parts property but none of them did work. I also tried adding some static value instead of "Items>Status" for testing purpose but the input in the formatter function is still null.
Has anyone an idea why the input of the formatter function is always null?
Based on the your input, I have understood that you have a JS view and your are changing the Icon and its color based on the status
View.js
var oTable = new sap.m.Table("idPrdList", {
headerText : "List of Products",
headerDesign : sap.m.ListHeaderDesign.Standard,
mode : sap.m.ListMode.None,
includeItemInSelection : false,
});
var col1 = new sap.m.Column({header: new sap.m.Label({text:"Product Name"})});
oTable.addColumn(col1);
var col2 = new sap.m.Column({header: new sap.m.Label({text:"Description"})});
oTable.addColumn(col2);
var col3 = new sap.m.Column({header: new sap.m.Label({text:"Price"})});
oTable.addColumn(col3);
controller.js
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
'items': [
{
'ProductID': "sdf",
'ProductName': "asdf",
"Status": "1"
},
{
'ProductID': "ss",
'ProductName': "asf",
"Status": "1"
},
{
'ProductID': "fff",
'ProductName': "asdf",
"Status": "2"
},
{
'ProductID': "fas",
'ProductName': "asdf",
"Status": "1"
},
{
'ProductID': "asdfa",
'ProductName': "asdfwer",
"Status": "2"
}]
});
sap.ui.getCore().setModel(oModel, "tableData");
var oTable = sap.ui.getCore().byId("idPrdList");
var colItems = new sap.m.ColumnListItem("colItems", {
type: "Active"
});
var txtNAME = new sap.m.Text({
text: "{tableData>ProductID}"
});
colItems.addCell(txtNAME);
var txtNAME2 = new sap.m.Text({
text: "{tableData>ProductName}"
});
colItems.addCell(txtNAME2);
var txtNAME3 = new sap.ui.layout.VerticalLayout({
content: [
new sap.m.Label({
text: "{tableData>Status}"
}),
new sap.ui.core.Icon({
src: {
parts: ["tableData>Status"],
formatter: assets.util.mFormatter.formatStatusIcon
},
size: "1rem",
color: {
parts: ["tableData>Status"],
formatter: assets.util.mFormatter.formatStatusIconColor
}
})
]
})
colItems.addCell(txtNAME3);
oTable.bindAggregation("items", "tableData>/items", colItems);
oTable.setModel(oModel, "tableData");
Formatter.js
jQuery.sap.declare("assets.util.mFormatter");
assets.util.mFormatter = {
formatStatusIcon: function(Status) {
return (Status === "2" ? "ICONPath1" : "ICONPath2");
},
formatStatusIconColor: function(Status) {
return (Status === "2" ? "Color1" : "Color2");
},
};
Output
Your syntax is wrong I think. Remove that parts stuff.
Try this:
src="{path: 'invoice>Status',
formatter: '.Formatter.statusText'}
Try this syntax below :
new sap.ui.layout.VerticalLayout({
content: [
new sap.m.Label({text:"{Items>Status}"}),
new sap.ui.core.Icon({
src: {
parts: [
{path: 'Items>Status'}
],
formatter: '.Formatter.formatStatusIcon'
},
size: "1rem",
color: {
parts: [
"Items>Status"
],
formatter: Formatter.formatStatusIconColor
}
})
]
})
Related
I'm trying to use the PlanningCalender from SAPUI5. However, I have a problem when I switch to the week view. Here appointments that are close together are written in a new line. But I don't want this behavior. All appointments should be written one after the other, even if I can then no longer read the content of the appointments.
It seems like there is a minimum width for appointments. But I can't find a way to change this appointment width.
Does anyone have an idea how I can get the appointments one after the other?
Plunker Example
sap.ui.define([
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel',
'sap/m/Dialog',
'sap/m/Button'
],
function(Controller, JSONModel,Dialog, Button) {
"use strict";
var PageController = Controller.extend("sample1.View1", {
onInit: function () {
// create model
var oModel = new JSONModel();
oModel.setData({
startDate: new Date("2015", "11", "15", "8", "0"),
people: [
{
pic: "sap-icon://employee",
name: "John Doe",
role: "team member",
appointments: [
{
start: new Date("2015", "11", "15", "08", "30"),
end: new Date("2015", "11", "15", "10", "30"),
title: "Meeting",
type: "Type02",
tentative: false
},
{
start: new Date("2015", "11", "15", "10", "30"),
end: new Date("2015", "11", "15", "12", "0"),
title: "Team meeting",
info: "room 1",
type: "Type01",
pic: "sap-icon://sap-ui5",
tentative: false
},
{
start: new Date("2015", "11", "15", "12", "00"),
end: new Date("2015", "11", "15", "13", "30"),
title: "Lunch",
type: "Type03",
tentative: true
}
]
}
]
});
this.getView().setModel(oModel);
},
handleAppointmentSelect: function (oEvent) {
var oAppointment = oEvent.getParameter("appointment");
if (oAppointment) {
alert("Appointment selected: " + oAppointment.getTitle());
}else {
var aAppointments = oEvent.getParameter("appointments");
var sValue = aAppointments.length + " Appointments selected";
alert(sValue);
}
},
handleIntervalSelect:function(oEvent){
var dialogData = {
newEntry: {
start: oEvent.getParameter("startDate"),
end: oEvent.getParameter("endDate"),
title: "",
info: "",
type: "Type01",
pic: "sap-icon://sap-ui5",
tentative: false
},
people: this.getView().getModel().getProperty("/people").map(function(p,i){ return { name: p.name, index: i, selected: true }; }) //A List of all people. All selected by default.
};
var dialogModel = new JSONModel(dialogData);
var that = this;
var planningDialog = new Dialog({
title:"Add Appointment",
content: sap.ui.xmlview({viewName:"sample1.AppointmentDialog"}).setModel(dialogModel),
leftButton: new Button({
text: "Cancel",
press: function(){
planningDialog.close();
planningDialog.destroy();
}}),
rightButton: new Button({
text: "Save",
type: "Accept",
press: function(){
planningDialog.close();
that.addAppointment(dialogData);
}}),
});
planningDialog.open();
},
addAppointment:function(data){
var model = this.getView().getModel();
var peopleList = model.getProperty("/people");
data.people
.filter(function(p){return p.selected;})
.forEach(function(p){
peopleList[p.index].appointments.push(data.newEntry);
});
model.setProperty("/people",peopleList); //Updates Bindings
}
});
return PageController;
});
setBuiltInViews
Sets a new value for property builtInViews.
Defines the list of predefined views as an array. The views should be specified by their keys.
The default predefined views and their keys are available at sap.m.PlanningCalendarBuiltInView.
Note: If set, all specified views will be displayed along with any custom views (if available). If not set and no custom views are available, all default views will be displayed. If not set and there are any custom views available, only the custom views will be displayed.
When called with a value of null or undefined, the default value of the property will be restored.
Default value is [].
What you are looking for is somehow tweak -- sap.m.PlanningCalendarBuiltInView.Week.
Haven't worked on it, will look for the solution! All the best!
I am trying to display a VizFrame and my data are in a simple JSON format.
Both my view and controller are in JS. (I will start writing my view in XML going forward) because I see that is the way to go.
I get a blank page with the error: "setDataset of undefined". What am I missing?
My view code is this.
createContent: function(oController) {
var oSubHeader = new sap.m.Bar({
contentLeft: [
new sap.m.Button({
icon: "sap-icon://nav-back",
press: [oController.onNavBack, oController]
})
],
contentMiddle: [
new sap.m.Label({
text: "{i18n>app_subhead_2}"
})
]
});
var oVizFrame = new sap.viz.ui5.controls.VizFrame("VizFrameId", {
width: "100%",
height: "400px",
vizType: "line"
});
var oPage = new sap.m.Page({
title: "UI5 Assignment App",
showSubHeader: true,
subHeader: oSubHeader,
content: [oVizFrame]
});
return oPage;
}
My corresponding controller is
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/UIComponent",
"sap/ui/core/routing/History",
"sap/viz/ui5/controls/VizFrame",
"sap/viz/ui5/data/FlattenedDataset"
], function (Controller, UIComponent, History, VizFrame, FlattenedDataset) {
"use strict";
return Controller.extend("Project_Tile_learning.Divya_tile_Project.controller.ProductDetailPage", {
onNavBack: function () {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("homepage", true);
}
},
onInit: function () {
var sampleDatajson = new sap.ui.model.json.JSONModel("json/PA.json");
var oVizFrame = this.getView().byId("VizFrameId");
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
name: "Year",
value: "{Year}"
}],
measures: [{
name: "Supplier",
value: "{Supplier}"
}, {
name: "Liquor",
value: "{Liquor}"
}, {
name: "Quantity",
value: "{Quantity}"
}],
data: {
path: "/items"
}
});
oVizFrame.setDataset(oDataset);
oVizFrame.setModel(sampleDatajson);
var oFeedValueAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Supplier"]
});
var oFeedValueAxis1 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Liquor"]
});
var oFeedValueAxis2 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Quantity"]
});
var oFeedCategoryAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "categoryAxis",
"type": "Dimension",
"values": ["Year"]
});
oVizFrame.addFeed(oFeedValueAxis);
oVizFrame.addFeed(oFeedValueAxis1);
oVizFrame.addFeed(oFeedValueAxis2);
oVizFrame.addFeed(oFeedCategoryAxis);
}
});
});
Update: JS View is deprecated since UI5 v1.90. Use Typed View instead.
When creating a control in JS view definition, always use this.createId("myControl").
From the doc:
If you want to define IDs for controls inside a JSView to guarantee their uniqueness [...], you cannot give hardcoded IDs, but have to give the view the opportunity to add its own instance ID as a prefix. This is done by using the View.createId(...) method.
For the example above, this is done as follows:
new sap.viz.ui5.controls.VizFrame(this.createId("VizFrameId"), { /*...*/ });
Then in the controller, myView.byId tries to access the control with view's own ID as a prefix, which will succeed this time since the control has an ID with the view ID as a prefix.
I am displaying data in the table using sap.m.table. The table is created in the controller using java script. JSON model is binded to the table. In one of the column of the table, if there is no value i have to provide a button in the same column, for the user to click and create data .
You can achieve it using an aggregation binding using a Factory Function
Factory function is used to generate different controls based on the data received at runtime
onCreateTable: function () {
var oData = {
"items": [
{ "Column1": "Col1", "Column2": "Col12", "value": "10" },
{ "Column1": "Col2", "Column2": "Col22", "value": "9" },
{ "Column1": "Col3", "Column2": "Col32", "value": "7" },
{ "Column1": "Col4", "Column2": "Col52", "value": "1" },
{ "Column1": "Col6", "Column2": "Col62", "value": "3" },
{ "Column1": "Col7", "Column2": "Col72", "value": "" }
]};
var oTable = new sap.m.Table({
headerToolbar: new sap.m.Toolbar({
content: [new sap.m.Label({
text: ""
})]
}),
columns: [new sap.m.Column({
width: "2em",
header: new sap.m.Label({
text: "Column1"
})
}), new sap.m.Column({
width: "2em",
header: new sap.m.Label({
text: "Column2"
})
}), new sap.m.Column({
width: "2em",
header: new sap.m.Label({
text: "Column3"
})
})]
});
sap.ui.getCore().byId("tableWrapper").addItem(oTable);
oTable.bindItems({
path: "/items",
factory: this.populateItems.bind(this)
});
oTable.setModel(new sap.ui.model.json.JSONModel(oData));
},
populateItems: function(sId, oContext) {
var oInput = null;
if(oContext.getObject().value)
oInput = new sap.m.Label({ text: oContext.getObject().value });
else
oInput = new sap.m.Button({ text: "Create" });
var oRow = new sap.m.ColumnListItem(sId, {
type: "Active",
cells: [
new sap.m.Text({ text: "{Column1}" }),
new sap.m.Text({ text: "{Column2}" }),
oInput
]
});
return oRow;
},
Output
I have a requirement wherein I have to populate columns and rows dynamically from oData. For test purpose I created the following JSON files for columns and rows.
column.json
{
"Columns": [
{ "column": "col1" },
{ "column": "col2" },
{ "column": "col3" }
]
}
row.json
{
"Rows": [
{ "col1": "abc",
"col2": "def",
"col3": "ghi"
},
{ "col1": "jkl",
"col2": "mno",
"col3": "pqr"
}
]
}
Here is my view
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="sam.test" xmlns:html="http://www.w3.org/1999/xhtml">
<Table id="ID"
columns="{path: 'Column>/Columns', factory: '.populateColumns'}"
items="{path: 'Row>/Rows', factory: '.populateItems'}">
</Table></core:View>
Note that in manifest file "Column" points to column.json and "Row" points to row.json file.
Here is my corresponding controller -
sap.ui.controller("sam.test", {
// onInit: function() {
// },
// onBeforeRendering: function() {
//
// },
// onAfterRendering: function() {
//
// },
// onExit: function() {
//
// }
populateItems: function(sId, oContext) {
var row = new sap.m.ColumnListItem(sId, {
type: "Active",
cell: [
new Text({
text: "{Column>col1}"
}),
new Text({
text: "{Column>col2}"
}),
new Text({
text: "{Column>col3}"
})
]
});
return row;
},
populateColumns: function(sId, oContext) {
var sColumnId = oContext.getObject().column;
return new sap.ui.table.Column({
id: sColumnId,
label: sColumnId,
template: sColumnId,
sortProperty: sColumnId,
filterProperty: sColumnId
});
}
});
This however is not working. It renders table with no column headers and no rows. When I bind rows directly to items aggregation of Table and also provide columns aggregation with same value it works.
Am I missing something? I am having tough time figuring this out. Any pointers will be appreciated
Thanks!
3 Mistakes which I found:
Wrong type of Column: new sap.ui.table.Column- The correct column type should be sap.m.Column since this is a sap.m.Table.
Wrong name of aggregation used for sap.m.ColumnListItem: The correct aggregation is cells and not cell ( typo).
Wrong model is bound to ColumnListItem: It should be Row>col1 and not Column>col1 as Row model stores the data.
Lets correct these mistakes and below is the working code:
populateItems: function(sId, oContext) {
var row = new sap.m.ColumnListItem(sId, {
type: "Active",
cells: [
new sap.m.Text({
text: "{Row>col1}"
}),
new sap.m.Text({
text: "{Row>col2}"
}),
new sap.m.Text({
text: "{Row>col3}"
})
]
});
return row;
},
populateColumns: function(sId, oContext) {
var sColumnId = oContext.getObject().column;
return new sap.m.Column({
header: new sap.m.Text({
text:'{Column>column}'
})
});
},
Let me know if this works.
I have put together a simple jsfiddle demonstrating the issue. It has a grid with two records. One has a true value in in the Boolean column and the other has a false.
I have logged the data to the console so you can see the values that the grid is getting.
Yet the grid shows false for both rows.
http://jsfiddle.net/codeowl/KhBMT/
Thanks for your time,
Scott
Code for StackOverflow:
var _Data = [
{ "SL_TestData_ID": "1", "SL_TestData_String": "Bool is 1", "SL_TestData_Boolean": "1" },
{ "SL_TestData_ID": "2", "SL_TestData_String": "Bool is 0", "SL_TestData_Boolean": "0" }
];
var _kendoDataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
console.log('Transport READ Event Raised - Data: ', JSON.stringify(_Data, null, 4));
options.success(_Data);
}
},
schema: {
model: {
id: "SL_TestData_ID",
fields: {
SL_TestData_ID: { editable: false, nullable: false },
SL_TestData_String: { type: "string" },
SL_TestData_Boolean: { type: "boolean" }
}
}
},
error: function (a) {
$('#TestGrid').data("kendoGrid").cancelChanges();
}
});
// Initialize Grid
$("#TestGrid").kendoGrid({
columns: [
{ field: "SL_TestData_ID", title: "ID" },
{ field: "SL_TestData_String", title: "String" },
{ field: "SL_TestData_Boolean", title: "Boolean" }
],
dataSource: _kendoDataSource
});
I found that if I altered my select statement to return "TRUE"/"FALSE" for my TINYINT column in the database it worked. Eg;
SELECT
SL_TestData_ID,
SL_TestData_Number,
SL_TestData_String,
SL_TestData_Date,
SL_TestData_DateTime,
if (SL_TestData_Boolean = 1, "TRUE", "FALSE") as SL_TestData_Boolean
FROM
SL_TestData;
Regards,
Scott