如何在ExtJS文本区域字段中检索光标位置?

时间:2018-03-07 08:52:32

标签: extjs cursor

我在extJS窗口中定义了一个文本区域字段,如下所示:

       me.myTextArea = Ext.create({
        xtype: 'textareafield',
        width: 500,
        height: 500,
        editable: true,
        selectOnFocus: false,
        listeners: {
            afterrender: function() {
                this.focus(true);
                let cursorPos = this.getValue().length;
                this.selectText(cursorPos, cursorPos);
            }
        }
    });

我将文本区域字段添加到窗口中包含的面板,并将文本区域字段设置为焦点元素。在textarea字段被渲染之后,我阻止了那里的文本被选中。我想添加以下功能。在关闭窗口时,我将能够获得光标在文本区域字段中的位置。到目前为止,我解决问题的尝试都取得了成功。我按如下方式设置了警报:

    listeners: {
    'close': function(me) {
        alert(me.getCaretPos(cmp.myTextArea.getEl().getId()));
    }
},

现在名为" getCaretPos"旨在获取光标位置。我没有发明这个功能,但我在网上找到了。没用,函数不起作用,它总是返回-1:

    getCaretPos: function(id){
    var el = document.getElementById(id);
    var rng, ii=-1;
    if(typeof el.selectionStart=="number") {
        ii=el.selectionStart;
    } else if (document.selection && el.createTextRange){
        rng=document.selection.createRange();
        rng.collapse(true);
        rng.moveStart("character", -el.value.length);
        ii=rng.text.length;
    }
    return ii;
}

特别是,我不会丢脸,为什么" el.selectionStart"在函数中始终未定义。如果有人能帮助我解决这个谜团,我会很高兴。

2 个答案:

答案 0 :(得分:0)

这对我有用(根据您的代码)。我正在使用ExtJS 4.2。

Ext.onReady(function(){

    Ext.QuickTips.init();
    Ext.FocusManager.enable();
    Ext.Ajax.timeout = 100 * 1000;

    Ext.define('Trnd.TestWindow', {
        extend: 'Ext.window.Window',

        closeAction: 'destroy',
        border: false,
        width: 400,
        height: 500,
        modal: true,
        closable: true,
        resizable: true,
        layout: 'fit',

        getCaretPos: function() {
            var me = this;

            var el = me.myTextArea.inputEl.dom;
            if (typeof(el.selectionStart) === "number") {
                return el.selectionStart;
            } else if (document.selection && el.createTextRange){
                var range = document.selection.createRange();
                range.collapse(true);
                range.moveStart("character", -el.value.length);
                return range.text.length;
            } else {
                throw 'getCaretPosition() not supported';
            }
        },      

        initComponent: function() {
            var me = this;
            me.callParent(arguments);

            me.myTextArea = Ext.create('Ext.form.field.TextArea', {
                width: 500,
                height: 500,
                editable: true,
                selectOnFocus: false,
                listeners: {
                    afterrender: function() {
                        this.focus(true);
                        var cursorPos = this.getValue().length;
                        this.selectText(cursorPos, cursorPos);
                    }
                }
            });     

            me.panel = Ext.create('Ext.panel.Panel', {
                items: [
                    me.myTextArea
                ]
            });

            me.add(me.panel);
        },

        listeners: {
            'close': function() {
                var me = this;

                alert(me.getCaretPos());
            }   
        }       
    }); 


    var win = new Trnd.TestWindow({

    });
    win.show();

});

答案 1 :(得分:0)

在此 FIDDLE 中,我使用custometextarea创建了extend:Ext.form.field.TextArea并推出了一些自定义方法。我希望这有助于/指导您实现您的要求。

我已经检查过这段代码是在ExtJS 4.x及更高版本中运行的。

CODE SNIPPET

Ext.application({
    name: 'Fiddle',

    launch: function () {

        Ext.define('CustomeTextArea', {
            extend: 'Ext.form.field.TextArea',
            xtype: 'customtextarea',

            inputTypeSelectionSupported: /text|password|search|tel|url/i,

            selectDir: {
                b: 'backward',
                back: 'backward',
                f: 'forward'
            },

            /*
             * this event will call get the cursoe postion inside of field
             * @return {NUMBER}
             */
            getCaretPos: function () {
                var dom = this.inputEl.dom,
                    pos, selection;

                if (this.inputTypeSelectionSupported.test(dom.type)) {
                    pos = dom.selectionStart;
                    selection = (typeof pos !== 'number') && this.getTextSelection();
                    if (selection) {
                        pos = selection[0];
                    }
                } else {
                    Ext.raise('Input type of "' + dom.type + '" does not support selectionStart');
                }

                return pos;
            },

            /*
             * this event will call selectText event
             * @params {NUMBER} pos
             */
            setCaretPos: function (pos) {
                this.selectText(pos, pos);
            },

            /*
             * @params {NUMBER} start
             * @params {NUMBER} end
             * @params {STRING} direction to select it is optional
             */
            selectText: function (start, end, direction) {
                var me = this,
                    range,
                    dom = me.inputEl.dom,
                    len;

                if (dom && me.inputTypeSelectionSupported.test(dom.type)) {
                    start = start || 0;
                    len = dom.value.length;
                    if (end === undefined) {
                        end = len;
                    }
                    direction = me.selectDir[direction] || direction || 'forward';
                    if (dom.setSelectionRange) {
                        dom.setSelectionRange(start, end, direction);
                    } else if (dom.createTextRange) {
                        range = dom.createTextRange();
                        range.moveStart('character', start);
                        range.moveEnd('character', -(len - end));
                        range.select();
                    }
                } else if (!me.inputTypeSelectionSupported.test(dom.type)) {
                    Ext.raise('Input type of "' + dom.type + '" does not support setSelectionRange');
                }

                return me;
            },

            //This event will select the text inside of textfield/textarea
            getTextSelection: function () {
                var dom = this.inputEl.dom;
                if (this.inputTypeSelectionSupported.test(dom.type)) {
                    return [
                        dom.selectionStart,
                        dom.selectionEnd,
                        dom.selectionDirection
                    ];
                } else {

                    Ext.raise('Input type of "' + this.dom.type + '" does not support selectionStart, selectionEnd and selectionDirection');

                    return [];
                }
            }
        });

        Ext.create('Ext.window.Window', {
            title: 'cursor position',
            height: 200,
            width: 400,
            layout: 'fit',
            items: [{
                xtype: 'customtextarea',
                margin: 5,
                grow: true,
                name: 'message',
                fieldLabel: 'Message',
                labelAlign: 'top',
                value: 'How can I retrieve the cursor position in an ExtJS text area field?',
                anchor: '100%',
                listeners: {
                    afterrender: function (cmp) {
                        Ext.defer(function () {
                            cmp.focus(false); //if you pass true then it will automatically select text inside of field
                            let cursorPos = cmp.getValue().length;
                            cmp.selectText(0, cursorPos - 5, 'b');
                        }, 50)
                    }
                }
            }],
            listeners: {
                beforeclose: function (win) {
                    var textArea = win.down('customtextarea'),
                        pos = textArea.getCaretPos();

                    Ext.Msg.alert('Success', `This is your cursor postion <b>${pos}</b>`)
                }
            }
        }).show();
    }
});