This is a useful technique, thanks. You didn't mention that
injectLoginFunction() needs to be called around the same time as
form.setAction(...).

This technique would be more convenient if "doLogin" wasn't a static
method.

I tried to change to non-static, such as:

   private native void injectLoginFunction() /*-{
      $wnd.__gwt_login = [email protected]::doLogin
();
   }-*/;

   private void doLogin() {}

This causes a stack trace (GWT 1.6.4, hosted mode):

     [java] Exception occurred in MethodDispatch.invoke:
     [java] Exception in thread "main" java.lang.ClassCastException
     [java]     at java.lang.Class.cast(Class.java:2990)
     [java]     at com.google.gwt.dev.shell.JsValueGlue.get
(JsValueGlue.java:128)
     [java]     at com.google.gwt.dev.shell.moz.MethodDispatch.invoke
(MethodDispatch.java:70)
     [java]     at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event
(Native Method)
     [java]     at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event
(OS.java:5273)
     [java]     at org.eclipse.swt.widgets.Display.eventProc
(Display.java:1135)
     [java]     at
org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native
Method)
     [java]     at
org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:1428)
     [java]     at org.eclipse.swt.widgets.Display.readAndDispatch
(Display.java:2840)
     [java]     at com.google.gwt.dev.SwtHostedModeBase.processEvents
(SwtHostedModeBase.java:235)
     [java]     at com.google.gwt.dev.HostedModeBase.pumpEventLoop
(HostedModeBase.java:558)
     [java]     at com.google.gwt.dev.HostedModeBase.run
(HostedModeBase.java:405)
     [java]     at com.google.gwt.dev.HostedMode.main(HostedMode.java:
232)


So I stuck with a static method.

When I tried to wrap a form element inside doLogin(), the wrap call
would silently fail and terminate the doLogin() function.

Example:

private static void doLogin() {
  GWT.log("before", null);
  TextBox.wrap(Document.get().getElementById("login_username"));
  GWT.log("after", null);
}

The "before" is printed to the log, but the "after" is not. The
getElementById() succeeds, I tried printing that out before the wrap()
call and that works.

I opted to wrap all the elements beforehand into static fields of my
class. I also saved "this" to a static field so I can call back into
my instance from doLogin().

Hope this helps others trying to use this technique.

On Feb 26, 10:21 am, Thomas Broyer <[email protected]> wrote:
> If you want to have browsers auto-complete username/password in your
> application's login form, you probably did (*I* did) this:
> 1. follow recommandations 
> fromhttp://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecur...,
> i.e. your form and fields have to be in the original markup and you
> mustn't use .submit() but let the browser submit using, say... a
> submit button?
> 2. use something like that in your code:
>    // note the "true" second argument, to create a hidden iframe
>    FormPanel form = FormPanel.wrap(Document.get().getElementById
> ("login"), true);
>    form.addFormPanel(new FormPanel() {
>       public void onSubmit(FormSubmitEvent event) {
>          // do some validation before submitting (non-empty fields)
>          // and call event.setCancelled(true) if needed.
>       }
>       public void onSubmitComplete(FormSubmitCompleteEvent event) {
>          // somehow "parse" event.getResults() to know whether it
>          // succeeded or not.
>       }
>    });
> 3. Your server have to send its response in with Content-Type:text/
> html, even if its JSON (hence the "parse" above)
>
> But there's actually an alternative!
>
> It never occured to me before someone pointed me to a login page that
> does it: if your form submits to a javascript: URL, then the browser's
> "auto-complete" feature will work (provided the form and fields were
> in the original HTML page markup, same limitation as above).
>
> What it means is that you can use GWT-RPC or RequestBuilder!!!
>
> Your code now looks like:
>    private static native void injectLoginFunction() /*-{
>       $wnd.__gwt_login = @com.example.myapp.client.App::doLogin();
>    }-*/;
>
>    private static void doLogin() {
>       // get the fields values and do your GWT-RPC call or
>       // RequestBuilder thing here.
>    }
>    ...
>    // notice that we now pass "false" as the second argument
>    FormPanel form = FormPanel.wrap(Document.get().getElementById
> ("login"), false);
>    form.setAction("javascript:__gwt_login()");
>
> And of course, you can still validate the form before it's submitted:
>
>    form.addFormPanel(new FormPanel() {
>       public void onSubmit(FormSubmitEvent event) {
>          // do some validation before submitting (non-empty fields)
>          // and call event.setCancelled(true) if needed.
>       }
>       public void onSubmitComplete(FormSubmitCompleteEvent event) {
>          // will never be called.
>       }
>    });
>
> Tested in IE7, Firefox 3.0 and Opera 10alpha; please update if it
> works (or doesn't work) for you in other browsers.
> The previous solution (using the iframe) was successfully tested in
> IE6, IE7, IE8 (beta 1 at that time), Firefox 2 and 3.0, Opera (9.62 at
> that time), Safari 3 for Windows and Google Chrome (1 and 2).

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to