6

Default CodeMirror HTML Editor with Preview - http://jsfiddle.net/D9MvH/1/ - http://liveweave.com/zSqCfA

Load File in CodeMirror with FileReader API - http://liveweave.com/VvsXN9

Here's a very simple example of what I'm trying to do. (Save function don't work on these online editors, but the import file function works on this simple editor) - http://liveweave.com/MrUBfZ

My problem is when I click my input file form to browse for a file. I choose the HTML document to be opened and it won't open with/in CodeMirror. I tried everything of my knowledge and can't get it to work. Can anyone help with this?

HTML:

<input type="file" onchange="loadfile(this)">

JavaScript:

var delay;

// Initialize CodeMirror editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
    mode: 'text/html',
    tabMode: 'indent',
    lineNumbers: true,
    lineWrapping: true,
    autoCloseTags: true
});

// Live preview
editor.on("change", function() {
    clearTimeout(delay);
    delay = setTimeout(updatePreview, 300);
});

function updatePreview() {
    var previewFrame = document.getElementById('preview');
    var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
    preview.open();
    preview.write(editor.getValue());
    preview.close();
}
setTimeout(updatePreview, 300);

function saveTextAsFile() {
    var textToWrite = document.getElementById("code").value;
    var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
    var fileNameToSaveAs = "myfile.html";

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }

    downloadLink.click();}

function destroyClickedElement(event) {
    document.body.removeChild(event.target);}

function loadfile(input){
    var reader = new FileReader()
    reader.onload = function(e) {
        editor.setValue = e.target.result;}
    reader.readAsText(input.files[0]);}

    var input = document.getElementById("select");

    function selectTheme() {
      var theme = input.options[input.selectedIndex].innerHTML;
      editor.setOption("theme", theme);
    }

    var choice = document.location.search &&
               decodeURIComponent(document.location.search.slice(1));
    if (choice) {
      input.value = choice;
      editor.setOption("theme", choice);
    }

Full Code

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: HTML5 preview</title>
<script src='http://codemirror.net/lib/codemirror.js'></script>
<script src='http://codemirror.net/mode/xml/xml.js'></script>
<script src='http://codemirror.net/mode/javascript/javascript.js'></script>
<script src='http://codemirror.net/mode/css/css.js'></script>
<script src='http://codemirror.net/mode/htmlmixed/htmlmixed.js'></script>
<link rel='stylesheet' href='http://codemirror.net/lib/codemirror.css'>
<link rel='stylesheet' href='http://codemirror.net/doc/docs.css'>
<style type='text/css'>
.CodeMirror {
    float: left;
    width: 50%;
    border: 1px solid black;}

iframe {
    width: 49%;
    float: left;
    height: 300px;
    border: 1px solid black;
    border-left: 0px;}
</style>
</head>
<body>
    <textarea id="code" name="code"><!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>HTML5 canvas demo</title>
<style>p {font-family: monospace;}</style>
</head>
<body>
    <p>Canvas pane goes here:</p>
    <canvas id=pane width=300 height=200></canvas>

    <script>
      var canvas = document.getElementById('pane');
      var context = canvas.getContext('2d');

      context.fillStyle = 'rgb(250,0,0)';
      context.fillRect(10, 10, 55, 50);

      context.fillStyle = 'rgba(0, 0, 250, 0.5)';
      context.fillRect(30, 30, 55, 50);
    </script>
</body>
</html></textarea>

    <iframe id="preview"></iframe>

    <input type="file" onchange="loadfile(this)">
    <a href="#my-header" onclick='saveTextAsFile()'>Save/Download</a>

<script>
var delay;

// Initialize CodeMirror editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
    mode: 'text/html',
    tabMode: 'indent',
    lineNumbers: true,
    lineWrapping: true,
    autoCloseTags: true
});

// Live preview
editor.on("change", function() {
    clearTimeout(delay);
    delay = setTimeout(updatePreview, 300);
});

function updatePreview() {
    var previewFrame = document.getElementById('preview');
    var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
    preview.open();
    preview.write(editor.getValue());
    preview.close();
}
setTimeout(updatePreview, 300);

function saveTextAsFile() {
    var textToWrite = document.getElementById("code").value;
    var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
    var fileNameToSaveAs = "myfile.html";

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }

    downloadLink.click();}

function destroyClickedElement(event) {
    document.body.removeChild(event.target);}

function loadfile(input){
    var reader = new FileReader();
    reader.onload = function(e) {
        document.getElementById('code').value = e.target.result;}
    reader.readAsText(input.files[0]);}

    var input = document.getElementById("select");

    function selectTheme() {
      var theme = input.options[input.selectedIndex].innerHTML;
      editor.setOption("theme", theme);
    }

    var choice = document.location.search &&
               decodeURIComponent(document.location.search.slice(1));
    if (choice) {
      input.value = choice;
      editor.setOption("theme", choice);
    }
</script>
</body>
</html>
Michael Schwartz
  • 8,153
  • 14
  • 81
  • 144
  • TL;DR, please state your issue clearly, what is the problem you're having? – Eliran Malka Jul 15 '13 at 08:05
  • The question has been updated. A solution to this would be really helpful. – Michael Schwartz Jul 22 '13 at 18:50
  • are there any errors on the console? please be more specific – Eliran Malka Jul 22 '13 at 19:15
  • Nothing is showing up in the console on Firebug. CodeMirror isn't reading/showing the value imported into the textarea, but it works without CodeMirror, just by itself. – Michael Schwartz Jul 22 '13 at 19:31
  • please create a live demo illustrating this, as it's quite hard to know what's going on, without some more information (I've [tried](http://jsfiddle.net/D9MvH/), believe me). you can do so on [jsFiddle](http://jsfiddle.net/). – Eliran Malka Jul 22 '13 at 19:58
  • I updated with links (live demos as you requested) and added the complete code for what I'm trying to do. – Michael Schwartz Jul 28 '13 at 18:24
  • *"My problem is when I click my input file ... it won't open with/in CodeMirror"* - it seems to be working just fine in the demo you provided (http://liveweave.com/MrUBfZ). what is the problem, than? – Eliran Malka Jul 28 '13 at 19:39
  • That's the same problem that occurred with me. I'm trying to get it to open within CodeMirror. – Michael Schwartz Jul 28 '13 at 23:11
  • ok, and I'm saying that **it's working fine**, an uploaded file is loaded into CodeMirror as expected. – Eliran Malka Jul 30 '13 at 18:07
  • http://liveweave.com/MrUBfZ is a simple editor I made, not CodeMirror. I added a link to the editor with CodeMirror using the same load file function as before but it's not working. I get no errors with FireBug, or in the terminal on Ubuntu. Here's the link - http://liveweave.com/VvsXN9 – Michael Schwartz Jul 30 '13 at 20:57
  • alright, i get it now, see my answer on how to fix that. – Eliran Malka Jul 30 '13 at 23:38

2 Answers2

6

You're simply misusing CodeMirror; when the file content is loaded into the reader, instead of assigning a value to the textarea element, e.g.:

reader.onload = function(e) {
    document.getElementById('code').value = e.target.result;
}

… use the CodeMirror API and insert content via the editor instance setValue() method, like so:

reader.onload = function(e) {
    editor.setValue(e.target.result);
}

See the CodeMirror docs for doc.setValue(content: string), and here's the updated, working demo illustrating this.

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
  • 5
    oh, and please, stop using *liveweave*, [we](http://jsfiddle.net/) [have](http://plnkr.co/) [better](http://codepen.io/pen/) [tools](http://jsbin.com/) [around](http://tinkerbin.com/), [and](https://shiftedit.net/) [plenty](https://c9.io/) [of them](http://coderun.com/ide/) – Eliran Malka Jul 30 '13 at 23:52
  • 1
    ok, i take my first comment back - liveweave has gotten much better :) – Eliran Malka Apr 20 '15 at 09:15
0

Here is sample example.

<script src="codemirror/lib/codemirror.js"></script>
<link rel="stylesheet" href="codemirror/lib/codemirror.css"/>
<script src="codemirror/mode/clike/clike1.js"></script>
<script src="codemirror/mode/javascript/javascript.js"></script>

<div id="editor"> </div>
<div>
    <input type="file" onchange="localLoad(this.files);" />
</div>

<script>
   var myCodeMirror = CodeMirror(
   document.getElementById('editor'), {
      lineNumbers: true
   });

   function localLoad(files) {
       if (files.length == 1) {
            document.title = escape(files[0].name);
            var reader = new FileReader();
            reader.onload = function(e) {
              myCodeMirror.setValue(e.target.result);
            };
            reader.readAsText(files[0]);
         }
    }
</script>

The above one is done for div. If you wanted for textarea, change it like:

<textarea id="editor" name="field1"></textarea>

 <script>
 var myCodeMirror = CodeMirror.fromTextArea
  document.getElementById('editor'),{
  lineNumbers: true
   });
   myCodeMirror.setSize(null, 600);
 </script>
Ratnesh
  • 1,554
  • 3
  • 12
  • 28