CodeMirror keeps appending when language dropdown is selected

陌路散爱 提交于 2019-12-25 08:58:14

问题


I am using CodeMirror to provie syntax highlighting for a little project to save programming departments code bits. The asp-mvc page consists of a textxt, a dropdown list for languages, a textbox for a description and a textbox for code. when the user makes his/her first selection from the dropdown, a nice Codemirror editor is created. If they were to make change the language selection, a NEW CodeMirror box is created and pre-pended above the first box. this goes on each time a selection is made, causing the boxes to stack and become confusing. I would like a single Codemirror editor at all times. If they were to type in text, for instance, then decide to choose languages, the text should just be copied over to a new CodeMirror editor. Here is a description of how to do this in the manual:

In cases where you don't want to append the editor to an element, and need more control over the way it is inserted, the first argument to the CodeMirror function can also be a function that, when given a DOM element, inserts it into the document somewhere. This could be used to, for example, replace a textarea with a real editor:

var myCodeMirror = CodeMirror(function(elt) {
myTextArea.parentNode.replaceChild(elt, myTextArea); }, {value: myTextArea.value}); However, for this use case, which is a common way to use CodeMirror, the library provides a much more powerful shortcut:

var myCodeMirror = CodeMirror.fromTextArea(myTextArea); This will, among other things, ensure that the textarea's value is updated with the editor's contents when the form (if it is part of a form) is submitted.

as you will see in my code, I am using the second method, but to no avail. Heres the markup and JavaScript:

@using (Html.BeginForm("Save", "Home", FormMethod.Post, new {id="CodeBlock"}))
{
    @Html.TextBoxFor(m => m.Title, new { type = "Search", autofocus = "true", id = "title", placeholder = "Code snip Title", style = "width: 200px", @maxlength = "50" })
    @Html.DropDownList("Language",
    new SelectList(Enum.GetValues(typeof(LangType))),
    "Select Language", new {id="codeDDl", @onchange = "changeSyntax()" })
    <p></p>
    @Html.TextAreaFor(m => m.Description, new { type = "Search", autofocus = "true", id = "description", placeholder = "Code snip Description",style = "Width: 800px" })
    <p></p>
    <div id="CodeArea">
        @Html.TextAreaFor(m => m.Code, new {id = "code", style = "width: 800px"})
    </div>
    <p></p>


    <input type="submit" value="Submit" />
    <input type="button" value="Reset" onclick="Reset()"/>




}
<script>
    var cm;
    function changeSyntax() {
        switch (document.getElementById("codeDDl").selectedIndex) {

        case 1:                 
            BuildBox(true, true, "text/x-csharp");  
            break;
        case 2:
            BuildBox(true, true, "text/x-css");
            break;
        case 3:
            BuildBox(true, true, "text/x-chtml");
            break;
        case 4:
            BuildBox(true, true, "text/x-javascript");
            break;
        case 5:
            BuildBox(true, true, "text/x-perl");
            break;
        case 6:
            BuildBox(true, true, "text/x-php");
            break;
        case 7:
            BuildBox(true, true, "text/x-python");
            break;
        case 8:
            BuildBox(true, true, "text/x-ruby");
            break;
        case 9:
            BuildBox(true, true, "text/x-sql");
            break;
        case 10:
            BuildBox(true, true, "text/x-vb");
            break;
        case 11:
            BuildBox(true, true, "text/x-xml");
            break;
        }
    }

    function BuildBox(lines, match, mode) {

        cm = CodeMirror.fromTextArea(document.getElementById("code"),
        {
            lineNumbers: lines,
            matchBrackets: match,
            mode: mode
        });


    }

    function Reset() {
        cm.toTextArea();
        document.getElementById("code").value = "";
        document.getElementById("codeDDl").disabled = false;
        document.getElementById("codeDDl").selectedIndex = 0;
    }

The model is simple and can be derived from the Razor controls, controller does nothing special at this time. Any ideas out there on how I can accomplish having a single CodeMirror Editor appear no matter how many time the language selection box is changed?


回答1:


You only need to call fromTextArea ONCE ever (per text area).

So create it, store it off, and use it if you need to change anything later.

var cmInstance = $('#code').data('CodeMirrorInstance');

if (!cmInstance)
{
    cmInstance = CodeMirror.fromTextArea(document.getElementById("code"),
    {
        lineNumbers: lines,
        matchBrackets: match,
        mode: mode
    });
    $('#code').data('CodeMirrorInstance', cmInstance);
}



//later
var cm = $('#code').data('CodeMirrorInstance');
cm.whateverYouWantToDoToCodeMirror();


来源:https://stackoverflow.com/questions/39167641/codemirror-keeps-appending-when-language-dropdown-is-selected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!