Tiptap: insert html content at the current position

Created on 13 Jul 2019  路  10Comments  路  Source: ueberdosis/tiptap

Hi, thank you for this great project.
I was looking for a way to insert HTML string at the current position and get it parsed automatically like when you paste the content into the editor.

currently I'm using editor.commands and custom methods like this:
js insertLinkWithText({ href }, text) { const mark = this.editor.schema.marks.link.create({ href }) const from = this.editor.state.selection.from const transaction = this.editor.state.tr.insertText(text + ' ') transaction.addMark(from, from + text.length, mark) this.editor.view.dispatch(transaction) }
I also tried setContent with no luck

feature request

Most helpful comment

This will be in core for tiptap v2. For now here are the basics for it:

import { DOMParser } from 'prosemirror-model'

function elementFromString(value) {
  const element = document.createElement('div')
  element.innerHTML = value.trim()

  return element
}

function insertHTML({ state, view }, value) {
  const { selection } = state
  const element = elementFromString(value)
  const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
  const transaction = state.tr.insert(selection.anchor, slice.content)

  view.dispatch(transaction)
}

use it:

insertHTML(editor, '<div>hey</div>')

All 10 comments

Is there any reason why you aren't using the Link() extension in tiptap-extensions? You'll have a much easier time with this use case. Here is the example documentation: https://github.com/scrumpy/tiptap/tree/master/examples/Components/Routes/Links

@ryanbliss thanks for your reply, how would I insert link with href + text at the current position? also I need a way to insert unknown HTML string (not just links) something like programmatically pasting content at the cursor position

@reza-akbari I would make a custom NodeView if you are going to do that, but I imagine that use case is going to be really challenging to support. The links with text would be pretty easy just by slightly modifying the Link() node that Tiptap supports out of the box, but any generic HTML isn't really a good idea (inline vs. block, being an easy example that comes to mind).

There really isn't way to insertHTML at current position like insertText:

const transaction = this.editor.state.tr.insertText(body);
this.editor.view.dispatch(transaction);

?

This will be in core for tiptap v2. For now here are the basics for it:

import { DOMParser } from 'prosemirror-model'

function elementFromString(value) {
  const element = document.createElement('div')
  element.innerHTML = value.trim()

  return element
}

function insertHTML({ state, view }, value) {
  const { selection } = state
  const element = elementFromString(value)
  const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
  const transaction = state.tr.insert(selection.anchor, slice.content)

  view.dispatch(transaction)
}

use it:

insertHTML(editor, '<div>hey</div>')

Thanks a lot!

Works like a charm, but it adds an empty paragraph when I use it like this:

insertHTML(editor, '<p>Hello there</p>');

insertHTML(editor, "") is error

Did this ever get added?

We started to actively work on tiptap 2 in August and yes, we added insertHTML to it. :) That said, it鈥檒l take some time until we release tiptap 2.

If you want to know more, subscribe to #547 鉁岋笍

Really excellent :-) This insertHtml.js extension seems to work for me:

import { Node } from 'tiptap'

import { DOMParser } from 'prosemirror-model'

export default class Generic extends Node {
  get name () {
    return 'html'
  }

  get schema () {
    return {
      inline: false,
      attrs: {},
      group: 'block',
      draggable: true,
      parseDOM: []
    }
  }

  commands ({ type }) {
    return {
      insertHTML: value =>
        (state, dispatch) => {
          const { selection } = state
          const element = document.createElement('div')
          element.innerHTML = value.trim()
          const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
          const transaction = state.tr.insert(selection.anchor, slice.content)
          dispatch(transaction)
        }
    }
  }
}

And to use it:

 this.editor.commands.insertHTML('<p>Hello <b>you</b> there </p>')
Was this page helpful?
0 / 5 - 0 ratings

Related issues

git-mischa picture git-mischa  路  3Comments

Auxxxxlx picture Auxxxxlx  路  3Comments

chrisjbrown picture chrisjbrown  路  3Comments

unikitty37 picture unikitty37  路  3Comments

jetacpp picture jetacpp  路  3Comments