Search code examples
javascriptjqueryextjsextjs4.2html-editor

selectText in extjs html editor 4.2.1


I have created a sencha fiddle which explains my requirement. Below is the link to the fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2m3c

My requirement is to select a particular text (??) in extjs HTML Editor when I click the "F2 Editor" button in the toolbar. I was able to achieve this with textarea when I click "F2 textarea" button. I want the same in html editor. I know the method "selectText(start, end)" is not available in the extjs docs of html editor. Is there any other way to achieve this using jquery or any other piece of code.

You can edit my fiddle else create a new fiddle to help me achieve this.


Solution

  • Html editor in ExtJS creates iframe element. You can find the body element of iframe and select text within it using native events available on window.

    Here is how you can achieve selection inside iframe with your example:

    Ext.application({
        name: 'Fiddle',
    
        launch: function () {
            $.fn.selectRange = function (start, end) {
                if (end === undefined) {
                    end = start;
                }
                return this.each(function () {
                    if ('selectionStart' in this) {
                        this.selectionStart = start;
                        this.selectionEnd = end;
                    } else if (this.setSelectionRange) {
                        this.setSelectionRange(start, end);
                    } else if (this.createTextRange) {
                        var range = this.createTextRange();
                        range.collapse(true);
                        range.moveEnd('character', end);
                        range.moveStart('character', start);
                        range.select();
                    }
                });
            };
    
            Ext.tip.QuickTipManager.init(); // enable tooltips
    
            Ext.form.HtmlEditor.override({
                frame: true,
                initComponent: function () {
                    this.callOverridden();
                    this.addEvents('submit');
                },
    
                initEditor: function () {
                    this.callOverridden();
    
                    var me = this;
                    var doc = me.getDoc();
    
                    if (Ext.isGecko) {
                        Ext.EventManager.on(doc, 'keypress', me.fireSpecialKey, me);
                    }
    
                    if (Ext.isIE || Ext.isWebKit || Ext.isOpera) {
                        Ext.EventManager.on(doc, 'keydown', me.fireSpecialKey, me);
                    }
                },
    
                fireSpecialKey: function (e) {
                    if (e.getKey() == e.F2) {
                        var myVal = this.getValue();
                        if (myVal.indexOf('??') != -1) {
                            debugger;
                            //alert('found');
                            //$('#htmlEditorF2-inputCmp-textareaEl').selectRange(myVal.indexOf('??'), (myVal.indexOf('??')+2));
                            //$('#htmlEditorF2-inputCmp-iframeEl').contents().select();
                            this.selectText(myVal.indexOf('??'), (myVal.indexOf('??') + 2))
                        }
                    }
                },
    
                /*
                selectText : function(start, end){
                    var me = this,
                        v = me.getValue(),
                        doFocus = true,
                        el = me.inputEl.dom,
                        undef,
                        range;
                    debugger;
                    if (v.length > 0) {
                        start = start === undef ? 0 : start;
                        end = end === undef ? v.length : end;
                        if (el.setSelectionRange) {
                            el.setSelectionRange(start, end);
                        }
                        else if(el.createTextRange) {
                            range = el.createTextRange();
                            range.moveStart('character', start);
                            range.moveEnd('character', end - v.length);
                            range.select();
                        }
                        doFocus = Ext.isGecko || Ext.isOpera;
                    }
                    if (doFocus) {
                        me.focus();
                    }
                }
                */
            });
    
            new Ext.panel.Panel({
                title: 'HTML Editor',
                renderTo: Ext.getBody(),
                width: 550,
                height: 500,
                frame: true,
                layout: 'vbox',
                items: [{
                    xtype: 'htmleditor',
                    id: 'htmlEditorF2',
                    enableColors: false,
                    enableAlignments: false,
                    width: '100%',
                    value: 'This patient ??, gender ??, aged ?? has come here for ?? and he has been suggested to take up ?? skin test. Upon testing and verifying his lab results it was found he is allergic to ??.'
                }, {
                    xtype: 'textareafield',
                    id: 'txtareaF2',
                    grow: true,
                    width: '100%',
                    height: 200,
                    name: 'message',
                    fieldLabel: 'Message',
                    anchor: '100%',
                    value: 'This patient ??, gender ??, aged ?? has come here for ?? and he has been suggested to take up ?? skin test. Upon testing and verifying his lab results it was found he is allergic to ??.'
                }],
                tbar: [{
                    xtype: 'button',
                    text: 'F2 Editor',
                    handler: function () {
                        var iframewindow = Ext.getCmp('htmlEditorF2').iframeEl.el.dom.contentWindow;
                        var iframebody = Ext.getCmp('htmlEditorF2').iframeEl.el.dom.contentDocument.querySelector('body');
    
                        function selectTextRange(obj, start, stop) {
                            var endNode, startNode = endNode = obj.firstChild
    
                            startNode.nodeValue = startNode.nodeValue.trim();
    
                            var range = document.createRange();
                            range.setStart(startNode, start);
                            range.setEnd(endNode, stop + 1);
    
                            var sel = iframewindow.getSelection();
                            sel.removeAllRanges();
                            sel.addRange(range);
                        }
    
                        var myVal = iframebody.innerText;
                        var start = myVal.indexOf('??');
                        var end = myVal.indexOf('??') + 2;
    
                        selectTextRange(iframebody, start, end);
                    }
                }, '-', {
                    xtype: 'button',
                    text: 'F2 Textarea',
                    handler: function () {
                        debugger;
                        var myVal = Ext.getCmp('txtareaF2').getValue();
                        Ext.getCmp('txtareaF2').selectText(myVal.indexOf('??'), (myVal.indexOf('??') + 2));
                        Ext.getCmp('txtareaF2').focus();
                    }
                }]
            });
        }
    });
    

    Here is link to working Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2m3l