koca / vue-prism-editor

A dead simple code editor with syntax highlighting and line numbers. 3kb/gz
https://prism-editor.netlify.com
MIT License
751 stars 84 forks source link

Dynamically adjusting contents after initial load #112

Closed tansaku closed 3 years ago

tansaku commented 3 years ago

Apologies if there is an obvious answer, but is there a simple way to dynamically add/insert code into the editor after the initial loading step?

For example, say that one wanted to add a new line of code on, say, line 4 after the user had taken some action?

Many thanks in advance

rzfzr commented 3 years ago

Add a v-model="foo", foo being present in your page/components data. Then you can manipulate it however you want to, in the case of adding string would be foo+= "stuff"

tansaku commented 3 years ago

thanks @rzfzr I gave that a try but I don't see any update to the content in the editor when I submit the form

This was my code:

    <div>
      <prism-editor
        v-model="code"
        class="my-editor"
        :highlight="highlighter"
        line-numbers
      ></prism-editor>
      <div class="form">
          <form @submit.prevent="formSubmit">
              <button class="button" type="submit">Submit</button>
          </form>
      </div>
    </div>
export default {
  name: 'HomePage',

  components: {
    PrismEditor,
  },
  data: () => ({
    code: 'console.log("Hello World")\nconsole.log("Goodbye World")',
  }),
  methods: {
    highlighter(code) {
      return highlight(code, languages.js) // languages.<insert language> to return html with markup
    },
    // so we could have another method here that was called by a button that adjusted the `code` variable `code+='stuff'`
    formSubmit(e) {
      console.log(`------------------`) 
      console.log(`REQUEST TO 'formSubmit'`) 
      console.log(`e ${stringify(e)}`)
      console.log(`------------------`) 
      e.preventDefault();
      var { code } = this
      code += '\n\nhello'
      return code
    } 
  },
}

was I missing some step?

rzfzr commented 3 years ago

Really strange, your code lgtm... the only thing I do different is that 'var {code} = this', can you try this.code = 'new stuff'? For reference I'll highlight the important steps, if it still does not work tell me and I'll share my code, we'll work it out.

Inside template there is:

    <prism-editor
      class="my-editor"
      v-model="code"
      :highlight="highlighter"
      line-numbers
      style="min-height: 100vh"
    ></prism-editor>

inside export default, data is:

  data: () => ({
    code: ""})

then inside methods I have a method that manipulates that variable, I'm including my crude formatting method as example:

  formatCode() {
      let code = [];
      let level = 0;
      let tab = "    ";
      this.code.split("\n").forEach((line) => {
        if (line.includes("}")) {
          level--;
        }
        code.push(tab.repeat(level) + line);
        if (line.includes("{")) {
          level++;
        }
      });
      this.code = code.join("\n");
    },

My component declaration is the same as yours, in the highlighter I have 'languages.clike' but I don't even know if thats a proper parameter hehe. Hope it helps

rzfzr commented 3 years ago

before your line ' code += '\n\nhello'' I would try to logging 'code'(this.code) and 'this'

rzfzr commented 3 years ago

@tansaku solved?

tansaku commented 3 years ago

will double check in next 24 hours and update

tansaku commented 3 years ago
Screenshot 2021-07-01 at 09 47 28

so the code variable is definitely updated - I can't get much useful information from this as I can't stringify it and it gives me [object Object] printed raw

Aha, I think it was the:

let { code } = this

as you suggested - I changed to this and it worked:

      // let { code } = this
      console.log(`this: ${this}`)
      console.log(`code: ${stringify(this.code)}`)
      this.code += '\n\nhello'
      console.log(`code: ${stringify(this.code)}`)

thanks so much for taking the time to help :-)

rzfzr commented 3 years ago

No worries, btw, you can log an object by converting it, JSON.stringify(this), I believe console.table(this) will be a pleasant find.

tansaku commented 3 years ago

thanks, I did use JSON.stringify as I regularly do, but it would not work for the this object in this case - gives me this erros:

[Vue warn]: Property or method "toJSON" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <NuxtBuildIndicator> at .nuxt/components/nuxt-build-indicator.vue
       <Root>

but console.table(this) works great - many thanks for that! :-)