PDA

View Full Version : Flush not working everytime in editor



christiedavel
18 Jan 2012, 1:48 AM
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:



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();
}
});
}
}


Any suggestions???

christiedavel
22 Jan 2012, 11:28 PM
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();
}
});

FEAT
13 Jul 2012, 6:07 AM
Hi!

I am having the exact same problem. Any work-around found?

Colin Alworth
13 Jul 2012, 7:12 AM
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/#ExamplePlace: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:


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);
}
});


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.

christiedavel
15 Jul 2012, 10:47 PM
I created a method which I call before I do the flush.



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();


}

FEAT
16 Jul 2012, 3:18 AM
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!

Colin Alworth
17 Jul 2012, 4:45 PM
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.

FEAT
20 Jul 2012, 1:33 AM
Thanks for the pointer, I will try this. as soon as I will find some time I will try to reproduce this behavior.

Colin Alworth
20 Jul 2012, 12:40 PM
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.

FEAT
27 Jul 2012, 1:40 AM
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).

balakishan.r
13 Dec 2012, 5:44 AM
We are also having the similar issue. Can any one help us, in which version of GXT it got resolved.

Colin Alworth
13 Dec 2012, 6:18 AM
Balakishan - I was never able to reproduce it after the actual 3.0.0 release, and definitly not in 3.0.1, the current non-support-subscriber release. If you are using an earlier version than those, consider upgrading, or defer the call to flush() using the scheduler class - that's how we got around in in very early releases before we resolved the button focus issue.

If you can provide the specific details of your case - what version of GXT, what browser, and the circumstances around calling flush() - we can probably be more helpful.

Tin Bui
3 May 2013, 1:14 AM
I faced the same problem and I found that the demo code calls flush() method twice and this solve the problem!
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);
}
});

Colin Alworth
3 May 2013, 8:29 AM
Whoops, that should have been removed - we added that back in GWT 2.3 or 2.2 to solve a bug in GWT itself. If memory serves, it was related to checking for errors.

Which version of GWT and GXT are you using? I think this is working with GWT 2.4.0 and GXT 3.0.1, and I'll remove the extra driver.flush() from our examples to avoid later confusion.

lindsay.thurmond
21 May 2013, 8:51 AM
I thought I was having this same issue, but what was actually happening is that the value in my field was not yet set when calling getValue() because I hadn't clicked off the field yet (annoying I know). What I really wanted was to use getCurrentValue() on the field. To fix, I overrode the getValue() method like the following and used my Extended field instead of the default GXT one.



public class ExtendedTextArea extends TextArea {


public ExtendedTextArea() {
}


@Override
public String getValue() {
// Value should be whats in the box regardless of if the user clicked off yet or not
return this.getCurrentValue();
}
}