How to achieve Two Way data binding in native GWT? - gwt

We have been using GWT for around 4 years now. One of the most often discussed features missing in native GWT is data binding. Reading across AngularJs another Google offering, i came across http://devgirl.org/2013/03/21/fun-with-angularjs/ . I do not wish to use GXT or any other third party tools. I also wish to avoid generator related solution.
Is there any way this will ever be implementable in pure native GWT?
Is there any specific reason why GWT cannot provide this out of the BOX?

Have you tried GWT Pectin?
I have used it successfully in a larger project some time ago.

I suggest you try HexaBinding, which is non invasive and only focused on data binding. Here is the link : https://github.com/ltearno/hexa.tools/blob/master/hexa.binding/README.md
It works with pure Java, GWT and will soon work also with Android and JavaFX. It may even work with J2Objc but not sure yet...

I read the post you mention on devgirl about AngularJS. In that post the "2 way data binding" refers to the property of the code to reflect automatically on the view the changes that occurs to the data that the view is currently displaying.
This is achieved in GWT since version 2.1 with the Cell Widgets
In the first paragraph of the Cell Widgets documentation I linked above it is clearly stated that:
A cell widget can accept data from any type of data source. The data
model handles asynchronous updates as well as push updates. When you
change the data, the view is automatically updated.
If you want to do in GWT something as basic as the example in the devGirl post you need to write a onKeyup handler (in AngularJS you should write a Scope to this purpose) that would copy what you entered to the linked label. Something like this:
...
final TextBox nameField = new TextBox();
final Label enteredName = new Label("");
...
public void onKeyUp(KeyUpEvent event) {
enteredName.setText(nameField.getText());
}
...

Related

SugarCRM fetching data from outside REST service to subpanel

I'm trying to create subpanel in Account detail view where list of elements is fetched from external REST service.
I know how to define subpanel, but have no idea how to fill it with data from external network source. Was trying to use get_subpanel_data but there I can only change SQL.
Any ideas how can I do this?
When I've done this in the the past, at least with Sugar 6, I opted distinctly not to try to create a true subpanel. The data being loaded is coming from an outside source and is loaded dynamically with the page, so why present it as if it's static data coming from Sugar? Instead, I created a custom Smarty template to use as the footer on the detail page. For such an example, you can check how it works on the Calls Edit View. I think it's the footerTpl parameter in the detailviewdefs.php or editviewdefs.php. I loaded the smarty template by creating a custom detail view for my module, so custom/modules/MyModule/views/view.detail.php - extend the base Detail View class and override the display to feed Smarty new params, then your Smarty template only needs to iterate through and present the data that your view defined.
To be super-hip and abide by MVC, you could even put your custom code into your bean (if it's a custom module) or into a custom controller method, then reference that from the view.detail.php, and still feed it from there to the Smarty template.
Alternatively, you could just load JavaScript into the Smarty template and use the JavaScript to call the third-party service, parse and present it, etc.
I realize this question is a little bit old now however it comes up fairly often so why not provide an answer with a couple possible solutions. I won't get into code but more just into the design theory of how it can work. If someone needs more specific code help then that is another question.
A couple ideas...
As you mentioned you can define a custom Function which will load in Data to the SubPanel from your own SQL Query. That is one method that I just recently got to finally put to use after knowing about it for a good year and a half.
When you go this route, you are restrained to using the Columns in the SubPanel. I assume it is using the actual Metadata files to determine which Field Columns a SubPanel can use so you pretty much need your custom data in a Database table to have the same column names as the fields defined in the SubPanel Metadata.
Obviously this works great in the right situation, however not always and that leads us into the 2nd method I know of.
The other way is pretty much what #Mattew-Poer mentioned in his answer. It means abandoning the SubPanel altogether and instead generating your own HTML. This is by far my favorite and prefered way of doing it and I have been some really custom modules due to this being possible in a custom module! I will show an example below.
(Click HERE to View full size image)
In the screenshot, you can see in this example that I have something looking Similar to a SubPanel however it is not and is much for flexible and easy to customize.
Example, to the far left column in my fake subpanel is image checkboxes. When clicked on, an AJAX request is made to change the Task row Status.
After that, the checkbox image is updated to indicate the new Status state, the Modified DateTime is updated, the Status column has color background SPANS and is also updated with the correct text and background color when the left side checkbox is clicked.
Doing any of this with the standard SubPanels is a complete nightmare and would be difficult to do some of the stuff that you are open to do when you build your own version of a SubPanel.
With that said, I have built an identical clone of the above screenshot using SugarCRM default SubPanels! It was a nightmare. I could easily update the content and HTML in some of the columns. I even had the AJAX click checkbox image to update and do all the other updates I mentioned above. It wasn't too hard and worked fairly good but it had some issues.
When you do inline edit, inline create record, or subpanel paging to load different set of record. You would then lose all the custom HTML formatting that was applied. The reason is, in the SubPanel you are limited to using the After UI load logic hook. So since the "Page" is loaded already, when an AJAX request is made to add/edit the subpanel content or load a new set of items with the paging links. It only loads the SubPanel content on those events and the whole Page content does not reload. Because the logic hook only fires off 1 time after the page loads, this newly loaded subpanel data doe not receive any of your custom HTML formatting.
In my case, this means that nice looking colored background Status spans are lost, the image checkboxes are lost, and some other functionality is lost.
Now to get super technical, I could have gone another 3rd route and instead made new Custom Field Types for each SubPanel filed that I needed to apply custom HTML to. This process is super hard in my experience and in some cases it really isn't the BEST solution.
Because of the reason explained, this is why my new modules use the Custom HTML route to generate my own version of a custom subpanel or whatever Data is needed in my Module pages! So far it is working better than I imagined and has opened doors for me to build custom SugarCRM modules that I previously didn't even realize would be possible to build due to some of the issues I mentioned above. Now I bypass them altogether and open the door to do pretty much anything!
I've got some really cool stuff for SugarCRM in the works right now. If anyone has any questions feel free to ask in a new question or for me personally in a comment here.

Vaadin alternative for heavily loaded UI

Currently I am programming the Web Application based on Vaadin. I am quite happy with the learning cycle and the way how easy UI can be designed.
In general pluses of Vaadin are:
"Native" UI programming for Java users (component hierarchy / event listeners / drag & drop / validation).
Out-of-box nice collection of components (tree / table / list / ...).
The minuses are:
Big and complex HTML output. That slows down the browser response time (also mentioned here and there) and leads to some rendering peculiarities from browser to browser.
Difficulties in handling big number of components (see Can CustomLayout handle 5000 components?).
The need to recompile the widget set if you use 3rd party components.
My question to community is:
What Web Framework fits best the following requirements:
Separation of presentation with event/action handlers.
Common components out of box (with advanced features like table column drag&drop, lazy loading).
Layout support (no headache with padding and alignment of components).
Event propagation to server and server-side event processing.
Possibility to generate your HTML (if framework is not HTML-based) and also capture events for it (e.g. mouse clicks).
Possibility to register key stoke callbacks (e.g. Ctrl-S) is a plus.
Short learning curve for Java developer is a plus.
The sensible mix of approaches would fit as well. Please, provide the link for "Hello World" application, implemented based on the framework that you suggest. I am considering Apache Wicket / Echo2 / Tapestry / Click / GWT, but it's difficult to make a choice without playing for couple of months (hopefully with no deep disappointment).
I completely agree with all your mentioned minuses and can not say very much against. Because I'm quite new in GWT I can only share my little experience I have collected other last 2 months.
Separation of presentation with event/action handlers.
I think UiBinder with annotation #UiHandler("closeButton") #UiField in GWT 2.0 and later is exactly for separation HTML form code and handlers. Also MVP pattern with event bus is perfect answer from GWT team.
Short learning curve for Java developer is a plus.
I'm not naive and I don't think that it's possible to get quality result only with java knowledge without understanding WEB technologies.
Most of GWT UI frameworks I have reviewed and read about, introduces more problems than solutions. They somehow manages to and one or few benefits and restrict you from other features which comes in the new releases of GWT. I have chosen not to use vaadin because I felt like It will force me to do webapp development in their way, which I agree is fast easy to understand, but somehow limited. I like to have some freedom by choosing classic GWT without fancy controls.
Also I also feel that GWT UI Components are limited and there is no quality alternatives. Something is wrong here. I think google team have to do something on this part.
Regards RemisB
You can use a Vaadin Table to solve the original problem, more or less like this. The trick is to create a Vaadin Container and put components in it, as data. On the text side, wrap a label in VerticalLayout then add a click listener. This yields the ability to display "paragraphs" of XHTML text, detect clicks on them with relative locations, and still be able to handle large numbers of paragraphs.
You might need to modify your styles.css to allow wrapping of text within a table row, so you'll get ragged rows.
package com.soletta.clickytable;
import com.vaadin.Application;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;
public class ClickytableApplication extends Application {
#Override
public void init() {
Window mainWindow = new Window("Clickytable 2 Application");
setMainWindow(mainWindow);
mainWindow.addListener(new CloseListener(){
public void windowClose(CloseEvent e) {
WebApplicationContext context = (WebApplicationContext) getContext();
context.getHttpSession().invalidate();
close();
}});
IndexedContainer container = new IndexedContainer();
container.addContainerProperty("text", VerticalLayout.class, new VerticalLayout());
container.addContainerProperty("edit", Button.class, new Button("Edit"));
for (int i = 0; i < 10; i++) {
final int index = i;
Object item = container.addItem();
Label lbl = new Label("Text Content " + i);
VerticalLayout vl = new VerticalLayout();
vl.setWidth(100, Sizeable.UNITS_PERCENTAGE);
vl.addComponent(lbl);
vl.addListener(new LayoutClickListener() {
public void layoutClick(LayoutClickEvent event) {
System.out.println(String.format("Clicked on text %,d at client(%,d,%,d), relative(%,d %,d)\n", index, event.getClientX(), event.getClientY(), event.getRelativeX(), event.getRelativeY()));
}
});
container.getItem(item).getItemProperty("text").setValue(vl);
container.getItem(item).getItemProperty("edit").setValue(new Button("Button " + i));
}
Table table = new Table("ClickyTable 2", container);
table.setColumnExpandRatio("text", 1);
table.setColumnExpandRatio("edit", 0);
table.setSizeFull();
VerticalLayout fl = new VerticalLayout();
fl.setSizeFull();
fl.addComponent(table);
mainWindow.setContent(fl);
}
}
With some style changes in place, the result can look something like this:
ClickTable Screen Shot http://www.soletta.com/images/ClickyTable.PNG
If you ever find yourself putting hundreds of components on web page in Vaadin, you probably should reconsider your application structure. Why not implement a custom widget for the part of the UI that requires such huge number of widgets? It is just GWT and thus fairly easy. Then you can have the best of the both worlds - simplicity of Vaadin with full control of HTML5 on the client side.
Vaadin Flow
You must have been using the previous generation of Vaadin, versions 6, 7, and 8.
Because of the limitations and incompatibilities of earlier browsers, the long delays in producing CSS 3, and predating HTML5, Vaadin did indeed generate large and complicated pages. Given the relatively poor performance of JavaScript runtimes back then, some elaborate web apps may not have performed as well as you would have liked.
Web Components versus GWT
Fast forward some years now since your Question was posted. Vaadin Flow has arrived. Versions 10 and later are longer based on GWT. Instead they use the open standards that have emerged, collectively known as Web Components.
CSS 3
CSS 3 has finally arrived, and matured. Browsers now offer built-in sophisticated page layout with Flexbox and Grid, in addition to the previous Float. So no longer must page layout be hacked together with abuse of table and crazy assortment of div & span tag soup. Page layout can now be built with short, simple, and clean code.
Modern browsers
Other modern advancements include:
HTML5 designed expressly for building web apps (as opposed to web documents)
The consolidation in browser engines (basically only 2 left standing: WebKit/Chromium & Quantum/Gecko)
Dramatic advances in the performance of JavaScript runtimes, plus important new features of JavaScript 6
Close cooperation between browser makers in writing and implementing web standards with much more consistent behaviors
The "evergreen" rapid-release model of modern browsers
All these taken together mean the burden on Vaadin to deliver high-quality consistent web-app experiences has been greatly decreased. You should see much shorter, simpler, and faster page code.
Give it a try.
For more discussion, see my Answer to the Question, Understanding Vaadin Flow / Vaadin 10.
The minuses are:
Big and complex HTML output. That slows down the browser response time (also mentioned here and there) and leads to some rendering peculiarities from browser to browser.
No longer big and complex, as discussed above, because of modern web technology improving so much.
Difficulties in handling big number of components (see Can CustomLayout handle 5000 components?).
Web Components is an open standard, composed of four specifications.
Many components have been built over the last several years, now available for you to use in your Vaadin Flow web apps.
Most of the UI widgets you knew in Vaadin 6/7/8 have been rebuilt as Web Components (see Comparison Matrix). This means these Vaadin components can be used in other web projects without the Vaadin Flow server-side Java binding.
You can easily wrap other non-Vaadin-specific components built on Web Components to be available to your in your Java code running on the server-side Vaadin Flow framework. See Integrating a Web Component. To get you started, here are a couple thousand to choose from.
You can create your own components.
The need to recompile the widget set if you use 3rd party components.
No more WidgetSet in Vaadin Flow, because there are no more GWT widgets. Supplanted by Web Components as discussed above.
What Web Framework fits best the following requirements:
Vaadin Flow ticks all the boxes you listed in your Question: event handlers, common components with advanced features, sophisticated page layout, user-events propagating from client to server (and the other direction via built-in Push technologies), keyboard shortcuts, and a short learning curve for Java programmers.
Furthermore, from the server-side you can now invoke JavaScript snippets on the browser. And Vaadin 15 this spring brings client-side coding in TypeScript while still integrating with the Java code running server-side in Vaadin Flow.
Web Firm Framework is the best alternative. It's an opensource Java framework under Apache License 2.0. I also had to load heavy components in my application it was smooth with this framework.
It is like a collection of java classes for all HTML5 tags and attributes. Using these classes we can build the UI just like we do using the pure HTML. It can handle heavy HTML because the data coming from the server to client is like a stream through websocket, eg:-
//creates table
Table tableObj = new Table(null,
new Style("width:100%")).give(table -> {
new TBody(table);
});
//finding tbody object in the table
TBody tBody = TagRepository.findOneTagAssignableToTag(TBody.class, tableObj);
for (int i = 0; i < 10; i++) {
int count = i;
Tr trObj = new Tr(null).give(tr -> {
new Th(tr).give(th -> {
new NoTag(th, "Firstname " + count);
});
new Th(tr).give(th1 -> {
new NoTag(th1, "Lastname " + count);
});
new Th(tr).give(th2 -> {
new NoTag(th2, "Age " + count);
});
});
//appending tr in the table
tBody.appendChild(trObj);
}
Whenever trObj is appended it will be immediately available in the UI it will not wait to finish the for loop. Check their demo app which contains a button to stream 1000 rows.
We can handle events without much effort eg:
to handle click event of a button
//This will create a button in the UI.
new Button(null, new Type(Type.BUTTON), new OnClick((data, ev) -> {
System.out.println("Button clicked");
return null;
}));
In this git repo you can find sample projects for it.
We can also try this tool to convert HTML5 to Java/Kotlin code. This video and developers guide will be helpful to understand it better.

Using GWT MVP on a single screen application

I apologize in advance as this is one of those "how does this work" type questions. I am a newbie to GWT MVP and I am trying to create a project similar to this one here:
where basically I have a menu of widgets/components that I can drag and drop onto a panel and doing so changes the properties shown in the Property disclosurepanel.
I have been reading about the official GWT MVP framework and they its described it seems like it expects each application state to represented by a whole new page (a View with an associated Place).
I am confused as to how this would work this type of application. That is, an application that has 1 basic screen that never entirely changes (i.e. user never navigates to a whole new screen) with sections that need to communicate to each other (i.e. dropping a widget loads a different set of properties).
I am sure I am misunderstanding something about MVP so if someone can just offer some advice on how to wrap my brain around this that would be great.
It's not impossible to utilize the MVP paradigm with more than one on-screen regions.
You can read about a possible solution in this article. It's the last post of a four-part series. I suggest reading also the preceeding posts from the author with the same tags.

Dynamically creating GWT screens using Metadata?

I have an AWT applet application that needs to be ported over to GWT. The applet screens are described in meta data and the applet renders each screen dynamically using reflection.
We'd like the same thing in GWT/ExtGWT.
I've built a working version of this ExtJS whereby the metadata is turned into ExtJS Screen configs in the form of JSON. The drawback with this approach is the "wiring" of controls to data needs to be written in Javascript.
GWT is preferred since it'd be all Java code, no JS. Upon digging in it's possible to render the screens using GWT off the metadata using GWT.create().
The problem I'm having is the wiring to hook a dynamically created button for example to an event handler requires reflection which is not supported in GWT.
Is this conclusion correct? and if so, are there any other ways to achieve this type of dynamic UI using ExtGWT?
For extGWT where we don't have declarative UI's the easiest solution might be to just add a mapping/config your handlers in java which refer to instantiated classes. of the handlers, i.e.:
Map<String, ActionListener> mapping = new HashMap<String, ActionListener>();
mapping.put("HandleClicked", new HandleClickedActionListener());
then you can try to find an implementing class for your meta data.
For pure GWT 2 you can take a look at http://code.google.com/intl/de-DE/webtoolkit/doc/latest/DevGuideUiBinder.html#Simple_binding on how it's done there. it might be possible to create a similiar solution which annotated methods for you own extgwt solution like the one in gwt.

Paging a GWT-EXT datagrid with GWT-RPC?

I need to display data coming from a GWT-RPC service in a paginated datagrid.
The gwt-ext showcase does not provide an example combining gwt-rpc calls and datagrids.
That is too bad because the original javascript Ext grid components offer paging and remote sorting. How to take advantage of these features with GWT ?
I too wanted to do this a few weeks ago, and searched long and hard and found nothing. In the end I wrote my own paged grid that supports RPC/Sorting/Editing/Etc.
It's intended to be generic, and is still a work in progress, but to use it you simply implement the TableSource and TableRenderer interfaces like so:
new PagedTable(new AssetTableSource(), new AssetTableRenderer(), 30);
I have posted the code here:
http://wiki.shiftyjelly.com/index.php/GWT#GWT_RPC_Paged_Table
Feel free to revert the buttons in the PagingControl.java back to normal GWT buttons.