Wicket quick double click submit button - java

I have a problem with a Wicket Form. In my form if a User click twice quickly on a SubmitLink the onSubmit method called twice and there where 2 instances of an object. How can I prevent this? I have tried using a boolean variable
#Override
public void onSubmit(){
if(!submitted){
submitted = true;
dao.save(object);
setResponsePage(differentPage.class);
}
}
This method doesn't work for me. Can anyone help me please?

There are some work around To prevent double submit.
I guess you may not added renderStrategy.So first add setRenderStrategy in Your application class .
Direct, IRequestCycleSettings.RenderStrategy.ONE_PASS_RENDER. Everything is handled in one physical request. This is efficient, and is the best option if you want to do sophisticated clustering. It does not however, shield you from what is commonly known as the Double submit problem.
getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER);
Probably above solution will work with your case. On top of that
You can disable the button on click submit or You can use some indicatorbutton link .

I resolve with this lines of code
save_btn = new AjaxSubmitLink("submit_btn", this) {
protected void onSubmit(AjaxRequestTarget art){
art.appendJavaScript("e.preventDefault();");
}
};
And the
getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER);
of course

Related

GWT forbid History.back() to exit current site

I'm wondering if there is a simple way in GWT to forbid History.back() (or .forward()) to lead to an external site, and define a fallback url if one of this happen.
For example :
Assuming that mysite.com#token, contains a component triggering a History.back().
I am on stackoverflow.com, I paste mysite.com#token in my browser, then click on my component which move me back to stackoverflow, is it possible that click goes in mysite.com instead as a back exit my site?
Thanks for your help!
Use this approach
Window.addWindowClosingHandler(new ClosingHandler() {
public void onWindowClosing(ClosingEvent event) {
event.setMessage("Do you want to leave this site");
}
});

How to listen on save button or assign an event after it was clicked in Vaadin 7

When I am editing grid inline I can save or cancel my grid row changes. I want to update my database entries after button 'save' will be pushed(Data base mechanism has already done) How can I implement it?
My container:
BeanItemContainer<CategoryOfService> beansContainer;
Editing view:
All what I need it know which listeners I have to use. I found some CommitHandler which I can add by EditorFieldGroup class but I can't implement it properly maybe there is have to be another way to resolve problem.
There's kind of a way to capture inline Save click on the grid.
grid.getEditorFieldGroup().addCommitHandler(new FieldGroup.CommitHandler() {
#Override
public void preCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
//...
}
#Override
public void postCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
//...
}
});
After clicking Save both methods preCommit and postCommit get called.
Hope it helps :)
Grid does not currently give you any direct way of adding listeners to the save and cancel buttons for the inline editor, although that is something that might change in Vaadin 7.6.
As a workaround before that happens, the CommitHandler approach that you already mentioned is still supposed to work. You can find a basic example here. The contents of your BeanItemContainer should be fully updated in the postCommit phase.
grid.getEditor().addSaveListener((EditorSaveListener<Product>) event -> {
//your stuf
HibernateDataSource.updateProduct(event.getBean());
});

GWT event prevent default not working in Java

I'm new to GWT and I need to get a right click working. The doco I've read suggests that I need to override the onBrowserEvent() method. I'm just experimenting at this stage. the event is processed and my pop-up appears. However, as soon as I close the pop-up, the usual browser drop down menu appears (with options like "Bookmark this page" and such).
I'm using IceWeasel 24.5.0 (FireFox clone for Debian) and, obviously, Debian (wheezy).
Here's the relevant code:
public ActivityTextCell() {
super(BrowserEvents.MOUSEDOWN, BrowserEvents.MOUSEUP);
}
#Override
public void onBrowserEvent(
com.google.gwt.cell.client.Cell.Context context,
Element parent,
ActivityDTO value,
NativeEvent event,
ValueUpdater<ActivityDTO> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
event.preventDefault();
event.stopPropagation();
if (event.getType().equals(BrowserEvents.MOUSEUP)) {
Window.alert("mouse up event");
}
else {
switch ( event.getButton()){
case NativeEvent.BUTTON_RIGHT:
Window.alert("right mouseclick");
break;
case NativeEvent.BUTTON_LEFT:
Window.alert("left mouseclick");
break;
case NativeEvent.BUTTON_MIDDLE:
default:
break; // Do nothing
}
}
The class ActivityTextCell extends AbstractCell.
So what am I missing? How do I stop the browser from reaticng to the mouse click?
Well it certainly wasn't a matter of a few minutes (as can be seen by the fact that it has taken me a week to get back to this), but I have a solution. I tried reversing the order of the the event.preventDefault() and super.onBrowserEvent() but it didn't really help.
I tried a little experiment on a normal web page. It turns out, that the MOUSEDOWN event doesn't do anything in that context and the usual browser selection menu appears on the MOUSEUP. So the if/else logic sort of fell by the wayside.
What did the trick is to include the following in the top level GUI class immediately after adding the main page:
RootLayoutPanel.get().addDomHandler(new ContextMenuHandler() {
#Override
public void onContextMenu(ContextMenuEvent event) {
event.preventDefault();
event.stopPropagation();
}
}, ContextMenuEvent.getType());
This has the additional benefit (for my purposes, at least) of preventing the Browser from reacting to a right click anywhere in the application view.
As an aside: The purpose of preventing the default action is to stop the Browser doing its own thing Stopping propagation is possibly not required, but I left it in anyway (propagation goes fro the node up to the root, not the other way around). The purpose of overridinging onBrowserEvent() is to enable your own application to handel that event. The use of super.onBrowserEvent() is to allow the event to be handled by your code in the first place. I've given the relevant reference in my previous comment. The book "GWT in Action" is well worth a read if you're likely to be doing a lot of GWT coding.
You call super.onBrowserEvent() which triggers the standard browser response.
You should move event.preventDefault() to the if part of your code, and super.onBrowserEvent() to the else part. You want one of them executed depending on a browser event, but not both.

Models not updating on initial load of homepage in Wicket

I'm having some problems understanding what I'm doing wrong.
What I do:
Override getHomePage() in my Application. I return MyStartPage.class.
MyStartPage is a subclass of MySubPage.
MySubPage is a subclass of MySuperPage.
In MySuperPage I add a Panel. This Panel has a TextField and WebMarkupContainer with a AjaxEventBehavior(onclick) that prints the backing modelObject of the textfield.
What happens when I start my server and browse localhost/MyApp:
The printed modelObject is null even though the user input is not when I click my WebMarkupContainer.
What happens when I start my server, browse localhost/MyApp, go to another Page in my app and then back to MyStartPage:
The printed modelObject matches the user input when I click my WebMarkupContainer.
It also works when I do the following:
Override getHomePage() in my Application and return MyLoginPage. MyLoginPage contains MySigninPanel. In MySigninPanel I override onSignInSucceeded() like this:
#Override
protected void onSignInSucceeded() {
setResponsePage(new MyStartPage());
}
Can someone shed some light on what the correct way of getting my TextField to work properly when the user clicks the WebMarkupContainer the first thing they do?
Thanks in advance!
//EDIT :
This only seems to be a problem in Firefox, or at least it's working fine in Chrome IE9 and IE8-mode in IE9.
Your TextField's model will not be updated with user entered data unless you submit a Form with your click event. Your TextField should be the child of that Form. If it is, then it's content will be sent to the server, converted to the target type, and validated. On success, you'll be able to query the model and view the data entered on your page.
In order to do this, you should use a AjaxFormSubmitBehavior instead of the AjaxEventBehavior you are currently using:
webMarkupContainer.add(new AjaxFormSubmitBehavior(form, "onclick") {
#Override
protected void onSubmit(AjaxRequestTarget target) {
// You can now see what was entered in your TextField
System.out.println(textField.getModelObject());
}
#Override
protected void onError(AjaxRequestTarget target) {
// An error occurred and you should provide some kind of feedback
}
});
Well, i have a solution, although I'm not sure why it works. I added
mountPage("invoice/overview", OverviewPage.class);
In my WebApplication, and now it works in FireFox (OverviewPage is referred to as 'MyStartPage' in my initial post).
Here is what the wicket.ajax.baseurl and the typed url in the browser looked like before the change, when it did not work:
baseUrl: wicket/bookmarkable/eyesys.web.invoice.overview.OverviewPage
browser url: wicket/bookmarkable/eyesys.web.invoice.overview.OverviewPage?1
And after the change:
baseUrl: invoice/overview
browser url: invoice/overview?1

Wrapping/decorating GWT FileUpload

GWT FileUpload comes as a widget that produces so that one can upload a file during form submit (at least it's how I understand it :) ) What I want to do is to make it a better-looking and get rid of standard "Browse..." button.
Since I don't have good GWT experience (and no JavaScript), I looked for existing solutions and found quite a good project - gwtupload. It's good, but I realized I'd love to have my own miniature version (and also, I was curious about how it works). So I browsed through code and tried to extract the magic part. I realized that GWT FileInput is used, but it's not shown, and Button clicks are delegated to this FileInput. The code I tried to extract (only the part that delegates the click) after reviewing sources of gwtupload contains this tricky elem.click() JSNI:
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUpload upload = new FileUpload();
AbsolutePanel container = new AbsolutePanel();
// container.add(upload);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
But this seems not to work: clicking on 'My Browse..' results in no effect (just in case I also tried running with un-commented container.add(upload) line) . Could you please help me in understanding what's wrong/missing in this code sample?
Thank you in advance.
P.S. I know that I have to place it on the FormPanel, and I know the rest about how to perform the actual submit/handling in Servlet; the only thing I want to do is this kind of decoration.
Since I have not received any answers, I had to have more investigation of this issue, so I performed a deeper code analysis of gwtupload project in order to understand how GWT FileUpload (which gets transformed into ) can be decorated.
It turned out that element.click() will only work in browsers which support #click() method (IE, Chrome, Safari). Actually, Manuel Carrasco MoƱino - project author - mentions it within comments. There's second approach (for Firefox & Opera) that uses hack when FileInput is placed on transparent panel, which however is placed over some decorated button (using absolute positioning); comment by Manuel:
When the user puts his mouse over the button and clicks on it, what really happens is that the user clicks on the transparent file input showing the choose file dialog.
After that, the main work is correctly applying style attributes to elements.
Thus, there are two implementations of custom file upload component, and GWT deferred binding is used to instantiate them depending on Browser.
As for example I mention in my question, there're few fixes ("upload" has to be added to to the container, and it can be set to #setVisible(false)):
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUploadWithMouseEvents upload = new FileUploadWithMouseEvents();
AbsolutePanel container = new AbsolutePanel();
container.add(upload);
upload.setVisible(false);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
This example works fine in IE8.
P.S. Thanks to Manuel for his great library :)

Categories

Resources