1

I am developing a web application using Vuejs/Nuxtjs within that I have some textarea which is controlled by CodeMirror for beautification purposes. The problem I am facing is that when the content of the CodeMirror changes then it is not reflected on the CodeMirror textarea unless I click on it or if I use the JSON.parse while setting the value in Watch. If I click on it then it reflects the changes and everything is correctly working.

Following is the textarea which is governed by CodeMirror:

<textarea
    ref="input"
    :value="$store.state.modules.MyModules.input"
    class="form-control"
    placeholder="Input"
    spellcheck="false"
    data-gramm="false"
/>

Following is the code sample where I am loading the contents to CodeMirror if the values changes using the Vuejs Watch function:

data () {
    return {
        inputEditor: null
    }
},
watch: {
    '$store.state.modules.MyModules.input' (value) {
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(value)
        }
    }
},

mounted () {
    this.inputEditor = CodeMirror.fromTextArea(this.$refs.testInput, {
        mode: "applicaton/ld+json",
        beautify: { initialBeautify: true, autoBeautify: true },
        lineNumbers: true,
        indentWithTabs: true,
        autofocus: true,
        tabSize: 2,
        gutters: ["CodeMirror-lint-markers"],
        autoCloseBrackets: true,
        autoCloseTags: true,
        styleActiveLine: true,
        styleActiveSelected: true,
        autoRefresh: true,
    });

    // On change of  input call the function
    this.inputEditor.on("change", this.createTestData);

    // Set the height for the input CodeMirror
    this.inputEditor.setSize(null, "75vh");

    // Add the border for all the CodeMirror textarea
    for (const s of document.getElementsByClassName("CodeMirror")) {
        s.style.border = "1px solid black";
    }
  }

I found issues similar to this and tried the following things but still no luck:

  1. Trying to refresh the contents within the watch method:

watch: {
    '$store.state.modules.MyModules.input' (value) {
        const vm = this
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(value)
            setTimeout(function () {
                vm.inputEditor.refresh()
            }, 1)
        }
    }
},
  1. Trying to use the autorefresh within my CodeMirror but that also did not work.

What worked for me is that when setting the value I need to use the JSON.parse within the watch method. If I do that then It's working correctly but I do not want to do that:

watch: {
    '$store.state.modules.MyModules.input' (value) {
        const vm = this
        if (value !== this.inputEditor.getValue()) {
            this.inputEditor.setValue(JSON.parse(value))
        }
    }
},

Can someone please inform me why the CodeMirror data will not be updated if I do not do JSON.parse?

BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98

2 Answers2

0

Chain this to the master codemirror object, make sure nothing else is chained:

.on('change', editor => {
   globalContent = editor.getValue();
});;
dizad87
  • 448
  • 4
  • 15
  • Thanks a lot for the response. Can you please let me know what is `globalContent` here? Because I am unable to get it and its not working. Thanks in advance. – BATMAN_2008 Apr 04 '22 at 06:57
  • I have observed that the value for the `editor` is set when I do the `this.inputEditor.setValue(value)` within my `Vuejs Watch` but it's not reflected in the front-end. I need to somehow refresh the `CodeMirror` to ensure its being displayed on the front-end. But the `this.inputEditor.refresh() & this.inputEditor.save()` is not working for me either. Can you please provide some suggestion? – BATMAN_2008 Apr 04 '22 at 08:35
  • globalContent is essentially a global variable on your Vue component, for some reason my codeMirror variable is not, but chaining an onchange event was the only way I could fetch the value of my editor. Let me know if you are still unable to get it to work. – dizad87 Apr 05 '22 at 04:41
0

Providing the answer as it can be helpful to someone else in the future:

Actually the vm.inputEditor.refresh() will work only problem was that I was using it with setTimeout 0.001s which is way to quick for to refresh.

After trying a lot I found my stupid mistake. I tried to change it to 1000 or 500 and it works now.

Following is the change:

setTimeout(function () {
 vm.inputEditor.refresh()
}, 1000)
BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98