Интегрировать виртуальную клавиатуру в форму extjs 4.2

Я добавляю виртуальную клавиатуру с 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());
            }
        }]
    });
});

person Gonfi den Tschal    schedule 11.06.2013    source источник


Ответы (2)


  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/

person Sami Racho    schedule 22.08.2013
comment
к сожалению, форматирование кода и маркеры не очень хорошо сочетаются друг с другом: коду нужно 8 пробелов (вместо 4 обычно), и ctrl-K не помогает ;-) - person kleopatra; 22.08.2013
comment
Спасибо, это был мой первый пост. - person Sami Racho; 22.08.2013
comment
пожалуйста :-) Просто проверьте мое редактирование, я не слишком хорошо знаком с javascript, поэтому мог ошибиться при форматировании - person kleopatra; 22.08.2013
comment
Это все еще выглядит как взлом для меня. Почему бы просто не привязать событие к самому элементу DOM? - person jacoviza; 19.03.2015

  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. (ответил уже Сэми Ранчо)

    fieldStyle: 'margin-right:-40px',
    
  3. Опять же, избегайте таймеров и всего подобного. Просто добавьте это:

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

Найдите обновленную скрипту здесь: http://jsfiddle.net/g5VN8/11/

person jacoviza    schedule 19.03.2015