cjames728
cjames728

Reputation: 193

.focus not staying put

I have a validation routine I keep in my SSJS script library. It gets called when I hit the save button. The purpose (as seen in several posts around here) is to perform form validation, creates the error messages, then the onClientLoad event will display the message and return focus to the first problem field it finds.

Here are the code snippets; From the SSJS script library:

function DBValidate(FormName:String) {
	var efn:string = null;		// error Field Name
	var errorMessages:String = null;
	
	// here is where we group validation by the calling form.
	switch (FormName) {
		case "FieldDef":
		if ( isEmpty(currentDocument.getItemValue("FormName")[0]) ) setError("FormName","Form name cannot be blank");
		if ( isEmpty(currentDocument.getItemValue("EnglishFormName")[0]) ) setError("EnglishFormName","English form name cannot be blank");
		break
		default:
	}
	// We built the error messages (All will be displayed in a promptbox in the onClientLoad event 
	// of the form) The form MUST have an ErrorMessage field because we embed carriage returns 
	// in the message and viewScope.get doesn't like those too much..... We can however pass 
	// the error field(for focus if I ever get that working.....)in a viewScope variable.
	getComponent("ErrorMessage").setValue(errorMessages);
	viewScope.put("errorField",efn);
	if (errorMessages == null ) {
		return true;
	} else { 
		return false;
	}
}
function setError(fName:string,emsg:string){
	// after failing a field validation in DBValidate we
	// make note of the field name and build the error message that
	// we're going to display in the onClientLoad event.
	// Make note of the first field ID to fail so we can
	// set focus to it.
	if (efn==null) efn=getClientId(fName);
	if (errorMessages == null) {
		errorMessages = String.fromCharCode(10) + emsg;
	} else {
		errorMessages += String.fromCharCode(10) + emsg;
	}
	return
}
	<xp:eventHandler event="onClientLoad" submit="false"
		refreshMode="norefresh">
		<xp:this.script>
			<![CDATA[
				// the DBValidation routine sets the ErrorMessage computed field to something
				// if there was an error. If we had one, then we display a message, extract the field
				// name from the message.
				var em = XSP.getElementById("#{id:ErrorMessage}").innerHTML;
				if (em.length > 0) { 
					alert(em);
					var efn = '#{javascript:viewScope.get("errorField")}';
					var ef = dojo.byId(efn);
					ef.focus();
				}
			]]>
		</xp:this.script>
	</xp:eventHandler>

The ef.focus() actually works. I can see the cursor flash into the first field that has the error, but then it goes away.

I have no idea what's causing this. I try to follow in the debugger, but after stepping out of the onClientLoad event, I start wandering into very dense code (the upper piece which shows the UI is grayed out so I really can't tell when focus gets applied then removed. I don't have any other events defined.

Upvotes: 2

Views: 100

Answers (2)

Steve Zavocki
Steve Zavocki

Reputation: 1840

Please add return false after the ef.focus() line. This will cease execution of any serverside code from running immediately after.

Upvotes: 2

John Dalsgaard
John Dalsgaard

Reputation: 2807

I have had similar issues where some "under the hood Dojo magic" is going on - and therefore moves the focus.

The way I have gotten around it is a little "hack" where I use a client side timeout function to delay setting the focus 100-200 ms.

Not ideal, but I gave up trying to make it work directly ;-)

/John

Upvotes: 0

Related Questions