-
18 Jan 2012 1:48 AM #1
Flush not working everytime in editor
Flush not working everytime in editor
Hi,
I'm using the editor framework and getting strange behaviour while running in devmode. When I call flush() on the driver it works sometimes and sometimes not. Here is my code:
Any suggestions???Code:public class TrailerTypeEditor implements IsWidget, Editor<TrailerType> { private final MaintenanceServiceAsync maintenanceService = GWT.create(MaintenanceService.class); private Dialog dialog; private AsyncCallback<TrailerType> callback; interface TrailerTypeDriver extends SimpleBeanEditorDriver<TrailerType, TrailerTypeEditor> { } TrailerType vehicleType; // editor fields TextField description; private TrailerTypeDriver driver = GWT.create(TrailerTypeDriver.class); public TrailerTypeEditor() { } public TrailerTypeEditor(TrailerType lType, AsyncCallback<TrailerType> callback) { this.vehicleType = lType; this.callback = callback; boolean edit = vehicleType.getPk() != null && vehicleType.getPk() > 0; dialog = new Dialog(); dialog.setHeadingText((edit ? "Edit " : "Add ") + "Trailer Type"); dialog.add(asWidget()); driver.initialize(this); driver.edit(this.vehicleType); configureButtons(); dialog.show(); } public Widget asWidget() { VerticalLayoutContainer c = new VerticalLayoutContainer(); description = new TextField(); description.setAllowBlank(false); description.setName("description"); c.add(new FieldLabel(description, "Description"), new VerticalLayoutContainer.VerticalLayoutData(1, -1)); return c; } private void configureButtons() { // dialog.getButtonBar().clear(); dialog.getButtonBar().setPack(BoxLayoutContainer.BoxLayoutPack.CENTER); CellButtonBase okButton = dialog.getButtonById(Dialog.PredefinedButton.OK.toString()); okButton.setHTML("Ok"); okButton.setIcon(RMS.icons.ok()); dialog.getButtonBar().add(okButton); okButton.addSelectHandler(new SelectEvent.SelectHandler() { @Override public void onSelect(SelectEvent event) { vehicleType = driver.flush(); maintenanceService.updateEntityBase(vehicleType, new AsyncCallbackImp<TrailerType>() { @Override public void onSuccess(TrailerType result) { System.out.println(); callback.onSuccess(result); } }); dialog.hide(); } }); CellButtonBase cancelButton = new CellButtonBase(); cancelButton.setHTML("Cancel"); cancelButton.setIcon(RMS.icons.cancel()); dialog.getButtonBar().add(cancelButton); cancelButton.addSelectHandler(new SelectEvent.SelectHandler() { @Override public void onSelect(SelectEvent event) { dialog.hide(); } }); } }
-
22 Jan 2012 11:28 PM #2
Hi I manage to figure out what the problem is. This only happens when you edit a textField for example and hit the OK button when the flush happens. The value in the Widget is not updated. It is still in edit mode. I tried to call the finishEditing() method for all the Widgets that is edited before calling flush() but it is still not working. How can i force all edit widgets to update there edited value before calling flush()
okButton.addSelectHandler(new SelectEvent.SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
description.finishEditing();
if (driver.isDirty()) {
vehicleType = driver.flush();
maintenanceService.updateEntityBase(vehicleType, new AsyncCallbackImp<TrailerType>() {
@Override
public void onSuccess(TrailerType result) {
System.out.println();
callback.onSuccess(result);
}
});
}
dialog.hide();
}
});
-
13 Jul 2012 6:07 AM #3
Hi!
I am having the exact same problem. Any work-around found?
-
13 Jul 2012 7:12 AM #4
There was an issue related to this in pre-release versions of GXT 3, but has been resolved to my knowledge in 3.0.0. Take a look at the example at http://www.sencha.com/examples/#Exam...e:basicbinding - try to edit the field, and notice what happens if you don't leave the field and click on the 'save' button.
The code used there, nearly identical to the example provided by the original poster:
If you think you've found a bug, please provide us with a way to reproduce it, either in our explorer demos, or with a complete, working code sample.Code:save.addSelectHandler(new SelectHandler() { @Override public void onSelect(SelectEvent event) { driver.flush(); stock = driver.flush(); if (driver.hasErrors()) { new MessageBox("Please correct the errors before saving.").show(); return; } updateDisplay(); stockStore.update(stock); } });
-
15 Jul 2012 10:47 PM #5
FinishEditing
FinishEditing
I created a method which I call before I do the flush.
Code:public static boolean validateFormPanel(FormPanel formPanel) { for (int i = 0; i < formPanel.getFields().size(); i++) { IsField<?> isField = formPanel.getFields().get(i); if (isField instanceof Field ) { try { ((Field) isField).finishEditing(); } catch (NullPointerException e) { } } isField.validate(false); } return formPanel.isValid(); }
-
16 Jul 2012 3:18 AM #6
hi,
@colin
I am doing exactly as you wrote (same result with or without the second flush operation in your sample code). The last edited property does not have the entered value, if I press a button to retrieve the value of the edited object via a flush operation from the driver. If I first press TAB and then the button, the value is contained in the object.
Unfortunately I could not reproduce this error in a smaller sample. In the sample, everything worked as it should.
@christie
Seems, that finishediting was indeed not called. After adding a call to finishediting, it worked like a charm. Perhaps there is a timing problem or a required event is not raised in this particular case. Thanks for the pointer!
-
17 Jul 2012 4:45 PM #7
Thanks for the feedback - the samples we've had haven't experienced this issue, so we would welcome a working sample that can demonstrate the bug.
In the meantime, while @christiedavel's fix works for a FormPanel, we don't encourage using a FormPanel unless you actually want an html <form> tag. Instead, consider the FormPanelHelper's static methods to start at a given container and find all Fields declared within it.
-
20 Jul 2012 1:33 AM #8
Thanks for the pointer, I will try this. as soon as I will find some time I will try to reproduce this behavior.
-
20 Jul 2012 12:40 PM #9
One issue that has been brought to my attention is when triggering driver.flush() (actually field.getValue(), but flush() calls getValue()) on certain dom events like MouseDownEvent. One example of this is the ListView or Grid selection models, which pay attention to this pre-click event to handle multiple selection.
This is a problem because MouseDownEvent on the newly focused element doesn't actually focus the element just yet, so the TextField still has focus, and so it hasn't parsed/saved its current value, and the old value is still used.
In cases like this, rather than calling finishEditing on every field, I'd offer two suggestions:
* Use ClickEvent instead - there isn't a need to get the data _that_ early, give the user a chance to actually lift the mouse button!
* Defer the flush() call - use the Scheduler to wait until the next event loop, after which Blur and the new Focus will both have occurred, and the real value will be available.
In a case where you must have the value _while the user is editing_ (like a Timer going off) finishEditing will work, but it will likely stop the user from editing the field they are working on - they'll need to re-focus before they can continue. ValueBaseField.getCurrentValue() can be used in some cases to work with this, but isn't usable right away from an editor - an adapter would probably need to be written to wrap the field and call this other method instead.
-
27 Jul 2012 1:40 AM #10
Thank you for the background information, but in my case this does not seem to be applicable, since I am using select events only (in the form of @UiHandler-annotated member functions).
Thank you for reporting this bug. We will make it our priority to review this report.


Reply With Quote