Vaadin 23 proper usage of nested layouts - vaadin

Typically, when I need to present some information, I use VerticalLayout (VL) as a main container and many of nested HorizonalLayouts (HL). I may be wrong, but I feel that this is not a very effective way to organize the information. I suppose I may achieve the same without nesting of such amount of HorizonalLayouts.
For example, I need to present user info with 100 lines, each line will have 5-10 spans. Typically, with my current approach, I'll create 1 VL and 100 HL for that.
Is there a more effective way to present this information other than nesting 100 HL into VL ?

You're absolutely correct about that – the main inefficiency being that HorizontalLayouts are a bit heavier than plain html elements that would probably do the job just fine.
There are many different ways to approach this, but I'm going to assume that you're basically rendering a table where you want each element to line up in neat columns.
HTML has the <table> element for that, but unfortunately Flow does not have an API for doing <table>s easily.
The easiest way is probably to use this add-on that provides such an API: https://vaadin.com/directory/component/html-table/overview
Other ways would be to e.g. use Divs for tables, rows and cells instead. Divs can be made to render as those elements by applying the appropriate display css values table, table-row and table-cell. These can be applied via classnames or the Style API in Flow:
Div cell = new Div();
cell.getStyle().set("display", "table-cell");

Related

How do I force the SmartTable to load all items?

My SAP UI5 view contains a SmartTable that is bound to an entity set in an ODataModel in read-only mode.
The table limits the number of items it displays to 100, verifiable by the ?$top=0&$limit=100 parameters it appends ot the data query to the server.
However, my users would like to have the table load and display all items, without paging or having to press some "More" button.
Is there a way to override the SmartTable's default behavior? For example by setting some growingSize property to "Infinity"? Or by modifying the aggregation binding? Or by adding annotations to the OData service?
Since you did not specify the number of expected items or the table you're using here are some general considerations and a few possible solutions.
The type of table
There are a few things to consider between the varying types of tables you can use, there is some advice of SAP itself from the design guidelines:
Do not use the responsive table if: You expect the table to contain more than around 1,000 rows. Try using the analytical table or grid table instead; they are easier to handle, perform better, and are optimised for handling large numbers of items.
Ways around it
First option I can think of, if you're using a responsive table and you expect less than 1000 rows then the scroll to load feature might be of interest which should load more entries when the user reaches the bottom of the current list.
There are ways to increase the default size of 100, both through the table using the growingThreshold property, or through the declaration of the oData model using the sizeLimit
If you're using a grid table then the scroll-to-load works slightly differently, since it doesn't display all rows at the same time. Instead, it destroys the current lines to display new lines, which is why it's recommended for (very) large datasets.
Second, if none of those solutions work for your users you could alternatively first fetch the count of the current list including filters, so you can set an accurate threshold on the table before displaying results. If done correctly, your oData service should return a count using /myserivce/MyEntity/$count?$filters... when queried. CDS does this automatically, older services will need to implement that separately.
Last, if you know the list never exceeds a certain number of lines, you could set the growingThreshold parameter on the table to that number and then you don't have to worry about fetching an accurate count first.
How all of this is implemented depends a bit on how you create the smart table (elements, manually etc) so I'm not sure how to provide usable example code
You can achieve this by using a formatter function which will return how many entries are within your model.
<SmartTable growingThreshold = "{path:'yourModel>/', formatter:'.formatter.sizeCalculator'}">
In the formatter File, which is usually to find in the model folder:
sizeCalcualtor: function(oModel){
let count = 0;
for(let i in oModel){
//add item to count;
}
return count;
}

Strategy for Requirements Traceability Matrix in DOORS

I want to create a traceability matrix in a new module that shows the object ID & text at the top level, then in columns moving to the right the object ID & text for the source of the first in-link, and then it's in-links to the right, etc. If there is more than one in-link, the next source object will be shown on the next line (new object), and the higher level object ID & text just repeated in the columns to the left. Basically, it is the recursive trace analysis layout dxl, but I want to spread out the information over separate columns.
My question is related to the best practices for approach. Is it best to create a new module and write several dxl layout scripts for each column, pulling info from all of the various modules, and then later converting it to text (so it isn't too heavy)? Or is it necessary (or easier) to actually create dxl attributes within each requirements module, and then pull information from there into my RTM module?
I'm likely over-complicating it, but any tips would be appreciated!
Well, one of our assets contains something that looks like your approach:
script creates new modules that only contains trace information, a "report" module, which does not contain any link to the original "data" modules
there are some 2 or three columns for each Req Level (high level reqs at the left, low level reqs at the right)
the advantage of this approach is that one can easily use standard DOORS filtering mechanisms to find "holes" in the matrix (requirements which have not been implemented, design elements without requirement etc.). plus, as every report run creates a new report module with the date/time in its name, project progress can be made visible over time, reports to excels might be made.
On the other hand the implementation took several weeks. So, I don't know if this approach would be feasible for you.

How best to design and implement a page elements model, and it's logic?

In order to keep my views as uncluttered as possible I’m removing all logic that determines the state/appearance of 'dynamic' page elements, ie highlighting selected items, greying out buttons that are not context relevant, etc. etc.
Htmlhelpers will be used for this. What I'm not so sure about is where to place the model for the page elements whose state is 'dynamic', and the logic that processes them before they hit the htmlhelper.
Can this be incorporated directly into a page’s viewmodel, or should it be separated out and into it’s own class. I can’t see any advantage to the latter approach, but I'm asking now before I commit myself to a path I may regret having taken further on down the road, as has happened before. …
Can this be incorporated directly into a page’s viewmodel, or should
it be separated out and into it’s own class
If I understand you correctly, then your question is something like this -
I have 10 person objects, out of 10 (this can change in future say 20 persons or etc, so this is dynamic) persons, I have 6 males and 4 females (this proportion also changes dynamically). And out of 6 males, one is physically disabled (this too changes with time, so dynamic). So questions are -
Where do we have logic to identify given a person male or female?
Where do we have logic to identify given a person is physically disabled or not?
Where do we apply proper style to Physically disabled person?
If I am right with your understanding, then my answer would be as follows -
The logic for (1), (2) would be your Model classes. Then when you construct your ViewModel from Model classes (though constructing ViewModel from Model is not necessary, assuming you are having ViewModels), those corresponding properties from Model should be persisted in ViewModel. There might be some complex calculations required in some cases, then that specific calculations (provided those calculations are worthy for business) needs to be gone into business logic layer. But if there are calculations like formatting numbers, rounding precisions, convert upper to lowercase etc., they they are specific to View, so that calculations needs to go into View Models.
For (3), I would say I will have that logic in View itself. A simple ternary operator in Razor would be more appropriate for this calculation. I wouldn't take any code related to styles (or its related) to Controller Actions and neither to business logic layer.
HTH!
UPDATE1
Example: Page has 7 buttons to be switched on or off, and styled,
according to the status of an invoice. The viewmodel processes the
logic for the button model and the view will pass this to the custom
htmlheper button. M question is, does this approach, of including
processing logic in the view-model, have a flaw? No processing, either
complex or reusable, will occur. (3) CSS styling can be included in
the view using ternaries but if tag.addcssclass can do this, isn't
this a better solution, both tidier and OOP compliant?
Processing logic in ViewModel is fine, but at the same time debatable. At least in my perspective like this -
Want to show different color for different status of invoice? Then Status calculation logic will reside in Business logic layer.
Want to show different color for different range of amounts on invoices? Then categorizing invoices into different group of colors will be done by ViewModel Logic.
Want to show different formatted money display? then that logiv (either setting up proper culture or using String.Format()) would be going into HtmlHelpers or Views.
Coming to you second point with example of tag.addcssclass, I wouldn't do it that way. Usually we will have different set of people for designing, CSS & HTML coding, backend developers. Taking CSS into backend (I mean at least in C# code in ViewModels) is fine for small changes and also this approach is good for code which is getting repetitive (at least throgh HTML Helpers), but for larger chunks (like adding CSS classes based on different scenarios for different fields in ViewModels), it will be hard to maintain between different sets of people who are involved. Also in my perspective, it will hard to understand over period of time.

jQuery UI Sortable “Keep Together”?

I have a list of elements that work fine with jQuery UI sortable, but now I want to be able to group some adjacent siblings together. Is there a direct way of doing that, similar to the way a rich-text document has a keep-together or keep-with-next attribute on paragraphs?
For example, if I have items 123456, what’s the best way to keep 2 & 3 together, so that a) If I drag either 2 or 3, then they move together and b) It's not possible to drop something between 2 and 3?
My solution was to add a wrapper around the grouped elements with help from jQuery methods replaceWith() to remove the wrapper and wrapAll() to wrap the group. This requires some juggling if what you start with expects the individual elements to be direct children, but if you're referencing those elements by a class selector, it should go pretty easily.
I also wanted to be able to optionally lock the first and last items in place, and the solution there was to get a subset of the direct children and omit or include the first/last elements via slice().
If there's enough interest from anyone other than me, I’ll post some example code fragments.

Multiple Expanding Nodes in Virtual TreeView possible?

I am using a TVirtualStringTree (part of the Virtual TreeView Component) in my Delphi project and I would like to create a view where 2 columns can have children that are expandable/collapsable with [+] sign.
In the picture below as sample I would like to have a [+] sign in the Server Column but also in the Image column. The idea is that the tree has several Server nodes that each have many process child's (which main colum is image) and some processes have sub-processes which are children of the processes'node.
(source: remkoweijnen.nl)
Is such a layout possible? If not with the default component I would appreciate advice on how to implement this in a descendant.
/Edit: The following screenshots are when using the method TOndrej suggests:
alt text http://www.remkoweijnen.nl/temp/TreeView2.png
alt text http://www.remkoweijnen.nl/temp/TreeView3.png
alt text http://www.remkoweijnen.nl/temp/TreeView4.png
OK, I decided to implement as per TOndrej's idea:
alt text http://www.remkoweijnen.nl/temp/TreeView5.png
You most probably don't need that. Just make yourself a clear specification of what grouping you need. The first column can be multi-purpose - showing different information on each grouping level - e.g. level 0: server, level 1: process, level 2 and higher: child process.
On each level, only columns relevant to that level need to display any information. In the above example, level 0 would only display the server name in the first column; the rest of the columns would remain empty.
You could probably implement as many plus signs as you want by custom-drawing but it would be a lot of work and I really think the result is unnecessary, unusual and easily confusing to the user.
Only one column can have the tree, the other columns act a a listview. The column with the tree is the main column.
I would not know how your grouping would work if two columns had a tree and they might "conflict". What is parent node etc etc. GUI technically this might not be the best way of giving those details; a user won't expect it to work that way.

Resources