ExtJs 5.1 - Ext.Panel with XML-Highlighting, editing, linenumbering capabilities

617 Views Asked by At

Basically I am i need of an Ext.Panel which contains an XML-Editor together with syntax-highlighting, line numbers and editing.

I have searched through the web and found the Javascript API CodeMirror.

I have implemented something, but the alignment of the CodeMirror-object-Textfield does not adjust itself to the Top/left of the Ext.Panel and also no line-numbers are seen:

<!DOCTYPE html>
<html>
  <head>
    <!-- ext imports -->
    <script type="text/javascript" language="javascript" src="/ext-5.1.1/build/ext-all-debug.js"></script>
    <link rel="stylesheet" type="text/css" href="/ext-5.1.1/build/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css">
    <script type="text/javascript" src="/ext-5.1.1/build/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script>

    <!-- codemirror imports -->
    <script type="text/javascript" language="javascript" src="/CodeMirror-master/lib/codemirror.js"></script>
    <link rel="stylesheet" href="/CodeMirror-master/lib/codemirror.css">
    <script type="text/javascript" src="/CodeMirror-master/mode/xml/xml.js"></script>

    <script type ="text/javascript">
        Ext.onReady(function(){
            var panel_1 = Ext.create('Ext.panel.Panel', {
                    frame:true,
                    id: 'panel_1_id',
                    title: 'panel_1',
                    padding: '10 10 10 10',
                    margin: '10 10 10 10',
                    autoScroll: true
                });

            var vp = new Ext.Viewport({
                layout: 'fit',
                items: [panel_1],
                autoScroll: true,
                renderTo : Ext.getBody()
            });

            var myCodeMirror = CodeMirror(panel_1.body, {
              value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>"
            });
        });
      </script>
    </head>
     <body>
     </body>
</html>

So the following questions arise:

1.) I thought about extending Ext.Component and somehow pack the CodeMirror object inside it? Is this possible?

2.) Is it possible to adapt my little codeexample from above to align it correctly?

2

There are 2 best solutions below

3
On BEST ANSWER

This can be solved with a few slight tweaks to your code.

The key point here is that the behaviour of CodeMirror will vary depending on the type of the first parameter you pass to the CodeMirror constructor. Passing a HTML element (as in your example) will result in the HTML DOM function appendChild() being called. And this is why there is a large space before your new element, because it is being appended after the body of the panel.

If you pass in a function (acting as a callback) to the CodeMirror constructor then you will be returned with the HTML element that is the CodeMirror. Constructing the element this way enables you to replace the body element of the panel with the new HTML element (rather than appending).

This can be achieved by creating a simple function. The code changes you require are as follows....

Create a function to pass to CodeMirror constructor

var codeMirrorCallbackFunction = function(codeMirrorEl) { 
    var panelDom = panel_1.el.dom;        
    // the node at index 1 is the body (index 0 is panel header)
    panelDom.replaceChild(codeMirrorEl, panelDom.childNodes[1]);
};

Create the CodeMirror object passing the function as 1st parameter

var myCodeMirror = CodeMirror(codeMirrorCallbackFunction, {
    value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>"
});

Update the padding of the Panel

// without this change the panel header and codemirror html overlap
padding: '25 10 10 10'
0
On

You are doing good, you only need to add a property like

var myCodeMirror = CodeMirror(panel.body, {
                           value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>",
                           lineNumbers: true
                        });