How can I cancel a form submission using GWT?
I need to validate the form and process some of the data before actually submitting it.
So far I did the following, the problem is that the form is submitted even if the SubmitEvent is cancelled.
form.addSubmitHandler( new SubmitHandler() {
#Override
public void onSubmit(SubmitEvent event) {
if(validate()) {
// i do some processing here
form.submit();
}
else event.cancel(); // submits anyway
}
});
Is this a GWT issue? How should I do?
edit: I just found out that if it was a Button that uses form.submit() on click, the submit event is cancelled. However if a SubmitButton is clicked, the event is not cancelled.
So I guess this is a browser behavior. Still, I need to find way...
edit: just found out that it does only happen in development mode, I feel silly not to have tried outside development mode before.
It's an issue that only happen in development mode
I have reported the issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=5067
Related
I try to add a Googla Pay button on a website. I follow the Google Pay implementation tutorial (https://developers.google.com/pay/api/web/guides/tutorial).
There is a code:
var paymentsClient = getGooglePaymentsClient();
paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
.then(function(response) {
//...
})
.catch(function(err) {
//...
});
I need to get some data from my server side before I call the above code so I do the http post request. Within success hanlder of my post request I call the above code. It works fine in my Android browser and my laptop browser. But it doesn't work from Safari. I get the "Unexpected developer error please try again later" error. If I call it without ajax request it works in Safari as well. Could someone suggest the solution?
Thanks for including the jsfiddle.
The reason that it's not working is because Google Pay tries to open a popup window when you call loadPaymentData in Safari. When a new window is triggered as the result of a click event (user initiated action), the popup window opens as expected. When it is triggered by a non-user initiated action, Google Pay gets loaded in the same window which ends up causing it to fail.
It looks like when you make an ajax request in the click handler and then call loadPaymentData, Safari considers it a non-user initiated action.
Check out the following example in Safari:
const ajaxButton = document.getElementById('ajax');
const nojaxButton = document.getElementById('nojax');
ajaxButton.addEventListener('click', event => {
$.get('/echo/json/', () => {
window.open('about:blank');
});
});
nojaxButton.addEventListener('click', event => {
window.open('about:blank');
});
I would recommend avoiding making any http calls on the button click event before loadPaymentData. If you can fetch the data before the button is clicked, then do so.
Out of interest, what kind of data are you fetching?
I can of course force install my pwa on the device. However, existing sites on the market themselves offer the user to install the application. And about the possibility to install my application, the user will not know if he does not want to try (most likely he will not want to).
How to make the user such an offer, I unfortunately have not yet figured out. Articles could not be found (perhaps incorrectly set the search), the analysis of the code of service workers also did not help.
Help please.
On Chrome mobile, the default prompt is very visible. On desktop, less so.
But, Chrome actually has an event for this. If everything is in order for a PWA to be installed, the 'beforeinstallprompt' event is fired. You can simply add a listener to this event, and use that to display a message on your page to inform the user of the possibility to install the PWA.
The following example is written for Angular, but you can get the idea of the event.
ngOnInit() {
/**
* The beforeinstallprompt event is only triggered in certain browsers. This event simply indicates that everything is in order
* for the user to install the PWA. On mobile Chrome, a message is shown by default to the user, but we can also interfere and
* block it. This way, we can show our own message, and continue the event on our own terms.
* In this case, we store the event, and prevent it from continuing. We then show a regular <div> in the HTML, which contains the
* question to install the PWA, and a button to do so. That button then triggers the prompt, which the user can then accept or deny.
* The result of this prompt is mostly irrelevant to the functionality. Our code has no impact on the proceedings of the installation
* after the user has accepted the prompt.
* A possible usecase for the Promise resolved by the prompt, is for metrics. We can use the result to calculate how many users have
* accepted or denied our prompts.
*/
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
this.deferredPrompt = e;
console.log('beforeinstallprompt!');
// if askedOnce is true, no need to ask again.
this.showPwaPrompt = !this.askedOnce;
});
}
acceptPwaPrompt() {
this.showPwaPrompt = false;
this.askedOnce = true;
this.deferredPrompt.prompt(); // Wait for the user to respond to the prompt
this.deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
this.deferredPrompt = null;
});
}
I have the following code in the onModuleLoad() of my application:
Window.addWindowClosingHandler(new ClosingHandler() {
#Override
public void onWindowClosing(ClosingEvent event) {
event.setMessage("If you choose to close, application will sign out");
}
});
//sign out on close
Window.addCloseHandler(new CloseHandler<Window>() {
#Override
public void onClose(CloseEvent<Window> event) {
sendLogout();
}
});
The sendLogout() function looks like this:
// Set up the callback object.
AsyncCallback<String> callback = new LogoutCallback(this);
// Make the call to the survey service.
SurveySystemService.Util.getInstance().logout(details, callback);
Where 'details' is some object.
It works just fine when the window is closed, but if I try to refresh the page, it doesn't log out. What I figured is that since the call is asynchronous, it doesn't finish getting the message off to the server before the module is restarted.
I've tried:
1. creating and calling the callback inside the onClose method.
2. using a Timer to check if the call was made.
3. Endless loos which check the same as the above (I got desperate).
In all of these solutions, the program would reach the callback creation, but the server never received anything.
any help with this?
Can you just call logout any time the page first loads. Due to the stateless nature of the web the GWT application will not know the difference between someone hitting refresh or just navigating to the page.
You can store an ID variable in session storage which should be maintained until the browser window or tab is closed. If on the application start the ID variable exists in session storage you can use it to trigger the log out.
I'm trying to implement a browser auto-complete feature for my application Login view. However it seems that the only solution is through FormPanel. The problem with this is that it is intended to be used with standard servlet; in this case I will need to rewrite my "login" code, since what I have is Login RPC. Is there a way to do browser login form auto-complete with using GWT RPC for the Login service?
EDIT:
I tried this code:
FormPanel form = FormPanel.wrap(Document.get().getElementById("login-input"), true);
form.setAction("javascript:;");
form.addFormPanel(new FormPanel() { // EDIT: method undefined?
public void onSubmit(FormSubmitEvent event) {
// do some validation before submitting (non-empty fields)
// and call event.setCancelled(true) if needed.
// get the fields values and do your GWT-RPC call or
// RequestBuilder thing here.
}
public void onSubmitComplete(FormSubmitCompleteEvent event) {
// will never be called.
}
});
However, form.addFormPanel method is undefined.
It's possible with GWT-RPC too (but you still need the FormPanel for similar <form>): https://groups.google.com/d/msg/google-web-toolkit/KyzgtqqoJGE/5bqvG8pBSRYJ
According to GWT FormPanel Javadoc :
http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/FormPanel.html
replace form.addFormPanel with :
the deprecated method form.addFormHandler
which is now replaced with
form.addSubmitCompleteHandler and form.addSubmitHandler
I'm using the Facebook Registration Plugin (http://developers.facebook.com/docs/plugins/registration/) to register users for our site. The problem is I can't seem to get custom validation working and was wondering whether it's a mistake on my part or something wrong with Facebook.
This is the XFBML code that I'm using:
<fb:registration
fields="[{'name':'name'},
{'name':'email'},
{'name':'password','description':'Enter a password','type':'text'}]"
redirect-uri="http://local.dev"
onvalidate="validateFacebookRegistrationForm">
</fb:registration>
and I have a global function called validateFacebookRegistrationForm which has the following code in it:
function validateFacebookRegistrationForm(form) {
errors = {};
if (form.password == "") {
errors.password = "No Password Entered";
}
return errors;
}
I would expect hitting the register button on the form would do nothing and the validation message would show up... instead I get a popup like this:
http://i.imgur.com/ERxw3.jpg
Once the popup is closed, the form is validated ... and the error message shows. Clicking register again will not submit the form until the errors have been fixed - which is the how the form should behave in the first instance!
The Facebook Registration plugin does not client-side validate until AFTER the user has pressed "Register" and then in the popup pressed "Continue". Then, it will do the "client-side" validation... it really doesn't make sense to go in that order but that's how it seems to be.
Your code is fine.