.focus 没有原地踏步
Posted
技术标签:
【中文标题】.focus 没有原地踏步【英文标题】:.focus not staying put 【发布时间】:2015-07-08 14:00:24 【问题描述】:我在我的 SSJS 脚本库中保存了一个验证例程。当我点击保存按钮时它会被调用。目的(如这里的几篇文章所示)是执行表单验证,创建错误消息,然后 onClientLoad 事件将显示消息并将焦点返回到它找到的第一个问题字段。
这里是sn-ps的代码;来自 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 的上半部分是灰色的,所以我真的不知道什么时候应用焦点然后删除。我没有定义任何其他事件。
【问题讨论】:
如果您有两个或更多错误,它会尝试循环遍历所有错误吗?(甚至非常快) 它循环遍历将错误消息存储在 errorMessages 字段中的任何错误。在 setError 例程中,我通过获取 viewScope 变量获取了在“efn”字段中遇到错误的第一个字段的 ID,该字段在我的 onClientLoad 事件中得到。调试器显示我正在返回正确的字段并且焦点命令正在工作,我看到垂直的黑色光标线暂时出现在该字段中,但随后它消失了。 onClientLoad 事件之后发生了一些事情 只是为了好玩,请尝试在 if 语句后添加“return false”行 您的代码是在“客户端”onClientLoad 还是“服务器”onClientLoad 中?它看起来在服务器端,但 XSP.getElementByID 是客户端。我从未尝试过,但我认为 XSP 类和方法在 SSJS 中不起作用。 你是不是打算把这个加到Client端,不小心放到了Server端,好办?? 【参考方案1】:请在ef.focus()
行之后添加return false
。这将立即停止执行任何服务器端代码。
【讨论】:
【参考方案2】:我遇到过类似的问题,其中一些“幕后道场魔法”正在发生 - 因此转移了焦点。
我解决它的方法有点“hack”,我使用客户端超时功能将焦点设置延迟 100-200 毫秒。
不理想,但我放弃了让它直接工作的尝试;-)
/约翰
【讨论】:
我将代码替换为;设置超时(函数()ef.focus(),300)。我不认为这是它。以前的尝试,我硬编码字段名称而不是使用 dojo 函数。结果相同。 嗯...好的。那只是一个快速的尝试;-)以上是关于.focus 没有原地踏步的主要内容,如果未能解决你的问题,请参考以下文章
无语!你竟然连CompletableFuture都不知道,还天天说在jdk8原地踏步~