【问题标题】:Integrate virtual keyboard into extjs 4.2 form将虚拟键盘集成到 extjs 4.2 表单中
【发布时间】:2013-06-11 15:15:06
【问题描述】:

我正在将http://www.greywyvern.com/code/javascript/keyboard 中的虚拟键盘添加到 extjs 4.2 表单的文本字段中。

它基本上可以工作,见这里:http://jsfiddle.net/g5VN8/1/

1) 我的第一个问题是:这真的是连接它们的最佳方式吗?用计时器而不是事件来保持 extjs 值是最新的,对我来说看起来很丑。

另外我无法克服以下两个问题:

2) 键盘图标换行。它应该位于字段的末尾,在右侧,就像这里的示例一样:http://www.greywyvern.com/code/javascript/keyboard

3) 字段焦点不起作用。我有它在一个节目听众。即使包装在 window.setTimeout() 中,它也不起作用,因此这不是时间问题。不会抛出任何错误。

这是一个复制粘贴(stackoverflow 的规则)。我会及时更新这两个地方。

Ext.onReady(function() {    
    Ext.QuickTips.init();

    var formPanel = Ext.create('Ext.form.Panel', {
        renderTo: Ext.getBody(),
        bodyStyle: 'padding: 5px 5px 0 5px;',
        defaults: {
            anchor: '100%',
         },
        items: [{
            xtype:'textfield',
            name: 'string',
            fieldLabel: 'String',
            maxLength:30, enforceMaxLength:true,
            allowBlank: false,
            listeners: {
                show: function(field) {
                    //focus the field when the window shows
                    field.focus(true, 1000); //TODO: doesn't work, no error
                },
                afterrender:function(cmp){
                    cmp.inputEl.set({ //see http://jsfiddle.net/4TSDu/19/
                        autocomplete:'on'
                    });

                    //attach the keyboard
                    //because it modifies the dom directly we need to hack it to 
                    //inform extjs (really, ext has no such listener option?)
                    var interval = window.setInterval(function() {
                        try {
                            var newValue = cmp.inputEl.dom.value;
                            var oldValue = cmp.getValue();
                            if (newValue != oldValue) {
                                //only do it then, cause it also moves the cursor 
                                //to the end and that sucks.
                                cmp.setValue( newValue );
                            }
                        } catch (e) {
                            //form was removed
                            window.clearInterval(interval);
                        }
                    }, 100);
                    // see http://www.greywyvern.com/code/javascript/keyboard
                    VKI_attach(cmp.inputEl.dom); 
                }
            }
        }],
        buttons: [{
            text: 'Alert string',
            handler: function() {
                var stringField = this.up('form').getForm().findField('string');
                alert(stringField.getValue());
            }
        }]
    });
});

【问题讨论】:

    标签: javascript extjs4.2


    【解决方案1】:
    1. 您可以将侦听器附加到键盘,当用户单击 VKI 键时,您会触发文本字段更改事件。

      Ext.getBody().on({
      mousedown: function (ev) {
          if (ev.target.tagName === 'TD') {
              // We trigger change event only on textfield with the focus
              if (document.activeElement) {
                  if (document.activeElement.id === cmp.inputEl.dom.id) cmp.fireEvent('change');
              }
          }
      }, 
      delegate: '#keyboardInputMaster'
      });
      
    2. 这是因为 ExtJS 4 使用“style=width:100%”写入输入字段。 一种简单的方法是在文本字段中添加负边距

      fieldStyle: 'margin-right:-40px'

    3. 奇怪的 ExtJS 行为。您必须关注输入元素,而不是文本字段组件

      Ext.defer(function () {
          cmp.inputEl.dom.focus();
      }, 100);
      

    您可以在此处查看整个解决方案:http://jsfiddle.net/EGbLn/3/

    【讨论】:

    • 不幸的是,代码格式和项目符号不能很好地相互配合:代码需要 8 个空格(通常是 4 个),而 ctrl-K 没有帮助 ;-)
    • 谢谢,这是我的第一篇文章。
    • 不客气 :-) 请检查我的编辑,我对 javascript 不太熟悉,所以格式化时可能出错
    • 这对我来说仍然像是一个 hack。为什么不简单地将事件附加到 DOM 元素本身?
    【解决方案2】:
    1. 避免使用计时器。请改用常规的 dom 事件侦听器。

      afterrender: function (cmp) {
          ...
      
          // simply attach this to the change event from dom element
          cmp.inputEl.dom.addEventListener('change', function(){
              cmp.setValue(this.value);
          });
      
          ...
      }
      
    2. (已由 Samy Rancho 回答)

      fieldStyle: 'margin-right:-40px',
      
    3. 再次,避免使用计时器和类似的东西。只需添加以下内容:

      afterrender: function (cmp) {
          ...
      
          //focus on field
          cmp.inputEl.dom.focus();
      
          ...
      }
      

    在此处查找更新的小提琴:http://jsfiddle.net/g5VN8/11/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-18
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 2015-01-02
      • 2013-04-02
      • 1970-01-01
      相关资源
      最近更新 更多