Bind values dynamically to TextView properties in SAPUI5 - sapui5

I am designing a table with different columns filled with data, from an SAP OData backend, into textviews.
The design and semanticColor properties of the TextView are values received as a string. However loading fails with an error message: "String XY cannot be interpreted as design" // "..as semantic color" after binding in the following way..
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{MyBackendElement}",
textAlign : sap.ui.core.TextAlign.Center,
design : "{Class}",
semanticColor : "{FontClass},
}),
visible : true,
}));
If I put in the design and semantic color directly, everything works fine, but how can I make this from my service? which data type does it need? Is it possible to transform the string defined in brackets {} for design and semantic color??
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{MyBackendElement}",
textAlign : sap.ui.core.TextAlign.Center,
design : sap.ui.commons.TextViewDesign.Bold,
semanticColor : sap.ui.commons.TextViewColor.Critical,
}),
visible : true,
}));

The answer is partly in your question itself, the properties design and semanticColor only accept values of type sap.ui.commons.TextViewDesign and sap.ui.commons.TextViewColor.
However, as in your case you would be binding "strings" to these properties, you would need to ensure that the string is same as the last word of the possible list of values for the accepted types.
For example,
sap.ui.commons.TextViewDesign accepts
sap.ui.commons.TextViewDesign.Bold
sap.ui.commons.TextViewDesign.Italic
and so on. Therefore, you need to bring in "Bold" or "Italic" from your OData and bind it to the properties. Same goes for sap.ui.commons.TextViewColor
In your code snippet,
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{MyBackendElement}",
textAlign : sap.ui.core.TextAlign.Center,
design : "{Class}",
semanticColor : "{FontClass},
}),
visible : true,
}));
'Class' would have values "Bold", "Italic"... and 'FontClass' would have "Critical", "Default"...
The list of allowed values for
sap.ui.commons.TextViewDesign is here
sap.ui.commons.TextViewColor is here

Related

Extend standard UI5 control

I want to add an additional text property to sap.ui.unified.MenuItem. It currently has only one text property.
I am trying the following
sap.ui.unified.MenuItem.extend("ExtendedMenuItem",{
metadata:{
properties:{
SetText : {type: "string"}
},
aggregations: {
_SecondText : {type: "sap.ui.commons.Label", multiple : false, visibility: "public"}
}
},
init: function(){
var oSecondText = new sap.ui.commons.Label("TL",{
text: this.SetText
});
this.addAggregation("_SecondText",oSecondText);
},
renderer:"sap.ui.unified.MenuItemRenderer"
});
var oTestCopy = new ExtendedMenuItem("TC",{
text: "TEST COPY",
SetText: "CTRL+TEST"
});
but the second text property is not being displayed.
What can i do to add a second text property to a standard UI5 control ?
Here is an example from the official documentation of Custom Controllers. You have to implement the renderer itself to place the new m.Label element on the UI. In the renderer, you can operate with standard HTML elements. For more details, check the linked source.

The control manages the rows aggregation. The method "addRow" cannot be used programmatically

I have a table that I want to distinguish between the items in the table by checking some condition and if the condition holds, i want to add row. but when I try to do that I get the error that:
The control manages the rows aggregation. The method "addRow" cannot be used programmatically!
var oTable = new sap.ui.table.Table({
width : "900px",
visibleRowCount : 10,
navigationMode : sap.ui.table.NavigationMode.Paginator
});
oTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "Names"
})
}));
$.each(data, function(index,
nodes) {
if (nodes == something) {
oRow = new sap.ui.table.Row();
oRow.addCell(new sap.ui.commons.Link({
text : "something"
}));
oTable.addRow(oRow);
};
});
};
You cannot add data manually to the sap.ui.table.Table. This has to be done using databinding. Please check the examples in the documentation:
https://openui5.hana.ondemand.com/#test-resources/sap/ui/table/demokit/Table.html
you can find more information on data binding here:
https://openui5.hana.ondemand.com/#docs/guide/91f0ca956f4d1014b6dd926db0e91070.html

How to create space between to TextField in SAP UI5

I have created three text boxes in sapui5. i want to separate those text boxes with spaces. I have tried with &nbsp spacing but that hasn't work. Please help me to solve this.
When I have to use a space I use "\u00a0".
So e.g.
createContent : function(oController) {
var content = [];
content.push(new sap.ui.commons.TextField({
value : "Field1"
}));
content.push(new sap.ui.commons.TextView({
text : "\u00a0"
}));
content.push(new sap.ui.commons.TextField({
value : "Field2"
}));
content.push(new sap.ui.commons.TextField({
value : "Field3"
}));
return content;
}
will create three TextFields, where the first and second are seperated by one space

How to add ColumnListItem to a table inside a page in MVC from other page controller

I have a SAPUI5 application written in MVC
I have a view called oPage4:
var landscapePage = new sap.m.Page({
title : "Landscape Name",
showNavButton : true,
navButtonPress : [oController.back,oController],
footer : new sap.m.Bar({
id : 'landscapePage_footer',
contentMiddle : [
new sap.m.Button({
}),
new sap.m.Button({
})
]
}),
});
oLandscapePageTable = new sap.m.Table("landscape", {
inset : true,
visible : true,
getIncludeItemInSelection : true,
showNoData : false,
columns : [ new sap.m.Column({
styleClass : "name",
hAlign : "Left",
header : new sap.m.Label({
})
}) ]
});
landscapePage.addContent(oLandscapePageTable);
return landscapePage;
then inside page1 controller I want to add a columnlistitem to the table of page 4.
var oPage4 = sap.ui.getCore().byId("p4");
var landscapePageRow = new sap.m.ColumnListItem({
type : "Active",
visible : true,
selected : true,
cells : [ new sap.m.Label({
text : something
}) ]
});
oPage4.getContent().addItem(landscapePageRow);
it doesn't work. please show me how to do so?
Ok, I think I understood your problem now. In general I would avoid calling the page and doing manipulations on it from another view. However, it is absolutely possible:
Additional functions in your view
You can extend your page4 with some more functions that can be called from outside like this:
sap.ui.jsview("my.page4", {
createContent : function() {
this.table = ...
...
},
addColumnListItem : function(columnListItem) {
// add it to the table calling this.table ...
}
}
From another view you´re now able to call this function like this:
var page4 = sap.ui.jsview("my.page4");
page4.addColumnListItem(page4, columnListItem);
Attention: The page4 object itself doesn´t point to the control you´re returning but to the the view instance itself. You will notice this, if you log the page4 object to the console. This is why you have to add functions like described.
Some other approaches would be to use the EventBus like described here to publish and subscribe to events. Since you´ve asked for it let me show you how you could do it:
Using the EventBus
The main intention is, that one can subscribe to a particular event and others can publish such events to the eventbus. Let me give you an example:
Subscribing to the EventBus:
var eventBus = sap.ui.getCore().getEventBus();
eventBus.subscribe("channel1", "event1", this.handleEvent1, this);
Of course you can name your channel and events as you wish. The third parameter indicates the function, that will be called in case of published events. The last paramter is the scope 'this' will point to in the given function.
Your handleEvent1 function could look like this:
handleEvent1 : function(channel, event, data) {
var listItem = data.listItem
}
Publishing events to the EventBus:
var columnListItem = ...
var eventBus = sap.ui.getCore().getEventBus();
eventBus.publish("channel1", "event1",
{
listItem : columnListItem
}
);
One more option you have is to make the columnListItems depending on a model. Like everytime it depends on your actual architecture and data.
Let me know if this solved your problem or if you need some more information.

Jeditable: how to set parameters based on dom element attributes

Often I find that I need to use jeditable on several areas each requiring different parameter settings.
For example I use jeditable with autosuggest input type, and then I need to pass different data sources to the different inputs.
I wanted to use just one instance of the editable plugin, and have tried to assign attr-values to the script, but obviously this does not work the way I'm approaching it..
I'm hoping someone can guide me a bit..
Essentially I would like to be able to set a jeditable parameter value based on the value of an ttribute of the dom element it is manipulating.
something like:
$('.editme').editable('savedata.php',{
loadurl : 'loaddata.php',
loaddata : { handle: $(this).attr('rel') }
});
then I could simply specify different load sources with:
<div id="fruits" class="editme" rel="myfruits">apples</div>
I didn't find the keyword this to work in this way..
How can I access the attributes of the dom element being manipulated dynamically for each jeditable binding?
here is another example of what I want to do:
authorsList = "".split(",");
// extend jeditable with autocomplete
$.editable.addInputType('autoc', {
element: function(settings, original) {
var input = $("<input />").autocomplete(settings.mdata, settings.autoc);
$(this).append(input);
return input; }
});
$('.editable.authors').editable('savedata.php',{
type : "autoc",
mdata : $(this).attr('rel'), // should hold the name 'authorsList'
onblur : 'ignore',
autoc : { multiple: true,
multipleSeparator: ',' },
loadurl : 'loaddata.php',
loadtype : 'POST',
loaddata : {handle: function(){ return eval($("#objhandle").val())}, lookuptype: 'mirror'},
submit : 'save',
cancel : 'cancel',
tooltip : "Click to edit",
style : "inherit",
cssclass : 'jedi',
id : "field",
name : "data",
submitdata : {
storetype: 'mirror',
handle: function(){return eval($("#objhandle").val())},
timestamp: function(){return eval($("#objtimestamp").val())}
}
});
Warning, totally untested code but something like following should work:
$('.editme').each(function() {
$(this).editable('savedata.php',{
loadurl : 'loaddata.php',
loaddata : { handle: $(this).attr('rel') }
});
});
This way the score of this should be correct when initializing Jeditable on the element.
this worked for me
$(this).data('rel)
and for the html
<div id="fruits" class="editme" data-rel="myfruits">apples</div>