Search code examples
javascripthtmlcodemirror

Need help figuring out why I can't get the content of a certain textarea element with Javascript for my code playground


I'm building a code playground using Code Mirror. My issue is that I'm not able to get the content from the textarea elements I have for html, css, and js. I created a textarea aside from those textarea elements to see if my code for getting the content from a textarea had issues. So in my html, of course I have the textarea tags. I gave this new textarea a class name "txtb" and I created a link with an onclick attribute for a function called "AlertContent()". Here is the javascript for the function:

function AlertContent(){

alert(document.getElementsByClassName('txtb')[0].value);  

}

and guess what, it works. When I type into the textarea element that has the class "txtb", and click the link which calls the function AlertContent() I created, I see a message box appear displaying the text I typed into that textarea. It works. However, when I try to give classes to the textarea elements I'm using with Code Mirror, and use the same function to get the value or content from those textarea elements, I end up getting a blank message box even though there's text (html, css, js) in those textarea elements. All I want to do, is create a function that will get the content of the textarea elements (html, css, js) so then I can save it to my database. I would really appreciate the help. Here's the code I'm using for Code Mirror.

<!-- Code Editors -->
<section id="code_editors">
<div id="html" class="code_box">
<h3>HTML</h3>
<form><textarea class="MyHtml" name="htmlcode"></textarea></form>
</div>
<div id="css" class="code_box">
<h3>CSS</h3>
<textarea class="MyCss" name="css"></textarea>
</div>
<div id="js" class="code_box">
<h3>JavaScript</h3>
<textarea class="MyJs" name="js"></textarea>
</div>
</section>
</div>
<script src="http://codemirror.net/lib/codemirror.js"></script>
<!-- For HTML/XML -->
<script src="http://codemirror.net/mode/xml/xml.js"></script>
<script src="http://codemirror.net/mode/htmlmixed/htmlmixed.js"></script>
<!-- For CSS -->
<script src="http://codemirror.net/mode/css/css.js"></script>
<!-- For JS -->
<script src="http://codemirror.net/mode/javascript/javascript.js"></script>
</div> 
</div> 

<script>    
(function() {

// Base template
var base_tpl =
"<!doctype html>\n" +
"<html>\n\t" +
"<head>\n\t\t" +
"<meta charset=\"utf-8\">\n\t\t" +
"<title>Test</title>\n\n\t\t\n\t" +
"</head>\n\t" +
"<body>\n\t\n\t" +
"</body>\n" +
"</html>";

 var prepareSource = function() {
 var html = html_editor.getValue(),
 css = css_editor.getValue(),
 js = js_editor.getValue(),
 src = '';
 // HTML
 src = base_tpl.replace('</body>', html + '</body>');

 // CSS
 css = '<style>' + css + '</style>';
 src = src.replace('</head>', css + '</head>');
 // Javascript
 js = '<script>' + js + '<\/script>';
 src = src.replace('</body>', js + '</body>');
 return src;
 };
 var render = function() {
 var source = prepareSource();
 var iframe = document.querySelector('#output iframe'),
 iframe_doc = iframe.contentDocument;
 iframe_doc.open();
 iframe_doc.write(source);
 iframe_doc.close();
 };
 // EDITORS
 // CM OPTIONS
 var cm_opt = {
 mode: 'text/html',
 gutter: true,
 lineNumbers: true,
 };
 // HTML EDITOR
 var html_box = document.querySelector('#html textarea');
 var html_editor = CodeMirror.fromTextArea(html_box, cm_opt);

 html_editor.on('change', function (inst, changes) {
 render();
 });

 // CSS EDITOR
 cm_opt.mode = 'css';
 var css_box = document.querySelector('#css textarea');
 var css_editor = CodeMirror.fromTextArea(css_box, cm_opt);

 css_editor.on('change', function (inst, changes) {
 render();
 });

 // JAVASCRIPT EDITOR
 cm_opt.mode = 'javascript';
 var js_box = document.querySelector('#js textarea');
 var js_editor = CodeMirror.fromTextArea(js_box, cm_opt);

 js_editor.on('change', function (inst, changes) {
 render();
 });

 // SETTING CODE EDITORS INITIAL CONTENT
 html_editor.setValue('<p>Empty Room</p>');
 css_editor.setValue('body { color: gray; }');
 // RENDER CALL ON PAGE LOAD
 // NOT NEEDED ANYMORE, SINCE WE RELY
 // ON CODEMIRROR'S onChange OPTION THAT GETS
 // TRIGGERED ON setValue
 // render();
 // NOT SO IMPORTANT - IF YOU NEED TO DO THIS
 // THEN THIS SHOULD GO TO CSS
 /*
 Fixing the Height of CodeMirror.
 You might want to do this in CSS instead
 of JS and override the styles from the main
 codemirror.css
*/
 var cms = document.querySelectorAll('.CodeMirror');
 for (var i = 0; i < cms.length; i++) {
 cms[i].style.position = 'absolute';
 cms[i].style.top = '30px';
 cms[i].style.bottom = '0';
 cms[i].style.left = '0';
 cms[i].style.right = '0';
 cms[i].style.height = '100%';
 }
 /*cms = document.querySelectorAll('.CodeMirror-scroll');
 for (i = 0; i < cms.length; i++) {
 cms[i].style.height = '100%';
 }*/
 }());
 // Basically adding to the CM Options
 cm_opt['extraKeys'] = {
 Tab: function(instance) {
 if (inst.somethingSelected())
 CodeMirror.commands.indentMore(inst);
 else
 CodeMirror.commands.insertTab(inst);
 }
 }
 </script>

Solution

  • Why don't you use the get_value() that is provided on the editors? For example, html_editor.getValue()

    Here is an example page doing just that to alert what you write in the CodeMirror textarea when you click the respective editor's button.

    <!DOCTYPE html>
    <html>
    <head>
        <title>CodeMirror</title>
        <link rel="stylesheet" href="http://codemirror.net/lib/codemirror.css">
    </head>
    <body>
        <!-- Code Editors -->
        <section id="code_editors">
            <div id="html" class="code_box">
                <h3>HTML</h3>
                <form><textarea class="MyHtml" name="htmlcode"></textarea></form>
                <button onclick="viewHTML()">Alert this HTML</button>
            </div>
            <div id="css" class="code_box">
                <h3>CSS</h3>
                <textarea class="MyCss" name="css"></textarea>
                <button onclick="viewCSS()">Alert this CSS</button>
            </div>
            <div id="js" class="code_box">
                <h3>JavaScript</h3>
                <textarea class="MyJs" name="js"></textarea>
                <button onclick="viewJS()">Alert this JS</button>
            </div>
        </section>
    
        <div id="output">
            <iframe></iframe>
        </div>
    
        <script src="http://codemirror.net/lib/codemirror.js"></script>
        <!-- For HTML/XML -->
        <script src="http://codemirror.net/mode/xml/xml.js"></script>
        <script src="http://codemirror.net/mode/htmlmixed/htmlmixed.js"></script>
        <!-- For CSS -->
        <script src="http://codemirror.net/mode/css/css.js"></script>
        <!-- For JS -->
        <script src="http://codemirror.net/mode/javascript/javascript.js"></script>
    
        <script>    
        (function() {
            // Base template
            var base_tpl =
            "<!doctype html>\n" +
            "<html>\n\t" +
            "<head>\n\t\t" +
            "<meta charset=\"utf-8\">\n\t\t" +
            "<title>Test</title>\n\n\t\t\n\t" +
            "</head>\n\t" +
            "<body>\n\t\n\t" +
            "</body>\n" +
            "</html>";
    
            window.viewHTML = function() {
                alert(html_editor.getValue());
            }
    
            window.viewCSS = function() {
                alert(css_editor.getValue());
            }
    
            window.viewJS = function() {
                alert(js_editor.getValue());
            }
    
            var prepareSource = function() {
                var html = html_editor.getValue(),
                    css = css_editor.getValue(),
                    js = js_editor.getValue(),
                    src = '';
    
                // HTML
                src = base_tpl.replace('</body>', html + '</body>');
    
                // CSS
                css = '<style>' + css + '</style>';
                src = src.replace('</head>', css + '</head>');
    
                // Javascript
                js = '<script>' + js + '<\/script>';
                src = src.replace('</body>', js + '</body>');
    
                return src;
            };
    
            var render = function() {
                var source = prepareSource();
                var iframe = document.querySelector('#output iframe'),
                iframe_doc = iframe.contentDocument;
    
                iframe_doc.open();
                iframe_doc.write(source);
                iframe_doc.close();
            };
    
            // EDITORS
            // CM OPTIONS
            var cm_opt = {
                mode: 'text/html',
                gutter: true,
                lineNumbers: true,
            };
    
            // HTML EDITOR
            var html_box = document.querySelector('#html textarea');
            var html_editor = CodeMirror.fromTextArea(html_box, cm_opt);
    
            html_editor.on('change', function (inst, changes) {
                render();
            });
    
            // CSS EDITOR
            cm_opt.mode = 'css';
            var css_box = document.querySelector('#css textarea');
            var css_editor = CodeMirror.fromTextArea(css_box, cm_opt);
    
            css_editor.on('change', function (inst, changes) {
                render();
            });
    
            // JAVASCRIPT EDITOR
            cm_opt.mode = 'javascript';
            var js_box = document.querySelector('#js textarea');
            var js_editor = CodeMirror.fromTextArea(js_box, cm_opt);
    
            js_editor.on('change', function (inst, changes) {
                render();
            });
    
            // SETTING CODE EDITORS INITIAL CONTENT
            html_editor.setValue('<p>Empty Room</p>');
            css_editor.setValue('body { color: gray; }');
            js_editor.setValue('var x = \'10\';');
            // RENDER CALL ON PAGE LOAD
            // NOT NEEDED ANYMORE, SINCE WE RELY
            // ON CODEMIRROR'S onChange OPTION THAT GETS
            // TRIGGERED ON setValue
            // render();
            // NOT SO IMPORTANT - IF YOU NEED TO DO THIS
            // THEN THIS SHOULD GO TO CSS
            /*
            Fixing the Height of CodeMirror.
            You might want to do this in CSS instead
            of JS and override the styles from the main
            codemirror.css
            */
            /*
            var cms = document.querySelectorAll('.CodeMirror');
            for (var i = 0; i < cms.length; i++) {
                cms[i].style.position = 'absolute';
                cms[i].style.top = '30px';
                cms[i].style.bottom = '0';
                cms[i].style.left = '0';
                cms[i].style.right = '0';
                cms[i].style.height = '100%';
            }
            */
            /*cms = document.querySelectorAll('.CodeMirror-scroll');
            for (i = 0; i < cms.length; i++) {
                cms[i].style.height = '100%';
            }*/
    
            // Basically adding to the CM Options
            cm_opt['extraKeys'] = {
                Tab: function(instance) {
                if (inst.somethingSelected())
                    CodeMirror.commands.indentMore(inst);
                else
                    CodeMirror.commands.insertTab(inst);
                }
            }
        }());
    
        </script>
    </body>
    </html>