Thanks for the insightful post.

I have noticed something similar for chrome. While  remembering
login/password was working for firefox/IE it was not working for chrome
until a reload... It didn't cross my mind to programmatically cause a
reload...

   Vassilis


On Thu, Jul 10, 2014 at 1:48 AM, Blake McBride <blake1...@gmail.com> wrote:

> After a great deal of work, I finally have the whole browser-save-password
> code working on all browsers I can find (Chrome, IE, Firefox, Safari).  The
> code graciously provided by Saumar Hajjar in this thread does work.  You
> do, however, have to understand it in order to use it in your application.
>  Given the state of HTML and browser technology, as well as the various
> specific browsers, this code is incredibly fragile and sequence dependent.
>  It took me many days of debugging and trial-and-error coding to get it all
> working.  Now that it does work and I have some degree of understanding, I
> thought I would share some of the important points I discovered.  I hope
> this can be helpful to others.  I apologize in advance to those of you who
> find my observations obvious.
>
> Notice the line that has Window.Location.reload().  That critical line
> makes the whole thing work differently than anything you would have
> expected.  That line causes the whole page to reload from scratch losing
> all state information (including JavaScript variables, GWT instance and
> static variables, etc.) _except_ session data. You will notice that his
> backend code utilizes session data in order to keep track of the fact that
> he'd been there before (the user logged in).  This is the reason the first
> thing he has to do is call a backend service - to find out which state he
> is in (user logged in or not).  The system must re-load like this
> (according to him) in order for all browsers to execute their save-password
> operation.  Password saving happens at that reload point.
>
> Interestingly, his note states that the reload call is only necessary for
> Chrome.  Unfortunately, that one line dictates most of the architecture.
>  In other words, if that line wasn't required, a far simpler approach could
> be used.
>
> As has been stated all over the place, the browser will only save the
> password if the password stuff is in the original HTML file - not GWT added
> controls.  This means that you will likely want to make the login HTML
> disappear after they log-in, and re-appear when they log out.  I did that
> by wrapping the whole HTML body in a div like this:
>
> <div class="login-page" id="login-page" style="display: none;"> ....
>  </div>
>
> I could then control its visibility with:
>
>     private void hideLoginPage() {
>         RootPanel.get("login-page").setVisible(false);
>     }
>
>     private void showLoginPage() {
>         RootPanel.get("login-page").setVisible(true);
>     }
>
>     private void reloadLoginPage() {
>         Window.Location.reload();
>     }
>
> In my case, I set style="display: none;" on the div to prevent it from
> showing at first.  Something I needed.  If you want to show it right away,
> just remove that.  Importantly, I discovered that showLoginPage() can only
> be called _after_ all of the calls to the various wrap() methods have been
> called.
>
> Another thing I noticed, my call to reloadLoginPage() (in order to get the
> browser to save the password) only worked in response to a backend call -
> as part of the response handler as he does below.  During testing, if I
> eliminated the backend call, the reloadLoginPage() would not cause the
> browser to save the password.
>
> This is all I can think of.  I hope it is helpful.
>
> Blake McBride
>
>
>
>
>
> On Mon, Jun 9, 2014 at 12:39 AM, Saumar Hajjar <sau...@gmail.com> wrote:
>
>> Working example
>> *PleaseSaveMyPassword.html:*
>> <!doctype html>
>> <html>
>>   <head>
>>     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
>>     <title>Please Save My Password</title>
>>     <script type="text/javascript" language="javascript"
>> src="pleasesavemypassword/pleasesavemypassword.nocache.js"></script>
>>     <style>
>> h1 {font-size: 2em; font-weight: bold; color: #777777; margin: 40px 0px
>> 70px; text-align: center;}
>> #gwt, table {width: 100%;}
>>  .loginPanel {width: 300px; margin: 0 auto; border: 1px solid #ccc;
>> border-radius: 5px;}
>> input {width: 200px; float: right;}
>>  button {width: 80px; float: right;}
>> .loggedInPanel {width: 300px; margin: 0 auto; font-size: 1.5em;}
>> .gwt-HTML {float: left;}
>>  a {float: right;}
>> </style>
>>   </head>
>>   <body>
>>     <h1>Please Save My Password</h1>
>>     <div id="gwt"></div>
>> <div id="login" style="display: none;">
>> <form id="login_form" action="javascript:;">
>>  <input type="text" name="username" id="login_username" />
>> <input type="password" name="password" id="login_password" />
>>  <button type="submit" id="login_submit"></button>
>> </form>
>> </div>
>>   </body>
>> </html>
>>
>> *PleaseSaveMyPassword.java:*
>> package com.sh.pleasesavemypassword.client;
>>
>> import com.google.gwt.core.client.EntryPoint;
>> import com.google.gwt.core.client.GWT;
>> import com.google.gwt.event.dom.client.ClickEvent;
>> import com.google.gwt.event.dom.client.ClickHandler;
>> import com.google.gwt.user.client.DOM;
>> import com.google.gwt.user.client.Window;
>> import com.google.gwt.user.client.rpc.AsyncCallback;
>> import com.google.gwt.user.client.ui.Anchor;
>> import com.google.gwt.user.client.ui.Button;
>> import com.google.gwt.user.client.ui.FlexTable;
>> import com.google.gwt.user.client.ui.FlowPanel;
>> import com.google.gwt.user.client.ui.FormPanel;
>> import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
>> import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
>> import com.google.gwt.user.client.ui.HTML;
>> import com.google.gwt.user.client.ui.Label;
>> import com.google.gwt.user.client.ui.PasswordTextBox;
>> import com.google.gwt.user.client.ui.RootPanel;
>> import com.google.gwt.user.client.ui.SubmitButton;
>> import com.google.gwt.user.client.ui.TextBox;
>>
>> public class PleaseSaveMyPassword implements EntryPoint {
>>  private static final BackendServiceAsync backend =
>> GWT.create(BackendService.class);
>>  private static class LoginForm extends FlowPanel {
>>  private static LoginForm instance = null;
>> private static final TextBox txtUser =
>> TextBox.wrap(DOM.getElementById("login_username"));
>>  private static final PasswordTextBox txtPassword =
>> PasswordTextBox.wrap(DOM.getElementById("login_password"));
>> private static final Button btnSubmit =
>> SubmitButton.wrap(DOM.getElementById("login_submit"));
>>  private static final FormPanel form =
>> FormPanel.wrap(DOM.getElementById("login_form"));
>>  public static LoginForm getInstance() {
>> if (instance == null) {
>> instance = new LoginForm();
>>  }
>> return instance;
>> }
>> private LoginForm() {
>>  setStyleName("loginPanel");
>>
>> FlexTable table = new FlexTable();
>> table.setWidget(0, 0, new Label("User:"));
>>  table.setWidget(0, 1, txtUser);
>> table.setWidget(1, 0, new Label("Password:"));
>> table.setWidget(1, 1, txtPassword);
>>  btnSubmit.setText("Login");
>> table.setWidget(2, 1, btnSubmit);
>> form.setWidget(table);
>>  add(form);
>>  form.addSubmitHandler(new SubmitHandler() {
>>  @Override
>> public void onSubmit(SubmitEvent event) {
>> btnSubmit.setEnabled(false);
>>  backend.login(txtUser.getText(), txtPassword.getText(), new
>> AsyncCallback<String>() {
>> @Override
>>  public void onFailure(Throwable caught) {
>> Window.alert(caught.getMessage());
>> btnSubmit.setEnabled(true);
>>  }
>>
>> @Override
>> public void onSuccess(String result) {
>>  if (result == null) {
>> Window.alert("Invalid username or password");
>> btnSubmit.setEnabled(true);
>>  }
>> else {
>> // This is the only I've found that makes Chrome happy:
>>  Window.Location.reload();
>> //  IE and FF don't require this reload thing.
>> // showLoggedInContents(result);
>>  }
>> }
>> });
>> }
>>  });
>> }
>> }
>>  public void onModuleLoad() {
>>  // check if the user is already logged in
>> backend.getLoggedInUser(new AsyncCallback<String>() {
>>  @Override
>> public void onSuccess(String result) {
>> if (result == null)
>>  showLoginForm();
>> else
>> showLoggedInContents(result);
>>  }
>>  @Override
>> public void onFailure(Throwable caught) {
>>  Window.alert(caught.getMessage());
>> }
>> });
>>  }
>>  private void showLoginForm() {
>>  RootPanel.get("gwt").clear();
>> RootPanel.get("gwt").add(LoginForm.getInstance());
>> }
>>  public static void showLoggedInContents(String user) {
>> FlowPanel loggedInPanel = new FlowPanel();
>>  loggedInPanel.setStyleName("loggedInPanel");
>>  HTML html = new HTML("Hello, <strong>" + user + "</strong>");
>>  loggedInPanel.add(html);
>>  Anchor a = new Anchor("Logout");
>>  a.addClickHandler(new ClickHandler() {
>> @Override
>> public void onClick(ClickEvent event) {
>>  backend.logout(new AsyncCallback<Void>() {
>> @Override
>> public void onFailure(Throwable caught) {
>>  Window.alert(caught.getMessage());
>> }
>>
>> @Override
>>  public void onSuccess(Void result) {
>> Window.Location.reload();
>> }
>>  });
>> }
>> });
>> loggedInPanel.add(a);
>>  RootPanel.get("gwt").add(loggedInPanel);
>>  }
>> }
>> *BackendServiceImpl.java:*
>> package com.sh.pleasesavemypassword.server;
>>
>> import com.google.gwt.user.server.rpc.RemoteServiceServlet;
>> import com.sh.pleasesavemypassword.client.BackendService;
>>
>> @SuppressWarnings("serial")
>> public class BackendServiceImpl extends RemoteServiceServlet implements
>> BackendService {
>>
>> @Override
>>  public String getLoggedInUser() {
>> return (String) getThreadLocalRequest().getSession().getAttribute("user");
>>  }
>>
>> @Override
>> public String login(String user, String password) {
>>  if (password.equals("ta7yasoorya")) {
>> getThreadLocalRequest().getSession().setAttribute("user", user);
>>  return user;
>> }
>> return null;
>> }
>>
>> @Override
>> public void logout() {
>> getThreadLocalRequest().getSession().removeAttribute("user");
>>  }
>>
>> }
>>
>>
>> Em domingo, 8 de junho de 2014 23h17min43s UTC-3, Blake escreveu:
>>
>>> On Sat, Jun 7, 2014 at 5:29 PM, Jens <jens.ne...@gmail.com> wrote:
>>>
>>>>  Other than that you should follow your original approach and let the
>>>>> browser/password manager ask the user to store the password.
>>>>>
>>>>
>>> That is clearly the best and my preferred approach.  The problem is that
>>> no person and no web site has stated they know how to do it (in a way that
>>> supports most modern browsers), and here is specifically how it is done (a
>>> working example).  The web sites have many half solutions, and I have seen
>>> many "try this" solutions.  I am weaker than most in this technology, and I
>>> am a bit lost.  I think the only thing that is going to help me is a
>>> working example.
>>>
>>> Thanks.
>>>
>>> Blake
>>>
>>>  --
>> You received this message because you are subscribed to the Google Groups
>> "Google Web Toolkit" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to google-web-toolkit+unsubscr...@googlegroups.com.
>> To post to this group, send email to google-web-toolkit@googlegroups.com.
>> Visit this group at http://groups.google.com/group/google-web-toolkit.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to google-web-toolkit+unsubscr...@googlegroups.com.
> To post to this group, send email to google-web-toolkit@googlegroups.com.
> Visit this group at http://groups.google.com/group/google-web-toolkit.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Vassilis Virvilis

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

Reply via email to