Vaadin: How to remove item from DB container grid - vaadin

How do I remove a row from a container/item/grid/db/entity/bean/class/object/ID?
Also, what's the difference between all these?
Everyone seems to say these as if they were interchangeable.
Can I get a simple explanation of how these all work together?
I've been through dozens of youtube videos and tutorials, but I still can't see the big picture.
Simple task: Delete one row from a grid.
But then it starts getting bigger and more complex with nested beanitem container property field entities and I just can't make sense of it.
Thank you for all of your help in advance!

The Grid, Table or any other Vaadin Component used to present set of data use some implementation of the Container to store your data. A Component is a part of your User Interface, the <div> in your DOM which is seen by your end user. The Vaadin Containers contains your objects. The most widely used containers are:
IndexedContainer - default container for Grid and Table. You usually add items by calling addItem method on either container or related component. The disadvantage of using this type of container is that you are usually obligated to set appropriate properties (think of columns) on both items and the container itself,
BeanContainer - is able to receive Java objects that follows JavaBean convention. Thus it is able to automatically infer properties of your component,
SQLContainer - contains data stored in database. Constructed using SQL query. Can be setup to automatically update your database based on changes made by user in UI.
Items and IDs
Adding single items to some containers may look a bit complicated. There are a few ways to do this. They are described very well on a Vaadin website. Basically the ID is an unique object that you use to access corresponding Item. The Item is represents the single row in your component. Every Item have properties. You can access and make changes to your items in container using their IDs i.e.
table.getItem("uniqueId");
Usually, you don't operate directly on containers. The components expose basic Container interface methods via their API. In example implementation of AbstractSelect.getItem() component currently (Vaadin 7.5.9):
protected Container items;
public Item getItem(Object itemId) {
return items.getItem(itemId);
}
(AbstractSelect is a super class of other Vaadin components like Table and Grid)
It gets more complicated with properties of the items. Every Item have some properties (columns). And every Property has its corresponding ID. Using property ID you can access the value of the item in the specific column. The following code presents above - it adds one item with one property and sets its value:
Table table = new Table();
table.addContainerProperty("column1", String.class, "defaultValue");
Item item = table.addItem("uniqueId");
item.getItemProperty("column1").setValue("Black Friday");
Notice that it is perfectly safe to use String literals as IDs since underneath they are compared using equals()

Related

Vaadin 14 TreeGrid - Cannot add the same item multiple times

Working on a project that will display hierarchies of "tasks". I'm running into a problem where it will not allow for multiple entries of the same object. From what I can tell, the "duplicate" item is under a different parent.
The domain data allows for this - a given task may appear in lots of places.
It would seem that this is intentional (maybe), but is there a way around this?
It's intentional to a degree; each Grid and TreeGrid data item is expected to be unique. You could work around this by creating your own implementation of the hierarchical DataProvider class (for example extend AbstractHierarchicalDataProvider) which overrides the getId method along with the other required methods. The return value of this method needs to be unique per item, as it's used as a hash key.
Well, this is probably not the best solution, but it works.
I added a field to the abstract super class that is initialized with the current time (long ms). When I am adding items to the tree grid, I check to see if the tree contains the item and if so, I randomize the field and then add it. The new field is marked #Transient so it's not persisted.

Passing a Collection from VBA to a form

I have a an MS Access database with nine tables. The main form will be driven by a query linking the two main tables. When I pull up any one record ("family within a house"), I have a lot of variable data to pull into the form (how many family members, names of each, other specific information) to retrieve from the other seven tables. I created a VBA module, linked to this form, which is triggered when a record is loaded. The code aggregates all the family member data into a Collection of "person" elements. All of that works, as evidenced by the "Immediate" window in VBA. The "person" object is defined as a Class Module with all the relevant attributes (firstname, lastname, email, is-parent/is-child, etc).
Where I'm stuck: how do I access the collection within the form, so I can start populating elements? I haven't been able to find any documentation to do this, nor any similar questions asked/answered online. Next step will be creating all the elements dynamically, but right now, being able to create a static element and setting the control source to (at least some component/value within) the collection would be a huge help.
My VBA form module has a method, "Private Sub Form_Current()", which generates the collection when the current record is changed.
Thanks in advance...
Got my answer: "you don't". Set the element values in code, rather than trying to pass the collection the form.

Sorting OData model in SAPUI5

Dear SAPUI5 Developers,
I developed a SAPUI5 Fiori Worklist project by using WebIDE template projects.
In the Component.js file the OData model has been fetched.
var sServiceUrl = this.getMetadata().getManifestEntry("sap.app").dataSources.mainService.uri;
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, {
json: true,
loadMetadataAsync: true
});
oModel.attachMetadataFailed(function() {
// Call some functions from APP controller to show suitable message
}, this);
this.setModel(oModel, "BrandSet");
This part of code causes a call to OData server to fetch data from the remote server.
Now I want to order the data in backend and then receive the data. Assume the sorting function has been implemented correctly in the backend.
Thus, if I use $orderby=name or $orderby=price it has to be sorted by name or price respectively.
In some toturial they said for ordering use sorter option inside of the XML view file. Like here:
https://sapui5.hana.ondemand.com/#docs/guide/c4b2a32bb72f483faa173e890e48d812.html
Now my questions are:
How to apply this sorting inside of the Component.js file where the Model is initiated?
The second question is how to apply this ordering when we apply a filter to the model? Like the example that in the following link applied filter:
https://sapui5.hana.ondemand.com/#docs/guide/5295470d7eee46c1898ee46c1b9ad763.html
In fact I am looking for a function or any kind of method that add the $orderby=xxx to the OData service call.
I found a way here: https://sapui5.hana.ondemand.com/docs/api/symbols/sap.ui.model.odata.ODataModel.html#constructor
If I use mParameters.serviceUrlParams then I can add some URL parameter to the service request but it has been said "these parameters will be attached to all requests". Does it mean if I add the $orderbywith this method then I can not get rid of that in the further requests on that data model for example for filtering?
An app would normally be structured a bit differently to what you propose. The general assumption is that there is a lot of data available from the backend and to load all this data at once can cause performance problems, particularly when used over a mobile phone network. Furthermore, the data is an oData Entity Set, that is, a list of many items of the same type, so the data would be presented in the UI with a list or table.
Typically the app would then show the data in some kind of list, such as sap.m.List or sap.m.Table. These controls are designed to work with large volumes of data and would load initially the first 20 items from the entity set. Only when the user scrolls down the list of data would additional items be loaded. Also, with these controls the user can decide to sort or filter the data according to certain fields in your data.
Assuming that your app is work like this, here is the standard approach.
The Main model (as defined in the manifest) would not be loaded in Component.js, but loaded via the binding defined in the xml views of the app. In the views you could define a fixed sort and/or filter in the binding or you could allow the user to set the sort and filter criteria. This would be handled programmatically in the respective controllers. Normally the changes that the user makes to the sort and filter would be applied separately. For example, he/she chooses an new sort order, the oData is reread and the new sort order shown in the UI. Then the user may chose a filter criteria, and this is applied too. Of course, in your programming logic in the controllers you would need to have applied any default sort and filter criteria and then maybe combine or replace these with the criteria selected by the user.
To see an example of this, I would suggest to look at the Template Application “SAP Fiori Master-Detail Application” in the WebIDE.

Can Orbeon controls have multiple values?

I think the answer is no, but the question has been put to me so I'd like to confirm. My understanding is that any custom XBL control that I create for use in Form Builder can have one and only one value. Is this correct?
I have always assumed this because the control name is then used in the data instance as the name of the node which contains the the value.
This question comes from the desire to have reusable components with multiple values, for example, an Address control so that addresses can be recorded consistently and the same set of fields does not need to be added many times. Orbeon does have some support for this in the form of Section Templates but because the control names stay the same in each instance of a Section Template this does not work well with our design.
The best idea I've had is that a custom control which records multiple values could encode all the values into a single text string for example in JSON. Of course, this is not ideal.
Are there any other options?
It is possible for controls to have multiple values. When that happens the values are typically stored in nested elements. I.e. a control could bound to an element <address>, and could create nested elements <street>, <city>,<country>, etc to store the different parts of the address.
In practice, you can look at how this is done in the Image Annotation annotation control (see wpaint.xbl), which creates nested elements <image> and <annotation>, leveraging the xxbl:mirror="true" functionality.

Showing many tables in many dropdown lists. c#, asp.net-mvc, linq2sql

I want to use an example to explain what I want.
Assume I've following DB design:
Item (id, name, categoryID);
Category (id, name);
When user wants to create an Item (fill in form), I'll give a list of categories in a dropdownlist, and when user chooses one of the categories ASP.NET MVC will automatically bind categoryID, to the selected one. I need to present same dropdown list when editing the item with correct selected one.
Question:
But my DB is very big, and it requires around 30-40 (maybe even more) category-like tables, that contain just "id" and "name", and all tables need to be shown in dropdown list while creating some other object, and also needs to be presented while editing the object. Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names. (I'm using Linq2SQL)
Currently my solution is:
Make a view that's based in all such tables and in application I just call a function that construction dropdownlist from that single view. But it's still tedious to change view definition everytime I add a new table.
Do you guys think of a better solution for this tedious work, possibly using reflection or some other tecnologies.
It is not a problem "Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names."
If I were you, I will mark an addition interface on these class using "partial class" feature.
Then, I will write few extension method for the partial class.
If anyone interested in the solution:
I've used reflection to solve this problem.
I use reflection over DataContext to get the Table (by string name), and get its fields and construct the optionlist.

Resources