Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table method getRows() returns only visible Rows #393

Closed
JenniferKiesel opened this issue Apr 10, 2015 · 18 comments
Closed

Table method getRows() returns only visible Rows #393

JenniferKiesel opened this issue Apr 10, 2015 · 18 comments

Comments

@JenniferKiesel
Copy link

In my use case I wanted to get the selected indices and the related rows. So I used the methods getSelectedIndices() and getRows(). But to my utter surprise I only get the actual visible rows, but the indices are the "real" indices (so when scrolled down they start fortunately NOT with 0).

In my opinion this is a bug, because working with indices and the rows becomes useless. Also the method should be called "getVisibleRows()" or something similar to make it clear.

Actual I use "the workaround" that I use the indices with my related model.

OpenUI5 version:
1.24.2

Browser/version (+device/version):
Google Chrome 41.0.2272.118 (64-bit)

Any other tested browsers/devices(OK/FAIL):
Firefox 37.0.1

Steps to reproduce the problem:

  1. Open the JSBin example
  2. Click the button and look into the console
  3. Scroll the table down, click the button and look into the console again
    http://jsbin.com/pujokiyusa/1/edit?html,console,output

What is the expected result?
getRows() should return ALL rows

What happens instead?
It returns only the displayed rows

@sirion
Copy link
Contributor

sirion commented Apr 15, 2015

Hi Jennifer,

you can currently use the getContextByIndex-method to get the row-context for all rows regardless of whether they are visible or not. https://sapui5.netweaver.ondemand.com/sdk/#docs/api/symbols/sap.ui.table.Table.html#getContextByIndex

I will contact the control owner to get more information on this and get back to you.

Internal reference: 1570147881

@SebastianRied
Copy link
Contributor

Hi Jennifer,
we are currently updating the documentation. I'll include your feedback and will try to make it clear, that getRows() only returns the visible rows.

When you only use client-models, you can go with getContextByIndex().

When you use OData models there are a few things to consider:
Due to paging and lazy loading of the table content it's quite difficult to return "all" rows with an API call since it might be the case that not all records are loaded yet. This might even be the case when using getContextByIndex. While this works nicely when all records are at the client, the method might return undefined and trigger a request for this single entity in order to load the missing entity. This can happen in select-all scenarios. I'd propose to process select-all scenarios in the backend, rather than loading all contexts to the client and then sending them back to the backend in order to perform an action.

If you require all data at the client, you might want to use the getContext method of the underlying (OData)ListBinding. It accepts start index, length and a threshold as parameters and will load the requested section from the backend or just return it if all is loaded. You need to register to the change event of the binding. This event will get fired when the model has finished loading.

@joeybronner
Copy link
Member

joeybronner commented Apr 1, 2017

Hi,

Can you please update the openui5 documentation https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.table.Table.html#getRows ?
I lost time to understand why I only get visible rows with the getRows() method... until I found this post.

Thank you guys.

@sonjadeissenboeck
Copy link

sonjadeissenboeck commented Oct 4, 2018

These methods are not working for me. I'm looking for a way to loop through the cell content for all of the cells. @SebastianRied @sirion
With getContextByIndex() or _getContext() I can't access the getText() method of the rows, I only get the constructors for each of them.
Is there another way for accessing the content?

@kak00n
Copy link

kak00n commented Nov 27, 2018

Hello,

If I need to know the selected indices (in collapse or expanded elements, both), it's not possible. getContextByIndex() need a parameter to return data. This solution not resolved the problem of the thread.

Regards.

@sfdfklskldf
Copy link

So the table is for "big amount of data" but mass change does not work well?

What would be the correct solution to mass change for example 2000 entries? A function import? How should it work with the information of ".getSelectedIndices()"? Frontend could be sorted somehow and also user could uncheck some entries.

@davidconvista
Copy link

I found myself in the same situation. If I want to delete all entries in the table I need to set the table threshold to a number higher than the number of entries, in order to preload them beforehand and being able to get the context afterwards and calling remove for each entry path.

This seems innapropiate to me, because I now have 2000 entries, but i could be having several thousands more...

I thought about the idea of creating a function import for mass deletion, checking whether the select all is active or not, but what if the user selects all and afterwards deselects one?

Is there gonna be any solution to this?

Thank you

@TeeOlee
Copy link

TeeOlee commented Jan 23, 2020

I thin it is still open in SAP Ui5 16013... It says ...

"Gets content of aggregation rows.
Rows of the Table"

Yeah well but only gets the visible rows.

getSelectedIndices() returns all Indices but nothing else like the data/key of the row... Now im more or less blind on what rows the user has marked(selected) ,... My idea was to match the index with the rows to get the selected row

var oTab = this.getView().byId("tblAdminMaint");
var oRows = oTab.getRows();

		if (oTab) {
			var oSelRows = oTab.getSelectedIndices();
			if (oSelRows) {
				for (var i = 0; i < oSelRows.length; i++) {

					for (var ii = 0; ii < oRows.length; ii++) {
						if (oRows[ii].getIndex() === oSelRows[i]) {
							var oSource = this.getView().getModel().getProperty(oRows[ii].getBindingContext().sPath);
							if (oSource) {
								// do something
							}
						}
					}

				}
			}
		}

	}

Do we have any other solution to read all currently selected rows(with data also not visible) ?

Thanks in advance

@TeeOlee
Copy link

TeeOlee commented Jan 23, 2020

I now found a solution for me...

  1. Load all data at once by setting threshold="20000000" of the table to a high number
  2. Access aKeys to retrieve the object that was selected i.e. path

testItemsSelected: function (oEvent) {

		var oTab = this.getView().byId("tblAdminMaint");
		// var oRows = oTab.getRows(); //Does not work, only returns visible rows
		var oRows = oTab.getBinding().aKeys; //this is returning the array with keys excalctly haveing same sorting/filtering and can be accessed via index
		var sSelected = "";

		if (oTab) {
			var oSelRows = oTab.getSelectedIndices();
			if (oSelRows) {
				for (var i = 0; i < oSelRows.length; i++) {

					var oRow = this.getView().getModel().getObject("/" + oRows[oSelRows[i]]);
					if (oRow) {
						sSelected = sSelected + oRow.Prototypematnr + ";"; //Prototypematnr = any attribute of your row/model
					}

				}

				sap.m.MessageToast.show(sSelected);
			}
		}

	}

@AnuradhaSharma000111
Copy link

Hi TeeOlee,
As per your solution, it is showing a simple Table not a smart table.
so, when we need to show number of columns that time it is not possible to show.

@AnuradhaSharma000111
Copy link

Still, I am finding some solutions for this.

@AnuradhaSharma000111
Copy link

Hi,
I think I got the solutions.

<smartTable:SmartTable id="LineItemsSmartTable" header="Smart Table" showRowCount="true" useVariantManagement="true" useTablePersonalisation="true" enableAutoBinding="true" entitySet="DATA" tableType="ResponsiveTable" initiallyVisibleFields="Column1,Column2,Column3" smartFilterId="smartFilterBar">

//START
<gt:Table enableColumnFreeze="true" id="TableId" threshold="10000" selectionMode="MultiToggle" visibleRowCount="7" columnHeaderHeight="40" rowHeight="50"/>
//END
</smartTable:SmartTable>

##Just add code written between START and END to your table and use the same table Id= “TableId” to get your selected Column.
If you are working on multiple selection you can use the below code:
var oList = this.getView().byId("TableId");
var aSelectedIndex = oList.getSelectedIndices();
var TableDataArray = [];
for (var i in aSelectedIndex) {
var Selectedrow = oList.getModel().getProperty(oList.getContextByIndex(oList.getSelectedIndices()[i]).sPath);
TableDataArray.push(Selectedrow);
}

@EricVanEldik
Copy link

EricVanEldik commented Nov 15, 2022

For anyone comming across this problem I used this the get the actual number of rows visible, but this can also be used to read the rows.

const table = this.getView().byId("MaterialTable");
table.setVisibleRowCount(table.getBinding("rows").getLength());
const oBinding = table.getBinding("rows"); 
oBinding.attachChange(function() {
            table.setVisibleRowCount(oBinding.getLength());
});

@ThomasChadzelek
Copy link
Member

This looks a bit weird to me. The 2nd line is essentially the same as the event handler. What are you trying to achieve thereby?

Maybe https://openui5.hana.ondemand.com/api/sap.ui.model.ListBinding#methods/getAllCurrentContexts is what you are looking for?

@EricVanEldik
Copy link

This looks a bit weird to me. The 2nd line is essentially the same as the event handler. What are you trying to achieve thereby?

Maybe https://openui5.hana.ondemand.com/api/sap.ui.model.ListBinding#methods/getAllCurrentContexts is what you are looking for?

The second line is to initialize, because attachChange is only called on a change.

@leonikussmaul
Copy link

Hi,

Another quick workaround that might fit some use cases is to simply bind the visibleRowCount property of the table to the model that has the table data stored and calculate the length using expression binding. This way avoids any complicated JS code and handles the calculation directly in the XML view.

visibleRowCount="{= ${tablemodel>/rows}.length }"

In this example i have stored the data for the rows inside the rows property of my JSON Model "tablemodel". Now getRows() returns all the rows which can be useful at times. In my use case, i needed to apply custom css to specific table cells and this was the only way that worked. However, it might not be the best approach for a large dataset.

@Vidal-Exxon-JM
Copy link

Vidal-Exxon-JM commented Mar 2, 2023

I have a question leonikussmaul, how can I set the visible row count from the controller? Because initially I am displaying the TreeTable empty, and when the filters are populated, then with bindRows I am populating the table

This is my code and is not working the parameter visibleRowCount
new Promise(function (resolve, reject) {
oTableTree.bindRows({
path: "/FieldsSet",
filters: that.makeFilters(),
parameters: {
expand: "JoinClauseSet",
countMode: "Inline",
numberOfExpandedLevels: 1,
operationMode: "Client",
editable: true,
json: true,
visibleRowCountMode: "interactive",
visibleRowCount: "FieldsSet>rows.length",
useServersideApplicationFilters: true
}
});
}).then(that.changeVisibility(true));

Thanks a lot for the help, really appreciate it

@leonikussmaul
Copy link

leonikussmaul commented Mar 2, 2023

Hi @Vidal-Exxon-JM,

Have you tried calling the method setVisibleRowCount()?

Something like this in your controller..

var aRows = oTableTree.getRows().length;
oTableTree.setVisibleRowCount(aRows);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests