JSF dataTable to display a fixed number of rows - datatable

Greetings,
The context is myFaces 2.0.2, possibly also adding Tomahawk 20-1.1.10
I have created a dataTable (currently an h:dataTable, but could also be a t:dataTable using Tomahawk) displaying certain attibutes of a List<MyObject> in a backing bean. I have paging by returning only a subList of the List, and also sorting by click of column headers.
The next thing I need to do is ensure the table always shows a fixed number of rows. For example, if my page size is 5 and I have 12 items in the List, I need page three to show the last two items, plus 3 blank rows.
I have tried to "pad" the subList with both nulls and instances of myObject with null values, but this led to ConcurrentModificationException when hitting the last page of the table (the view was trying to getDisplayList even as the paging method was still adding the extra values.). I then tried padding the main list in the same manner, but then got NullPointers on my sort functions (a no-brainer in hind sight). Plus, these things are all addng overhead in the backer, when I would rather do this in the xhtml view.
(h:/t:)dataTable does have a rows attribute, but this specifies the maximum number of rows to display, not the minimum, as I need.
Ideas, please?

Don't pad the sublist. Pad the list. Preferably immediately after retrieving it in the bean.

The solution here was to pad the MAIN List, rather than the subList, using objects which are not null but whose attributes are null, and to add a null check into the Comparator:
if (obj1.getSomeValue() == null) {
return +1;
}
else if (obj2.getSomeValue() == null) {
return -1;
}
else {
// primary sorting code
}
Which ensures null items always come last. Works perfect.
BalusC did give me the push in the right direction, so I am accepting his answer.

Related

Google Sheets - How to Combine Filter Function with Filter View

I've been working on a spreadsheet with over 100 rows, and found a hacky way to incorporate a "hide" checkbox that will hide any row where column C matches a specific value (building type), specified beside the box. To do this, I first created a function like this: =FILTER(Data!A1, OR(Data!$C1<>$O$2, $P$2)) and dragged that across every row and column in a seperate sheet. This reads as, "Display current cell if the corresponding column C in that row in Data does not match the building type, or if the the checkbox is checked. This way, the whole row is hidden when the building type matches, and the box is unchecked. A1 adjusted to each row individually, $C1 referenced the building's type, $O$2 referenced the targeted type to potentially hide, and $P$2 was the checkbox.
Problem #1: This created a lot of formulas in hundreds of cells, and when the building type was not found, it displayed #N/A across the entire row. A Filter View was able to hide these values, but it was inconvenient to have to reset the values every time I wanted to hide or unhide another building type.
My Attempt to Fix: I used a filter function once again to recreate the entire sheet from one cell, hiding the appropriate rows, using this: =FILTER(Data!A2:J191, ARRAYFORMULA((Data!$C2:C191<>$O$2)+(Data!D2:D191*$P$2)) This is the hacky part. I multiplied the checkbox's "true" by an array arbitrary positive numerical values in the D column to "OR" it with each building type value to achieve the same goal as before, but for EVERY cell.
Problem #2 arose: When I get my beautiful sheet, I can not sort it via a filter view, or it will throw an error and display nothing. I'm resorting to sorting the original tab, but intend to have it be ignored entirely. So how do I combine these two, Filter View, and Filter Function, to create a nice spreadsheet where I can SORT AND HIDE rows?
Bonus Problem #3: To add more buttons, my formula is this: =FILTER(Data!A1:J191, ARRAYFORMULA((Data!$C1:C191<>$O$2)+(Data!D2:D192*$P$2)), ARRAYFORMULA((Data!$C1:C191<>$O$3)+(Data!D2:D192*$P$3)), ARRAYFORMULA((Data!$C1:C191<>$O$4)+(Data!D2:D192*$P$4)), ARRAYFORMULA((Data!$C1:C191<>$O$5)+(Data!D2:D192*$P$5)), ARRAYFORMULA((Data!$C1:C191<>$O$6)+(Data!D2:D192*$P$6)), ARRAYFORMULA((Data!$C1:C191<>$O$7)+(Data!D2:D192*$P$7)), ARRAYFORMULA((Data!$C1:C191<>$O$8)+(Data!D2:D192*$P$8)), ARRAYFORMULA((Data!$C1:C191<>$O$9)+(Data!D2:D192*$P$9))) This is ugly, and very slow to load. Is there a way to create a function range to handle the same checks on multiple rows, and crunch it into a single formula?
Here is another monstrosity (this one has less repetition) for you:
=QUERY(
{IGNORE!A2:J, IGNORE!P2:P},
"SELECT * "
& "WHERE Col3 is not null "
& IF(COUNTIF(P2:P9, False) = 0, "", "AND NOT Col3 MATCHES '^" & JOIN("$|^", IFNA(FILTER(O2:O9, P2:P9 = False))) & "$' ")
& IF(COUNTIF(A2:K2, ">0") = 0, "", "ORDER BY Col" & JOIN(", Col", IFNA(FILTER(COLUMN(A2:K2) & IF(COLUMN(A2:K2) = 1, "", " DESC"), A2:K2)))),
0
)
Your checkboxes should remain. The second row can have just True/False values, no need for column number (a simple change will be needed COUNTIF(A2:K2, ">0") -> COUNTIF(A2:K2, True)). Also consequent sort works now (but only in the actual order of columns: if checked 1, 3, 4 then it will be sorted first by 1, then by 2, then by 4). You could place another config table on the right about sorting, where you would select all the columns you wish to sort by, their mutual order, and desc/asc for them.
Edit: added IFNA so FILTER won't return an error, changed multiple ANDS to MATCHES and simple regexes.

QTP UFT How to find a row number and column number? Angular JS

When I spy the table it shows just browser - Page - WebElement and also UI is developed in Angular JS.
I there any way to find row number and column number? By the way I am using UFT/QTP
From the source-code's image which you have attached, it is quite evident that the webElement corresponding to the rows have class = "ui-grid-row ng-scope". So, you can make use of descriptive programming. I assume that you already have added the object Browser(...).Page(...) to your OR.
Set rowDesc = Description.Create
rowDesc("Class Name").value = "WebElement"
rowDesc("Class").value = "ui-grid-row ng-scope"
Set objRows = Browser(...).Page(...).ChildObjects(rowDesc)
rowCount = objRows.Count 'This variable should now contain the total number of rows"
Now, this is just an idea which you can give a try. If it works for you, you can further enhance it to get the column count. If there is no way you can get the column count, then you can get the total cell count using the same method. In that case, you just need to change the value of property "class" to the one mentioned in the Object Spy Image("ui-grid-cell-contents ng-binding ng-scope"). Now you have Row Count and Cell Count. To get the column count, you can divide cell count by row count.(Again, this will give you correct answer ONLY IF there are same number of columns for each of tbe rows).

dhtmlxgrid addRow() unusual behavior on checkbox

I am trying to add rows to a grid using dhtmlx in java, following is the code.
var combinedColumn = "displayText";
displayOptionsGrid.addRow(selectedID, [ displayOptionsGrid.getRowsNum() == 0 ? 1 : 0, combinedColumn]);
What the function is supposed to do is that if the number of rows is zero it adds the first row as checked and then the rest as unchecked. The error which I am facing is, I delete the rows one by one and try to re-add the rows in the same session with some other row at first than the row I added previously, but can't. I can only add the row which I added first previously as the first row.
When I use grid.clearAll() it works fine. Can someone tell me the exact thing we do in clearAll() which we don't in deleteSelectedRows() in dhtmlxgrid. Thanks.
Please, check your selectedID attribute.
Note that each row should have a unique id, so adding a row with the id existing in your grid will break the grid.

Errors when grouping by list in Power Query

I have a set of unique items (Index) to each of which are associated various elements of another set of items (in this case, dates).
In real life, if a date is associated with an index, an item associated with that index appeared in a file generated on that date. For combination of dates that actually occurs, I want to know which accounts were present.
let
Source = Table.FromRecords({
[Idx = 0, Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}],
[Idx = 1, Dates = {#date(2016,2,1), #date(2016,2,2), #date(2016,2,3)}],
[Idx = 2, Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}]},
type table [Idx = number, Dates = {date}]),
// Group by
Grouped = Table.Group(Source, {"Dates"}, {{"Idx", each List.Combine({[Idx]}), type {number}}}),
// Clicking on the item in the top left corner generates this code:
Navigation = Grouped{[Dates={...}]}[Dates],
// Which returns this error: "Expression.Error: Value was not specified"
// My own code to reference the same value returns {0,2} as expected.
CorrectValue = Grouped{0}[Idx],
// If I re-make the table as below the above error does not occur.
ReMakeTable = Table.FromColumns(Table.ToColumns(Grouped), Table.ColumnNames(Grouped))
in ReMakeTable
It seems that I can use the results of this in my later work even without the Re-make (I just can't preview cells correctly), but I'd like to know if what's going on that causes the error and the odd code at the Navigation step, and why it disappears after the ReMakeTable step.
This happens because when you double click an item, the auto-generated code uses value filter instead of row index that you are using to get the single row from the table. And since you have a list as a value, it should be used instead of {...}. Probably UI isn't capable to work with lists in such a situation, and it inserts {...}, and this is indeed an incorrect value.
Thus, this line of code should look like:
Navigate = Grouped{[Dates = {#date(2016,1,1), #date(2016,1,2), #date(2016,1,3)}]}[Idx],
Then it will use value filter.
This is a bug in the UI. The index the UI calculates is incorrect: it should be 0 instead of [Dates={...}]. ... is a placeholder value, and it generates the "Value was not specified" exception if it is not replaced.

Efficient way to delete multiple rows in HBase

Is there an efficient way to delete multiple rows in HBase or does my use case smell like not suitable for HBase?
There is a table say 'chart', which contains items that are in charts. Row keys are in the following format:
chart|date_reversed|ranked_attribute_value_reversed|content_id
Sometimes I want to regenerate chart for a given date, so I want to delete all rows starting from 'chart|date_reversed_1' till 'chart|date_reversed_2'. Is there a better way than to issue a Delete for each row found by a Scan? All the rows to be deleted are going to be close to each other.
I need to delete the rows, because I don't want one item (one content_id) to have multiple entries which it will have if its ranked_attribute_value had been changed (its change is the reason why chart needs to be regenerated).
Being a HBase beginner, so perhaps I might be misusing rows for something that columns would be better -- if you have a design suggestions, cool! Or, maybe the charts are better generated in a file (e.g. no HBase for output)? I'm using MapReduce.
Firstly, coming to the point of range delete there is no range delete yet in HBase, AFAIK. But there is a way to delete more than one rows at a time in the HTableInterface API. For this simply form a Delete object with row keys from scan and put them in a List and use the API, done! To make scan faster do not include any column family in the scan result as all you need is the row key for deleting whole rows.
Secondly, about the design. First my understanding of the requirement is, there are contents with content id and each content has charts generated against them and those data are stored; there can be multiple charts per content via dates and depends on the rank. In addition we want the last generated content's chart to show at the top of the table.
For my assumption of the requirement I would suggest using three tables - auto_id, content_charts and generated_order. The row key for content_charts would be its content id and the row key for generated_order would be a long, which would auto-decremented using HTableInterface API. For decrementing use '-1' as the amount to offset and initialize the value Long.MAX_VALUE in the auto_id table at the first start up of the app or manually. So now if you want to delete the chart data simply clean the column family using delete and then put back the new data and then make put in the generated_order table. This way the latest insertion will also be at the top in the latest insertion table which will hold the content id as a cell value. If you want to ensure generated_order has only one entry per content save the generated_order id first and take the value and save it into content_charts when putting and before deleting the column family first delete the row from generated_order. This way you could lookup and charts for a content using 2 gets at max and no scan required for the charts.
I hope this is helpful.
You can use the BulkDeleteProtocol which uses a Scan that defines the relevant range (start row, end row, filters).
See here
I ran into your situation and this is my code to implement what you want
Scan scan = new Scan();
scan.addFamily("Family");
scan.setStartRow(structuredKeyMaker.key(starDate));
scan.setStopRow(structuredKeyMaker.key(endDate + 1));
try {
ResultScanner scanner = table.getScanner(scan);
Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important !
List<Delete> deletes = new ArrayList<Delete>();
int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer
int counter = 0;
while (entityIterator.hasNext()) {
if (counter < bufferSize) {
// key maker is used to extract key as byte[] from my entity
deletes.add(new Delete(KeyMaker.key(entityIterator.next())));
counter++;
} else {
table.delete(deletes);
deletes.clear();
counter = 0;
}
}
if (deletes.size() > 0) {
table.delete(deletes);
deletes.clear();
}
} catch (IOException e) {
e.printStackTrace();
}

Resources