GWT Editors for readonly and edit mode - gwt

GWT's Editor framework is really handy and it can not only be used for editing POJOs but also for read-only display.
However I am not entirely sure what the best practice is for doing inline edits.
Let's assume I have a PersonProxy and I have one Presenter-View pair for displaying and editing the PersonProxy. This Presenter-View should by default display the PersonProxy in read-only mode and if the user presses on a edit button it should allow the user to edit the PersonProxy object.
The solution I came up with was to create two Editors (PersonEditEditor and PersonDisplayEditor) that both added via UiBinder to the View. The PersonEditEditor contains
ValueBoxEditorDecorators and the PersonDisplayEditor contains normal Labels.
Initially I display the PersonDisplayEditor and hide PersonEditEditor.
In the View I create two RequestFactoryEditorDriver for each Editor and make it accessable from the Presenter via the View interface. I also define a setState() method in the View interface.
When the Presenter is displayed for the first time I call PersonDisplayDriver.display() and setState(DISPLAYING).
When the user clicks on the Edit button I call PersonEditDriver.edit() and setState(EDITING) from my Presenter.
setState(EDITING) will hide the PersonDisplayEditor and make the PersonEditEditor visible.
I am not sure if this is the best approach. If not what's the recommended approach for doing inline edits? What's the best way to do unit-testing on the Editors?

If you can afford developing 2 distinct views, then go with it, it gives you the most flexibility.
What we did in our app, where we couldn't afford the cost of developing and maintaining two views, was to bake the two states down into our editors, e.g. a custom component that can be either a label or a text box (in most cases, we simply set the text box to read-only and applied some styling to hide the box borders).
To detect which mode we're in, because we use RequestFactoryEditorDriver (like you do), we have our editors implement HasRequestContext: receiving a null value here means the driver's display() method was used, so we're in read-only mode. An alternative would be to use an EditorVisitor along with some HasReadOnly interface (which BTW is exactly what RequestFactoryEditorDriver does to pass the RequestContext down to HasRequestContext editors).

Yes,Presenter-View pair should be. But Here two ways to achieve this feature if you like to go with:
1) Integrate Edit/View code design in one ui.xml i.e.Edit code in EDitHorizonatlPanel and View code in ViewHorizontalPanel.The panel has different id. By using id, show/hide panel with display method. if getView().setState() ==Displaying then show ViewHorizontalPanel and if getView().setState()==Editing then show EditHorizontalPanel.
2) Instead of using labels, Use textboxes only. set Enable property is false when you need it in view mode otherwise true
You have created two Presenter/view but I think if Edit/View function has similar code so no need to rewrite similar code again and again for view purpose.
If a big project has so many Edit/View function and you will create such type of multiple View/Presenter than your project size become so huge unnecessary.
I think that whatever I have suggest that might be not good approach but a way should be find out which help to avoid code replication.

Related

UWP App with multiple frames using the MVVM pattern

Is there any library / framework that could simplify Universal Windows Platform app development of the application that contains multiple Frames.
I mean, using MVVM Light or BezySoftware MVVM-Navigation the application is highly tied to the idea of navigating between different pages that are hosted by single frame.
The UI I try to develop consist of multiple content frames (main, left, right) which content varies. I need something that will let me navigate easily between different views (by placing these views into appropriate frame) and provide the same features I would have with BezySoftware MVVM-Navigation, so:
handling of the view model state persistence
the ability to activate / query deactivate view models
back button feature
Few different options:
Combination of a single navigation service injected into your view model AND user controls for areas that need to be repeated view to view (e.g. a tabs, status bars, etc). With this route, every time you create a new view you would paste in the common user controls that need to appear. You would also be able to expose bindable properties from said user controls.
Combination of ContentControl, DataTemplate, and DataTemplateSelector to load in either an entire view (Page) or fragments of XAML. As one person pointed out you cannot use DataType attribute, instead you use the DataTemplateSelector class to do the mapping for you. With this approach you can also use triggers to dynamically change the template (content) based on changes to properties on your view model and/or user interactions.
A mix between 1 and 2 above.
I might right the whole thing right here, but it too lengthy. I just recommend you see this article to get your answer.
MVVM patter in UWP

How to pass a View to my ViewModel so an I*Service can use that View to do something

https://github.com/brianchance/MvvmCross-UserInteraction is a very nice plugin for showing cross platform Alerts!
But for this question, can we assume it can not use a UIAlertView (or some other top level MessageBox type call on other platforms) but needs to show a Message within a given subsection of the screen (i.e. on IPhone you would need to supply a UIView to the plugin which it will use to show the message within).
So, how would you set this up so the ViewModel knows what View to use as its display container?
As a specific example, if I wanted an Error Service, as so -
public interface IErrorPFService
{
void Show();
void Hide();
void SetErrors(List<Error> errors);
}
and I create a platform specific implementation for it.
If I inject this into my ViewModel so it can control Error Show/Hide/Set how do I tell it the UIView (or equivalent) that I want my Errors to show within?
Can I just expose the IErrorPFService field as a public property and do -
MyViewModel.ErrorPFService = new ErrorPFService(View);
in my ViewDidLoad ...
Or is this coupled incorrectly vs Mvvm Practice?
I would expect the ViewModel to subscribe itself to the ErrorService.
When receiving a message it would expose it in a collection(?) and the View would bind to that collection.
This way the View is unknown to the service and the ViewModel has the chance to influence the View contrary to your solution.
It would help if you could give an example for the scenario you are describing.
Sometimes, the way you visually want to display something might not be the best way, so if it's possible for you, you might find a different and simpler way, which spares you from having to find a solution regarding what you are describing.
Generally, I always do the best I can to avoid the idea of having to actually pass a 'view' or an abstraction of it, from the view-model to view. Also, cross-platform wise, things can work very different in terms of UI interaction. You can find yourself in a situation when things are complicated just because UI works differently than what you expected.
But let's try find another perspective:
At any given point, the view knows what data \ feature it's displaying. So when you are calling from the view-model an user interaction action (by a service, property change, event, etc) the view should 'expect' it.
For example, the platform specific user interaction implementation is able to get the currently displayed top-view and interact it in a platform specific manner or based a relationship. In your example, the message-box can be displayed in a specific sub-view of the top level view.
In advanced scenarios, I guess you could try to create a cross-platform approach for this, but you should try to put in balance all the abstraction you want to create just for that. Think about doing this as a plan ... Z. If possible. Again, giving an example might help.

Backbone Model View: Switch between editing (via form) and display

With Backbone I have created a view for a model. I would like to provide the following workflow to the users:
a) Initially, model content is just displayed via a template and there is an edit button
b) if the user clicks the edit button, the model content will be displayed in a form and can be saved back to the model by clicking a save button.
c1) if saved successfully, the new model content we be rerendered via the template and displayed again
c2) if there were any validation errors, the form is updated with the errors.
I came up with the following options on how to implement this. But I am not sure, on the best practices. Any advice is highly welcome.
Option 1: 2 sub views (one for the displaying the content, one for editing it) that are dynamically created on any switch between display and edit (and dropped afterwards).
Option 2: 2 sub views (one for the displaying the content, one for editing it) that are hidden/unhidden on any switch (like toggle)
Option 3: 2 sub views (one for the displaying the content, one for editing it) that are assigned to the parent element on any switch.
Option 4: 1 View to manage the model content and 2 templates (one for displaying and one for editing) that are rendered on any switch between between display and edit.
From my gut feeling, I clearly would prefer option 4, since it will need ony 1 view that could handle all logic. But maybe I have overseen something in terms of performance, event handling, DOM access etc. So any hard arguments on the pros and cons of the 4 options are highly appreciated.
What do you think?
I've been working on something like this except that the edit button is attached not to the whole model, but to individual attributes, which can be edited "in place". To do that I've been using backbone-forms, replacing the element to be edited by a backbone form and then re-rendering it after the form has been submitted. This works quite well.
In your case, since you're editing the whole model at once, it would actually be easier. When the user clicks the edit button, replace the view with a backbone form, and when they submit that re-render the model view with the errors or success message. Backbone forms makes displaying error messages on the form quite easy.
I have tried option 3 (2 subviews) and option 4 (1 view using 2 templates).
Here is an argument for 3:
Switching between readonly view and edit view in backbone js
And here is an article promoting 4, under "Switching a Contact Into Edit Mode":
http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-4/
I found option 3 to more trouble, because now you have 3 views using the same model. It brings up issues in the DOM, because now there is an el for the parent and an el for each child, nested inside. It also brings up issues with encapsulation, because the child views should really be inherited from the parent, but that's difficult with javascript:
Access parent class member with javascript inheritance?
I wanted option 3 to work more like an abstract base class tied to the el in the DOM. Then view and edit could inherit from it and internally set the el, preventing nesting of two els. But this breaks how backbone.js nests views:
Swap/switch/exchange backbone.js views in place?
Option 4 "just worked" the first time I tried it. It's trivial to have an editTemplate that gets rendered if View.editing is true. And in practice, the read-only view tends to be so small, with so little interaction by definition, that it only adds to an edit view by a few lines.
The downside to 4 is that you dirty your view with switching logic.
An argument for 4 is that it increases the possibility to reuse code and reinforce DRY.
One last argument for 4 is that you might have a "rich" form at some point that is always on, and maybe you only want to enable editing on specific form elements. For example a Contact form might have an Address view inside that handles its own updating. So view/edit might not be mutually exclusive down the road.
I finally resigned myself to going with what worked (option 4) because both options use two templates in the html file. The backbone.js implementation details don't matter to the end user.
I think this is all worthy of some lengthy articles weighing the pros and cons of each approach, with real-world examples. Backbone.js also needs to have backbone-relational built into it, and probably Backbone.ModelBinder, with a better ._super implementation. If some of these concepts were more fleshed out, it would make it easier to implement option 3 IMHO.
But I'm curious what others think, because neither 3 or 4 are perfect as they stand now, and I'd like to know what the best practices are for this, since form handling is one of the primary reasons that people get into backbone.js in the first place.

GWT MVP - maintaining multiple displays that are separate of one another

I have a GWT App and I am using GWT MVP with Places / Activities.
My application layout is something like
MENU | CONTENT
The Menu and the Content displays will change dynamically and one changes separately from the other. What I mean by this is that when the Content display changes I do not want to have to update the Menu display and vice versa. Both displays need to be able to respond to PlaceChangeEvents and update themselves when these occur. The problem is that each display should only update in response to certain PlaceChangeEvents, ignoring PlaceChangeEvents that are directed at the other display. However this does not work using the 'standard' GWT MVP pattern because even when each display has it's own ActivityManager they will automatically pick up ALL PlaceChangeEvents because there is a single PlaceController listening on a single EventBus. The only way I can see to do this is by having two EventBus's and two PlaceControllers - one for the Menu and one for the Content. So my question is whether this is a good solution or is there a simpler/better way that I am missing? One problem with this solution is that the PlaceHistoryHandler can only be registered with one of the EventBus's.
Place changes are actually controlled by ActivityMappers. They get a Place and return the corresponding Activity. This is where you control how Places are mapped to Activities:
You need to create two ActivityMappers (MenuActivityMapper, ContentActivityMapper) and then instantiate two ActivityManagers each with it's own ActivityMappers. Then for each ActivityManager you call setDisplay(AcceptsOneWidget display) where for each you pass in an area (display) where it will show it's content.
For menu you will probably only use one Activity, since it's available in all Places. So MenuActivityMapper.getActivity() will always return the same instance of the MenuActivity. To enable MenuActivity to still adapt it's look based on place changes, MenuActivity should listen to PlaceChangeEvents.

GWT ValueListBox: can it support more than a single selection?

Can GWT's ValueListBox support multiple selections? Also, is there a way to get it to display more than a single value at a time (like ListBox.setVisibleItemCount()) ?
It seems like you'd need to get at the underlying ListBox (or somehow provide a custom one) in order to make this happen. Of course getListBox() is private, so that's out.
No. ValueListBox is intended to operate on single value. That's why it can be easily used as editor (from Editor framework) for wrapped type.
For multiple selection you can use ListBox, but AFAIK there's no straightforward way to use it as editor (you have to write your own custom editor based on ListBox).