sap.ui.table.Table "VisibleRowCountMode.Auto" mode does not work - sapui5

I'm having trouble setting the number of rows for a table to automagically fill the available estate of its encapsulating container.
According to the API, setting the visibleRowCountMode property to sap.ui.table.VisibleRowCountMode.Auto should render the table to
"[...] automatically fills the height of the surrounding container.
The visibleRowCount property is automatically changed accordingly. All
rows need the same height, otherwise the auto mode doesn't always work
as expected."
I have used the following code:
var oTable = new sap.ui.table.Table( {
rowHeight : 30,
height : "100%",
// The below property is seemingly ignored... What did I do wrong?
visibleRowCountMode : sap.ui.table.VisibleRowCountMode.Auto
});
...but as you can see in this jsbin example http://jsbin.com/vazuz/1/edit it just shows the default 10 rows, and certainly doesn't "change the visibleRowCount property accordingly" :-(
Anyone has a solution?
Thanks in advance!
=====================
EDIT: Thanks to #matz3's answer below, I was ultimately able to solve this issue.
Setting the surrounding container DIV to 100%, this seems to be ignored. Setting it to a fixed height, however, worked just fine. But what I really wanted, if a user resized the window, the number of available rows needs to be adjusted accordingly. Setting it to a fixed height is therefor not an option...
However, the trick was in some extra CSS: not only the DIV needed to be set to 100% height, also both BODY and HTML (!!) needed to have a height set to 100%:
html, body {
height: 100%
}
div#uiArea {
height: 100%
}
Now, the table spans the full height of the available viewport, and resizing the window adjusts the table rather nicely. See the final working solution here: http://jsbin.com/bosusuya/3/edit
Matz3, thanks for your help!

CSS hacks is a dirty way. In my application I use to bind visibleRowCount to Array.length
For example, if you have model with this data:
[{firstName: 'John', lastName: 'Smith',
{firstName: 'David', lastName: 'Ericsson'}]
You can bind to Array property length like this:
var oTable = new sap.ui.table.Table({
visibleRowCount : '{/length}'
})

[...] automatically fills the height of the surrounding container [...]
Your surrounding container is the view, so you have to set the height of it also to a value (e.g. 100%)
this.setHeight("100%");
And your view will be set into the uiArea-div, so this one also needs a height (e.g. 500px)
<div id="uiArea" style="height:500px"></div>
With these changes it now works as expected

I'm with the same issue. I "resolve" that in this manner. This is not perfect, but it's better than UI5 resizing...
  _resizeTableRow: function () {
var oTable = this.getView().byId("referenceTabId");
var sTop = $('#' + oTable.getId()).offset().top;
var sHeight = $(document).height();
//if there a row, you can take the row Height
//var iRowHeight = $(oTable.getAggregation("rows")[0].getDomRef()).height();
var iRowHeight = 40;
var iRows = Math.trunc((sHeight - sTop ) / iRowHeight);
oTable.setVisibleRowCount(iRows);
   },

Other option is to put the Table in sap.ui.layout.Splitter:

Related

sap.ui.table.Table inside of Scroll Container: visibleRowCountMode=“Auto” not working

This is a follow-up question to this question. Basically, I have the same problem as described there where the table does not have as many rows as possible, there is more space there but it is unused.
I got it working for my table with the help of the answers in the last question. Now I had to adda horizontal Scroll-Container (the height is fixed) arround this table. Then the problem came up again.
I built a demo version with which you can see the problem and try arround with here.
The wanted result is just like as if you removed the ScrollContainer, then the table fills the entire page.
The same problem occurs when using this table inside of an IconTabBar but I was able to find an ugly work-around which does not work here. After the table was rendered I added the style height: 100% manually to the html-parents of the table (these are generated divs of the IconTabBar). This enabled the Table to receive the full height from its parents. With the ScrollContainer this tactic does not seem to work.
You can fix it like this:
onInit: function () {
this.oTable = this.byId("TableID");
this.oTable.onAfterRendering = function () {
const table = this.getTable();
const aColumns = table.getColumns();
for (let i = 0; i < aColumns.length; i++) {
aColumns[i].setProperty("width", "auto");
}
this.setHeight("100%");
};
}
And you may try these properties:
flexible: true/false,
resizable: true/false,
autoResizable: true/false,
width : "auto"
Please have a look at the restrictions of visibleRowCountMode="Auto"
https://ui5.sap.com/#/api/sap.ui.table.Table%23methods/getVisibleRowCountMode
See here the the layoutData definition for the HBox so that it gains the height from its parent
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
and also height: 100% style for the ScrollContainer's inner element which also let the table know the height of its container.

sap.ui.table.Table how to optimize column widths

I can't find this anywhere. In a sap.ui.table.Table control is it possible to tell it to resize all column widths so that their contents are fully visible? I don't see any property/method either on the table or column instances.
Is it not supported?
Many thanks.
You can use autoResizeColumn(colIndex) method
Option 1: setting fixed sizes of columns
var oTable = new sap.ui.table.Table({
width : "100%",
selectionMode : sap.ui.table.SelectionMode.None,
enableColumnFreeze : true,
});
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{Title}",
wrapping : true,
textAlign : sap.ui.core.TextAlign.Begin,
}),
enableColumnFreeze : true,
width : '350px', // also possible in % -> e.g. in ur case '100%'
}));
Option 2: resizable, but showing full column width, I would try to use these properties
width : sap.ui.core.CSSSize
flexible : boolean (default: true)
resizable : boolean (default: true)
like this
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{Title}",
wrapping : true,
textAlign : sap.ui.core.TextAlign.Begin,
}),
width : '100%',
resizable : false,
flexible : false,
}));
I think its a challenge, I also made it via fixed sizes .. eventually you can define fixed sizes depending on the screen size .. hope to help you.
I tried several ways but none was really working on 1.52.23 so I analyzed the way auto-resize is working on the double-click on the column separator. And found the hidden treasure: sap.ui.table.TablePointerExtension
This code does the trick for me:
var oTpc = new sap.ui.table.TablePointerExtension(oTable);
var aColumns = oTable.getColumns();
for (var i = 0; i < aColumns.length; i++) {
oTpc.doAutoResizeColumn(i);
}
This works for me:
my colums are:
flexible: true,
resizable: true,
autoResizable: true,
width : 'auto'
$($.find('.sapUiTableColRsz')).trigger("click");
For me, I need to do the call to "autoResizeColumn" after the data is received. You can attach to the binding dataReceived event
While facing the same issue, I found the solution in the sap.m.Table control. Using the "fixed layout" option (set value to false, see documentation attached), you can force the columns/cells to resize according to its content (same effect like in ALV grid controls). The feature is described very well in the API reference: sap.m.Table / setFixedLayout
var oTable = new sap.m.Table({
fixedLayout: false
});
Defines the algorithm to be used to layout the table cells, rows, and columns. By default, a table is rendered with fixed layout algorithm. This means the horizontal layout only depends on the table's width and the width of the columns, not the contents of the cells. Cells in subsequent rows do not affect column widths. This allows a browser to layout the table faster than the auto table layout since the browser can begin to display the table once the first row has been analyzed.
When this property is set to false, sap.m.Table is rendered with auto layout algorithm. This means, the width of the table and its cells depends on the contents of the cells. The column width is set by the widest unbreakable content inside the cells. This can make the rendering slow, since the browser needs to read through all the content in the table before determining the final layout. Note: Since sap.m.Table does not have its own scrollbars, setting fixedLayout to false can force the table to overflow, which may cause visual problems. It is suggested to use this property when a table has a few columns in wide screens or within the horizontal scroll container (e.g sap.m.Dialog) to handle overflow. In auto layout mode the width property of sap.m.Column is taken into account as a minimum width.

nvd3 space between bars

I've made a MultiBarChart with NVD3.
It works, however, a colleague said I needed more space between each Australian state.
So, Tasmania further from Victoria etc.
Here is the data visualisation
I can not find a forum that explains this in non-developer language. I'm not a developer, but having a go.
Here is my code...
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarHorizontalChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.margin({top: 30, right: 105, bottom: 30, left: 103})
.tooltips(true)
.showControls(false);
chart.yAxis
.tickFormat(d3.format(',.1f'));
d3.select('#chart1 svg')
.datum(long_short_data)
.transition().duration(1400)
.call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
Thanks you super kind and smart people!
No Need to use too much code for spacing just use below code :
var chart = nv.models.multiBarChart();
//added by santoshk for fix the width issue of the chart
chart.groupSpacing(0.8);//you can any value instead of 0.8
This is unfortunately something you can't configure in NVD3. However, you can change the height of the bars after the chart has been created to make it appear as if there's more space between them. The code to do this is simple:
d3.selectAll(".nv-bar > rect").attr("height", chart.xAxis.rangeBand()/3);
The default height is chart.xAxis.rangeBand()/2 -- you can adjust this as you see fit. The only thing to keep in mind when running this code is that NVD3 animates its elements, so not everything will be there in the beginning or values may be overwritten. You can solve this by waiting a small amount of time before calling that code using setTimeout:
setTimeout(function() {
d3.selectAll(".nv-bar > rect").attr("height", chart.xAxis.rangeBand()/3);
}, 100);
Just found this question while searching for a way to add more space between bars. Like Lars said, you can change the bar size after the chart has been drawn. However, when you increase the bar height without changing the space between each bar, it overflows. To add space between the bars you should use xRange:
var chart = nv.models.multiBarHorizontalChart().xRange([0, 125])

Make Firefox Panel fit content

I'm manually porting an extension I wrote in Chrome over to Firefox. I'm attaching a panel to a widget, and setting the content of that panel as an HTML file. How can I make the panel shrink and grow with the content? There's a lot of unsightly scroll bars and grey background right now.
var data = require("self").data;
var text_entry = require("panel").Panel({
width: 320,
height: 181,
contentURL: data.url("text-entry.html"),
contentScriptFile: data.url("get-text.js")
});
require("widget").Widget({
label: "Text entry",
id: "text-entry",
contentURL: "http://www.mozilla.org/favicon.ico",
panel: text_entry
});
Not setting the height property of the panel makes it quite tall.
You might want to check out this example that resizes the panel based on the document loaded. If you want to resize based on changes to the content size, at least on initial load:
https://builder.addons.mozilla.org/package/150225/latest/
( sorry for the delay in respinding, been afk travelling )

Titanium.UI.Label property height

In my code I am doing this:
var taskLabel = Ti.UI.createLabel({color:'#777', top:3, textAlign:'center', height:'auto', text:task.title});
Ti.API.info('Next info is: taskLabel.height');
Ti.API.info(taskLabel.height);
But, the output from this is:
[INFO] [123,883] Next info is: taskLabel.height
And nothing more, it looks like it breaks silently, but I guess it shouldn't, based on the API.
I am trying to sum some heights of the elements, but I would prefer it behaved like html postion:relative. Anyway, I'd like to read the height in float, how can I achieve that?
You need to set a fixed width when you use an auto height. For example:
var taskLabel = Ti.UI.createLabel({color:'#777', top:3, textAlign:'center', height:'auto', width: 200, text:task.title});
you are not going to get the height until it is actually rendered and added to view or window.
You cant read the height property off like that, if you didn't manually define it.
It has to be added to a view, and then displayed (assuming it doesn't auto display) before Titanium will return anything about the height.
var window = Ti.UI.createWindow();
var taskLabel = Ti.UI.createLabel({color:'#777', top:3, textAlign:'center', height:'auto', text:task.title});
window.add(taskLabel);
window.open();
Ti.API.info('Next info is: taskLabel.height');
Ti.API.info(taskLabel.height);
That should work to show the height.
This should work.
var lbl_obj = Ti.UI.createLabel( { height: 'auto', text:'Test Label', top:10 } );
var height = lbl_obj.toImage().height;
Ti.API.info(height);