如何以编程方式打开 Dojo djFilteringSelect 下拉列表

Posted

技术标签:

【中文标题】如何以编程方式打开 Dojo djFilteringSelect 下拉列表【英文标题】:How to programmatically open a Dojo djFilteringSelect drop down list 【发布时间】:2015-08-27 08:28:31 【问题描述】:

好的,这应该是可行的——而且非常简单,只要知道如何获取 djFilteringSelect 对象的句柄。

用例:我已经接管了扩展现有 XPage 的请求,该 XPage 具有下拉值列表的功能,不仅在用户单击 djFilteringSelect 输入字段右侧的小箭头时,而且在用户单击只需点击该字段。此 XPage 的大部分初始条目都是在制造现场完成的(使用触摸屏 - 没有鼠标/键盘)。随后的处理由使用“普通”计算机的用户完成。

所以我尝试“捕捉”“click”、“mousedown”或“mouseup”事件。我可以做到这一点 - 但我无法掌握我知道的过滤选择有一个方法“openDropDown()”,它可能会做我需要做的事情......我也尝试过模拟按键事件“arrowdown”如果我这样做也会提供相同的体验...我什至尝试延迟按键事件并添加一些上下文 - 但没有任何效果。

所以这是我目前非常简单但不起作用的示例:

                <xe:djFilteringSelect id="Antal" defaultValue="1">
                    <xp:selectItems id="selectItems13">
                        <xp:this.value><![CDATA[$javascript:var values=[];var i=0;while(i<=20)values.push(''+i++);return values;]]></xp:this.value>
                    </xp:selectItems>
                    <xp:selectItem itemLabel="20+"></xp:selectItem>

                    <xp:eventHandler event="onKeyUp" submit="false">
                        <xe:this.script><![CDATA[console.log("keyUp=" + thisEvent.keyCode)]]></xe:this.script>
                    </xp:eventHandler>
                    <xp:eventHandler event="onMouseDown" submit="false">
                        <xe:this.script><![CDATA[var ct = thisEvent.currentTarget;
var se = thisEvent.srcElement;
var te = thisEvent.toElement;
setTimeout(function(ct,se,te)
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";

keyboardEvent[initMethod](
                   "keyup", // event type : keydown, keyup, keypress
                    true, // bubbles
                    true, // cancelable
                    Window, // viewArg: should be window
                    false, // ctrlKeyArg
                    false, // altKeyArg
                    false, // shiftKeyArg
                    false, // metaKeyArg
                    40, // keyCodeArg : unsigned long the virtual key code, else 0
                    0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
/// Hmmmm... not working
keyboardEvent.currentTarget = ct;
keyboardEvent.srcElement = se;
keyboardEvent.toElement = te;
console.log('Fire arrow down key...');
document.dispatchEvent(keyboardEvent);
,200);
]]></xe:this.script>
                    </xp:eventHandler></xe:djFilteringSelect>

因此,任何想法都会受到赞赏 - 尤其是制造站点中的用户:-)

【问题讨论】:

是否可以为您的触摸屏用户使用不同类型的控件?我相信您会找到一款完全符合您和您的用户期望的产品 嗯.... 是的。虽然不理想,因为它们“看起来像”普通计算机。不确定我如何确定他们是否使用触摸屏 - 但也值得尝试遵循这条路线。谢谢! 你玩过 9.0.1 的 deviceBean 功能了吗?也许这可能有助于区分您的设备。此外,对于一些移动控制事件,例如“xe:singlePageApp”或“xe:appPage”,您手头还有其他有用的事件处理程序。祝你好运 嗯,这些电脑是普通电脑——只是带有触摸屏和“软键盘”。所以不是真正的 SPA(单页应用程序)的候选人。实际上,我们只需要几个字段就可以更轻松地用手指“点击”——而不是为部分用户重新设计页面;-) 【参考方案1】:

...不仅可以在用户单击 djFilteringSelect 输入字段右侧的小箭头时下拉值列表,还可以在用户仅单击该字段时。

如果我没看错您的问题,您只想在用户点击该字段时调出下拉菜单。这与您的其他代码不完全匹配,我不知道 dojo 如何解释来自 input 标记的点击事件并通过整个 dijit 工作,但我尝试添加一个事件处理程序,就像我希望用户在点击相应字段时强制触发 xe:namePicker 时使用的那样。

我在您的 xe:djFilteringSelect 中添加了以下内容,它似乎工作正常;无论如何,正如我所期待的那样。

    ....
    <xp:eventHandler
        event="onClick"
        submit="false">
        <xe:this.script><![CDATA[var el = dijit.byId("#id:Antal");
el.toggleDropDown();]]></xe:this.script>
    </xp:eventHandler>
</xe:djFilteringSelect>

[更新] 正如我们注意到的那样(在这个答案的 cmets 中),这在弹出窗口 已经 被触发之后才起作用,但不是第一次。解决方案很简单,使用 toggleDropDown() 函数代替 openDropDown()。看起来很可靠,我确认它在新页面加载后可以正常工作,正如预期的那样。与 open 函数相反,toggle 函数似乎会触发组成值列表的 DOM 元素的创建。 [/更新]

【讨论】:

感谢您的建议,埃里克。很抱歉我之前没有时间在客户的环境中对此进行测试。但是,它似乎不起作用-这可能是由于其他原因..但是我收到客户端 JS 错误:TypeError: Cannot read property 'domNode' of null - ...我检查了我得到的 id (变量 'el') 实际上不为空。这是 Dojo 代码中更深层次的东西...... 很好奇,现在这已经坐了大约一个月,我回去检查我的 XPage 我试过了,发现它有效,只是在我第一次触发用户下拉菜单之后相互作用;在此之前,它会抛出该类型错误。 是的,这是正确的——这里有同样的经历......如此接近!最后一点怎么解决? @JohnDalsgaard 使用 el.toggleDropDown() 代替 el.openDropDown()。我更新了我的答案。 宾果游戏!似乎工作。将使用“真正的”触摸屏对其进行测试。非常感谢!!!

以上是关于如何以编程方式打开 Dojo djFilteringSelect 下拉列表的主要内容,如果未能解决你的问题,请参考以下文章

dojo中以编程方式与以声明方式创建的小部件之间的区别?

Dojo 以编程方式验证 TextBox

以编程方式创建 dojo 数据网格“抱歉发生错误”

以编程方式填充组合框 dojo (1.8) 的最佳方法是啥?

dojo 增强网格过滤器 - 以编程方式设置列 A 大于某个数字

以编程方式使 dojo 数据网格单元跨越多列