The values are loaded from the data source but on ui no text is shown.
var r0c1 = new sap.ui.commons.DropdownBox("r0c1");
var oItemTemplate1 = new sap.ui.core.ListItem();
property binding is done:
oItemTemplate1.bindProperty("text", "{ZtmDockid}");
bind the items:
r0c1.bindItems("/d/results", oItemTemplate1);
Data is properly coming, but on UI its not showing the text.
there are two ways to bind data to a control.
First way using bindProperty:
var oItemTemplate1 = new sap.ui.core.ListItem();
oItemTemplate1.bindProperty("text", "value");
(notice: usage of { })
or binding the values when creating the control:
var oItemTemplate1 = new sap.ui.core.ListItem({
text: "{value}"
});
(you need to use { } to indicate dynamic values)
Herrlock is correct, but I wanted to draw out the subtlety - explicit binding with the bind* functions requires no curly braces ... these are only needed for embedded, or implicit binding.
Here's your code with the braces removed from your bindProperty's second parameter, as a runnable snippet.
// Code from question
var r0c1 = new sap.ui.commons.DropdownBox("r0c1");
var oItemTemplate1 = new sap.ui.core.ListItem();
oItemTemplate1.bindProperty("text", "ZtmDockid");
r0c1.bindItems("/d/results", oItemTemplate1);
// Extra code
r0c1
.setModel(new sap.ui.model.json.JSONModel({
d : {
results : [
{ ZtmDockid : "1" },
{ ZtmDockid : "2" },
{ ZtmDockid : "3" }
]
}
}))
.placeAt('content');
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m,sap.ui.commons"
data-sap-ui-theme="sap_bluecrystal"></script>
<div id="content"></div>
Related
I made a generic function that generates some form fields, because I need them at many different places in my app.
It has an optional parameter for setting the visibility of the fields.
But now I need to add additional visibility rules for specific fields.
These additional rules should stay the same for all function calls, so theoretically there's no need to set them through a new parameter.
Unfortunately these specific rules are overwritten if the visibility parameter is set.
My goal is to extend these rules with the visibility parameter.
Here's a minimal example:
The specific visibility rule is that an input's value has to be greater than 0.
On one function call another visibility rule is that the value of FlagSet need to be equal to "yes".
let data = {
"FlagSet": "yes",
"Data": [{
"Size": 1
},
{
"Size": 0
}
]
};
let oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
let oPage = new sap.m.VBox();
oPage.setModel(oModel);
let additionalVisibilityRules = [
false,
{
path: "/FlagSet",
formatter: (flagSet) => (flagSet === "yes")
}
];
for (let i = 0, l = data.Data.length; i < l; i++)
oPage.addItem(getFields(i, additionalVisibilityRules[i]));
function getFields(index, oVisibility) {
let oCtrl = new sap.m.Input({
value: `{/Data/${index}/Size}`
}).bindProperty("visible", {
path: `/Data/${index}/Size`,
formatter: (size) => (size > 0)
});
if (oVisibility) {
oCtrl.bindProperty("visible", oVisibility);
}
return oCtrl;
}
oPage.placeAt("content");
<script id='sap-ui-bootstrap' type='text/javascript' src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-libs="sap.m,sap.ui.commons,sap.ui.table" data-sap-ui-theme="sap_bluecrystal">
</script>
<body class='sapUiBody'>
<div id='content'></div>
</body>
How can I combine it so that the second input field is only visible if both its value is above 0 AND FlagSet is equal to "yes"?
If you need multiple model properties, you could try using Composite Binding
Here is an example from the documentation:
<TextField value="{
parts: [
{path:'birthday/day'},
{path:'birthday/month'},
{path:'birthday/year'}
],
formatter:'my.globalFormatter'}"/>
For more information see:
https://ui5.sap.com/#/topic/e2e6f4127fe4450ab3cf1339c42ee832
I am working with sap.m.table. I have requirement to apply or change the background color for some of the rows based on the data in one of the column in those rows in table.
I am using the following code but it is not working
created the CSSfile: test.css
<style type="text/css">
.Total {
background-color: LightSteelBlue !important;
}
</style>
The above CSS file declare in Component.js like the following way ( correct me if this not right way to make the css file available to access in whole ui5 project.
"resources": {
"css": [
{
"uri": "css/test.css"
}
]
}
In Controller.i have defined the following method to apply the style sheet for the particular rows alone in table.
rowColours: function() {
var oController = this;
console.log("rowColours() --> Start ");
var oTable = this.oView.byId("tblAllocation");
var rows = oTable.getItems().length; //number of rows on tab
//start index
var row;
var cells = [];
var oCell = null;
for (i = 0; i < oTable.getItems().length; i++) {
//console.log("rowColours() :: row--> "+row);
//actualRow = oTable.getItems(); //content
if (i == 0) {
row = oTable.getItems()[i];
cells = cells.concat(oTable.getItems()[i].getCells());
//getting the cell id
oCell = cells[2];
oCell = oCell.toString().substring(29, oCell.length);
otemp = this.getView().byId(oCell).getText();
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("grandTotal");
}
}
}
console.log("rowColours() --> end ");
}
In the above method. I am checking the cell2 data ( in table cell 2 i was using the Textview control to display the data. when call this method to get the data in that cell. I am getting the following error.
otemp = this.getView().byId(oCell).getText());
error:
Uncaught TypeError: Cannot read property 'getText' of undefined
is the following code is possible to change the row bg color.
if (otemp.toString() == "TotalAllocation") {
oTable.getItems()[i].$().taggleClass("Total");
}
Please let me know how to change the bg color or applying the style for the perticular row in sap.m.table
Thanks
The approach your following is not right. Better you can use a formatter.
Example:
var oTable = new sap.m.Table({
columns: [
new sap.m.Column({
header: new sap.m.Label({
text: "Name"
}),
}),
],
items: {
path: 'modelList>/',
template: new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
//formatter to the text property on sap.m.Text control.
text: {
parts: [{
"path": "modelList>Name"
}],
formatter: function(name) {
if (name == "TotalAllocation") {
// use this.getParent().. until u get the row. like this below and add class.
this.getParent().getParent().addStyleClass("Total");
}
}
}
})
]
})
}
});
var oModel = new sap.ui.model.json.JSONModel();
var modelData = {
greet: "hello"
};
oModel.setData(modelData);
var oTextView = new sap.ui.commons.TextView({
text: "{/greet}" + "?" // "{/greet}" interpreted as ordinary string in this case
});
oTextView.setModel(oModel);
oTextView.placeAt("content");
To make the issue simple, my problem can be simplified as follows:
I would like to append a question mark to the text of a TextView. However, the leading part of the text is from the model. Indeed, in this simple case, I could have accessed the text from the model before it is combined with the question mark. After the target string is produced, I can assign it to the text property of TextView. However, what if the model gets changed else where? The code accessing the text property won't be guaranteed to be executed, so the text of TextView won't get updated?
Is there any way to solve this problem?
You can use complex binding syntax for this. Simply add this to your bootstrap:
data-sap-ui-xx-bindingSyntax="complex"
This enables you to combine model values with static text values like this:
var oTextView = new sap.ui.commons.TextView({
text: "{/greet} ?"
});
or even something like this:
var oTextView = new sap.ui.commons.TextView({
text: "{/lastName}, {/firstName}"
});
If your static text part depends on the model value you can add a formatter function, for example:
var oTextView = new sap.ui.commons.TextView({
text: {
path : "/greet", // no curly braces here!
formatter : function(greet) {
if(greet === "hello") {
return greet + "!";
} else if (greet === "how are you") {
return greet + "?";
} else {
return greet;
}
}
});
I'm using the description field to hold an value that I don't want to be displayed, is it possible to set this property to visible:false or set to width to 0?
new sap.m.Input("idAltDistInput"+refDocID+sequenceID, {value:"{AltDistrictDesc}",
description: { path : 'AltDistrictID' }
:
visible : false doesn't seem to work.
Yes you can by adding StyleClass.
sap.m.Input("id",{
//Properties
}).addStyleClass("InputDescripTionHidden");
Add following css
.InputDescripTionHidden>span{
display:none
}
Your comment above suggests that you want to store some hidden value, for later use.
Rather than "hijack" (in the nicest sense of the word) another property, you should consider using Custom Data, which is designed for this sort of thing. Here's an example.
new sap.m.List({
mode: "SingleSelectMaster",
items: {
path: "/records",
template: new sap.m.InputListItem({
label: "District",
content: new sap.m.Input({
value: "{AltDistrictDesc}",
customData: [new sap.ui.core.CustomData({
key: "DistrictID",
value: "{AltDistrictID}"
})]
})
})
},
select: function(oEvent) {
var id = oEvent.getParameter("listItem")
.getContent()[0] // the Input control
.getCustomData()[0] // the only Custom Data
.getValue();
alert("Selected District ID : " + id);
}
})
.setModel(new sap.ui.model.json.JSONModel({
records: [{
AltDistrictID: "D1",
AltDistrictDesc: "District 1"
}, {
AltDistrictID: "D2",
AltDistrictDesc: "District 2"
}]
}))
.placeAt("content");
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-libs="sap.m" data-sap-ui-theme="sap_bluecrystal"></script>
<div class="sapUiBody" id="content"></div>
(Note that for simplicity, I'm just grabbing the first content and the first custom data within that content in the select listener. You will want to do this slightly more precisely in real code.)
I've seen similar things, where people have wanted to do this in ASP .NET, generic JavaScript, PHP, etc., but now here we have KnockOut that throws a wrench in things, since its fields are already rendered dynamically. Now here I go wanting to rewrite a dropdown when another is changed... dynamic loading on top of dynamic loading, all in old-fashioned cascading style....
I have a dropdown, "ourTypes", I've called it, that when changed, should re-write the options of the "slots" dropdown to its left. I have a .subscribe() function that creates new options based on a limit I get from the "ourTypes" value. All well and good, but how do we make the dropdown actually reflect those new values?
HTML:
<select data-bind="options: $root.slots, optionsValue: 'Value', optionsText: 'Text', value: $data.SlotPosition"></select>
<select data-bind="options: $root.ourTypes, optionsValue: 'ID', optionsText: 'Name', value: $data.OurTypeId"></select>
JavaScript:
var slots = [
{ Text: "1", Value: "1" },
{ Text: "2", Value: "2" },
{ Text: "3", Value: "3" }
];
var ourTypes = [
{ ID:"1", Name:"None", Limit:0 },
{ ID:"2", Name:"Fruits", Limit:5 },
{ ID:"3", Name:"Vegetables", Limit:5 },
{ ID:"4", Name:"Meats", Limit:2 }
];
var dataList = [
{ SlotPosition: "1", OurTypeId: 4 },
{ SlotPosition: "2", OurTypeId: 2 },
{ SlotPosition: "3", OurTypeId: 3 }
];
var myViewModel = new MyViewModel(dataList);
ko.applyBindings(myViewModel);
function MyViewModel(dataList) {
var self = this;
self.slots = slots;
self.ourTypes = ourTypes;
self.OurTypeId = ko.observable(dataList.OurTypeId);
self.SlotPosition = ko.observable(dataList.SlotPosition);
self.OurTypeId.subscribe(function() {
if (!ko.isObservable(self.SlotPosition))
self.SlotPosition = ko.observable("1");
// Get our new limit based on value
var limit = ko.utils.arrayFirst(ourTypes, function(type) {
return type.ID == self.OurTypeId();
}).Limit;
// Build options here
self.slots.length = 0;
self.slots.push({Text:"",Value:""});
for (var i=1; i < limit+1; i++) {
self.slots.push({Text:i, Value:i});
}
// What else do I do here to make the dropdown refresh
// with the new values?
});
}
Fiddle: http://jsfiddle.net/navyjax2/Lspwc4n4/
Well just made small changes in you code
View Model:
self.slots = ko.observableArray(slots); //should make it observable
self.ourTypes = ko.observableArray(ourTypes);
self.OurTypeId = ko.observable(dataList[0].OurTypeId); // initial value setting
self.SlotPosition = ko.observable(dataList.SlotPosition);
//Inside subscribe
self.slots([]); // clearing before filling new values
Working fiddle here