.focus 不停留

.focus not staying put

我在 SSJS 脚本库中保存了一个验证例程。当我点击保存按钮时它被调用。目的(正如这里的几篇文章中所见)是执行表单验证、创建错误消息,然后 onClientLoad 事件将显示该消息并且 return 关注它找到的第一个问题字段。

这是代码片段;来自 SSJS 脚本库:

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>

ef.focus() 确实有效。我可以看到光标闪烁到出现错误的第一个字段,但随后它消失了。

我不知道是什么原因造成的。我尝试跟随调试器,但在退出 onClientLoad 事件后,我开始徘徊在非常密集的代码中(显示 UI 的上半部分变灰,所以我真的无法判断何时应用焦点然后删除。我没有定义任何其他事件。

我遇到过类似的问题,其中一些 "under the hood Dojo magic" 正在发生 - 因此移动了焦点。

我绕过它的方法有点"hack",我使用客户端超时功能将焦点设置延迟 100-200 毫秒。

不太理想,但我放弃了让它直接工作的尝试;-)

/约翰

请在 ef.focus() 行后添加 return false。这将立即停止执行来自 运行 的任何服务器端代码。