Text Field Behavior

Hi, I am facing a problem while using ITMILL toolkit and would be grateful for some help. A have a login form with a text field for username and password and a login button for submiting the login data. I have used the hint that Marko Grönroos gave to a user about making a button default button for a form (http://forum.itmill.com/posts/list/315.page). So the problem i am facing is that in the button handler method I can get only the value of the username text field, the getValue().toString method for the password field returns empty string even though I have typed a password before prerssing the enter button. Note that the problem doesn’t happen if I click the login button in the ordinary way- it only happens when I use the enter button to submit the form. Thank you in advance for the ccoperation and wish you good bugless luck with the uppcomming 5.0 release.

This sounds like a bug in variable / event handling. I’d like to test your source code, could you cut & paste it here?

I am pasting the code - my application has many modules that are linked but I am giving you only the login module- sorry for the messy code for comments but I have been trying many ways to get arround this problem


import com.itmill.toolkit.*;
import com.itmill.toolkit.ui.Field.ValueChangeEvent;

import com.itmill.toolkit.data.*;
import com.itmill.toolkit.data.Property.*;
import com.itmill.toolkit.event.*;
import com.itmill.toolkit.ui.*;
import com.itmill.toolkit.ui.Component.*;
import com.itmill.toolkit.event.Action.Handler;
import com.sun.org.omg.SendingContext.CodeBasePackage.ValueDescSeqHelper;

import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * Simple program that demonstrates "modal windows" that block all access other
 * windows.
 * 
 * @author IT Mill Ltd.
 * @since 4.0.1
 * @see com.itmill.toolkit.Application
 * @see com.itmill.toolkit.ui.Window
 * @see com.itmill.toolkit.ui.Label
 */
public class LoginModule extends com.itmill.toolkit.ui.Panel implements Handler{//,ValueChangeListener{

	BugtrackingApp app = null;
	Label statusLabel = null;
	Button loginButton = null;
	TextField userText = null;
	TextField passText = null;
	int times = 1;
//	String passBuffer= "";
//	String userBuffer= "";
    private String userTexttSubmit = "";
    private String passTexttoSubmit = "";
	public LoginModule(BugtrackingApp app) {
		super("Enter Login Info");
//		passBuffer = "";
//		userBuffer= "";
		userTexttSubmit = "";
		   passTexttoSubmit = "";
		times = 1;
		// set the application to use Corporate -theme
		// setTheme("example");
		// Window main = new Window("Application window");
		// setMainWindow(main);
		// Panel panel = new Panel("Login Information");
		// OrderedLayout ordered = new
		// OrderedLayout(OrderedLayout.ORIENTATION_VERTICAL);
		// ordered.addComponent(new TextField("Name"));
		// ordered.addComponent(new TextField("Email"));
		// ordered.setStyle("form");
		// panel.addComponent(ordered);
		this.app = app;

		CustomLayout mainLayout = new CustomLayout("login");

		this.addComponent(mainLayout);
		this.setHeight(193);
		this.setWidth(305);
		// <span style =\"color:red;\">Test status</span>
		statusLabel = new Label("", Label.CONTENT_XHTML);
		loginButton = new Button("Login", this, "loginClicked");
		
		loginButton.addActionHandler(this);
		Label userlabel = new Label("Username");

		Label passlabel = new Label("Password");
		userText = new TextField();
		userText.focus();
		userText.setRequired(true);
		userText.setImmediate(true);
		passText = new TextField();
		passText.setSecret(true);
		passText.setRequired(true);
		passText.setImmediate(true);
		
		
		
		
		// mainLayout.addComponent(customLayoutPanel, "mainpanel");
		mainLayout.addComponent(userlabel, "userlabel");
		mainLayout.addComponent(userText, "usertext");
		mainLayout.addComponent(passlabel, "passlabel");
		mainLayout.addComponent(passText, "passtext");
		// mainLayout.addComponent(ordered, "logintext");
		mainLayout.addComponent(loginButton, "loginbutton");
		mainLayout.addComponent(statusLabel, "loginstatus");

		// main.addComponent(customLayoutPanel) ;

	}

	/**
	 * Retrieve actions for a specific component. This method will be called for
	 * each object that has a handler; in this example the Ok and Cancel
	 * buttons.
	 */
	public Action[] getActions(Object target, Object sender) {
		Action[] actions = new Action[1]
;

		// Set the action for the requested component
		if (sender == loginButton) {
			// Bind the unmodified Enter key to the Ok button.
			actions[0]
 = new ShortcutAction("Default key",
					ShortcutAction.KeyCode.ENTER, null);
		
		} else
			return null;
		return actions;
	}
	
	/**
 	 * Handle actions received from keyboard. This simply directs the actions to
 	 * the same listener methods that are called with ButtonClick events.
 	 **/
 	public void handleAction(Action action, Object sender, Object target) {
// 		passText.commit();
// 		passText.attach();
// 		passText.valueChange(new ValueChangeEvent(passText));
 		if (target == loginButton ){
 			System.out.println("Called handle actionr");
 			if(ifEmpty()){loginClicked();}
 			
 				if(ifOneEmpty()){
 					//fireEvent(new ValueChangeEvent(passText));
 				// loginButton.focus();	
 					loginClicked();
 				}else{
 					loginClicked();
 				}
 			

 			//this.loginClicked();
 			}
 		
 		
 	}
 	


	public void loginClicked() {
		
		ClearStatusLabel();
		if(CE.getConn() ==null){
		try {
				CE.connectToDB();
			} catch (ClassNotFoundException e) {
				
				e.printStackTrace();
				 
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				 
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
		boolean result = false;
		//passText.focus();
		//System.out.println("entered loginClicked--> " + userBuffer +" : " +passBuffer);
		userTexttSubmit = userText.getValue().toString();
		passTexttoSubmit = passText.getValue().toString();
		
		System.out.println("entered loginClicked--> " + userTexttSubmit +" : " +passTexttoSubmit);
		try {
			if(ifEmpty()){
				result =false;
			}
//			else {
//				
//				if(ifOneEmpty()){
//					return;
//				}else{
//				result = CE.isAuthenticated(userTexttSubmit,passTexttoSubmit,
//						 app);
//				}
//			}
//			
			
			
//			if(!CE.isStringEmpty(userTexttSubmit)){
//				result = CE.isAuthenticated(userTexttSubmit,
//						passBuffer, app);
//			}
//			
//			if(!CE.isStringEmpty(passTexttoSubmit)){
//				result = CE.isAuthenticated(userBuffer,
//						passTexttoSubmit, app);
//			}
	CE.isAuthenticated(userTexttSubmit,passTexttoSubmit, app);
		} catch (SQLException ex) {
			statusLabel
					.setValue("<span style =\"color:red;\">Connection problem with the server</span> ");
			Logger.getLogger(LoginModule.class.getName()).log(Level.SEVERE,
					null, ex);
		}

		if (!result) {
			statusLabel.setValue("");
			userText.setValue("");
			passText.setValue("");
			/*userBuffer = "";
			passBuffer = "";*/
			statusLabel
					.setValue("<span style =\"color:red;\">Invalid username or password</span> ");
		
			userText.focus();
			// test only
			// app.hideLoginModule();
			// app.showMainTabsheet();
			// test only
		} else {
//			userBuffer = "";
//			passBuffer = "";
			app.hideLoginModule();
			app.showMainTabsheet();
		}
	}

	public void ClearStatusLabel() {
		statusLabel.setValue("");
	}
    
	public TextField getuserNameText(){
		return userText;
	}
	
	private boolean ifEmpty (){
		if(userText.getValue().toString().equalsIgnoreCase("")&& passText.getValue().toString().equalsIgnoreCase("")){
			return true;
		}
		return false;
	}
	
	private boolean ifOneEmpty (){
		if(userText.getValue().toString().equalsIgnoreCase("")|| passText.getValue().toString().equalsIgnoreCase("")){
			return true;
		}
		return false;
	}

}
	



Basicly what loginClicked() method does is to call a helper method that denotes if the supplied user credentials for login are correct or not. What I am facing is that the userName is fine but the password is empty. To helpt you more I would say that it seems to me that the application gets the value if there has been an action ot the textfield- for example if I enter values in both fields but before clicking the login button I position the cursor in the username fields everything is fine when I hit enter button to submit. So for me it seems that the last field in which data is entered is somehow not activated an therefore it doesn’t know that it has value when the event is generated. Sorry for the messy code again- I have been using customlayout but I am sure you can try an ordered layout to be more faster for you to test. Thank you again for the cooperation and good luck:-)

Oh. It looks that my default key example doesn’t work properly after all. Sorry about that.

The problem is that the keyboard action is sent immediately when a key is pressed, without sending the current value of the TextField. The current value is sent only when a field loses its focus and causes the ValueChangeEvent. So it appears that keyboard actions can not easily be used for defining the default key.

There’s an alternative method to set the default button, by using setStyle(“default”) for the button, but that works only in IE. Firefox handles buttons a bit differently and doesn’t allow defining a default key without JavaScript, so setting the style would have no effect in Firefox. So, the form would work nicer only with IE.

I can think of one workaround for the problem. I think it would be possible to record the key presses to determine the current value of the field. But that would require editing a server-side value for every backspace, del, etc. and taking into account the current cursor position in the field. It’s a bit worksome…

We’ll have to think what to do with this problem. Sending the value change event before the action might not be desirable, as actions are often used for filtering some keys out. Setting the default key is such a common operation that perhaps there should be a dedicated API method for that. At least some frameworks seem to have one, while some others do not. Using a keyboard action handler is a more general solution.