Tiptap: [HELP] How to give each node unique id?

Created on 3 Apr 2019  路  1Comment  路  Source: ueberdosis/tiptap

I want to iterate over nodes, so I can sync them to a database, so I need to give each nodes a unique id.
This is my progress so far.

TodoItem.js (tiptap extension)

import { Node } from 'tiptap'
import { splitToDefaultListItem, liftListItem } from 'tiptap-commands'
import TodoItemComponent from './TodoItemComponent'
import uuid from 'uuid'

export default class TodoItem extends Node {

  get name() {
    return 'todo_item'
  }

  get view() {
    return TodoItemComponent
  }

  get schema() {
    return {
      attrs: {
        blockId: {
          default: uuid.v4() // *problem* it keeps the same value on all created node
        },
        done: {
          default: false
        },
      },
      draggable: true,
      content: 'paragraph',
      toDOM: node => {
        const { blockId, done } = node.attrs

        return [
          'li',
          { 
            'data-type': this.name,
            'data-done': done.toString(),
            'data-block-id': blockId
          },
          ['span', { class: 'todo-checkbox', contenteditable: 'false' }],
          ['div', { class: 'todo-content' }, 0],
          ['div', { class: 'todo-actions', contenteditable: 'false' }],
        ]
      },
      parseDOM: [{
        priority: 51,
        tag: `[data-type="${this.name}"]`,
        getAttrs: dom => ({
          blockId: dom.getAttribute('data-block-id') || uuid.v4(), // this works on loading editor content
          done: dom.getAttribute('data-done') === 'true',
        }),
      }],
    }
  }

}

TodoItemComponent.vue

<template>
  <li class="todo"
    :data-block-id="node.attrs.blockId"
    :data-type="node.type.name"
    :data-done="node.attrs.done.toString()"
  >
    <span class="todo-checkbox" contenteditable="false" @click="onChange"></span>
    <div class="todo-content" ref="content" :contenteditable="editable.toString()"></div>
  </li>
</template>

<script>
export default {
  props: ['node', 'updateAttrs', 'editable', 'view', 'getPos'],
  methods: {
    onChange() {
      this.updateAttrs({
        done: !this.node.attrs.done,
      })
    },
  },
}
</script>

Problem:

BlockId attrs is same between different node.

Expected:

BlockId attrs should be unique

Most helpful comment

Adding Plugin to the node resolve my problem

default node attrs for blockId changed to null

 get plugins() {
    return [
      new Plugin({
        appendTransaction: (transactions, oldState, newState) => {
          const newTr = newState.tr
          let modified = false

          newState.doc.descendants((node, pos) => {
            if (!!node.type && (node.type.name === 'todo_item')) {
              const { blockId, ...rest} = node.attrs
              if (blockId === undefined || blockId === null || blockId === '') {
                // Adds a unique id to a node
                newTr.setNodeMarkup(pos, undefined, { blockId: uuid.v4(), ...rest })
                modified = true
              }
            }
          })

          if (modified) {
            return newTr
          }
        }
      })
    ]
  }

This plugin is useful for anyone need to add some attributes to new nodes

>All comments

Adding Plugin to the node resolve my problem

default node attrs for blockId changed to null

 get plugins() {
    return [
      new Plugin({
        appendTransaction: (transactions, oldState, newState) => {
          const newTr = newState.tr
          let modified = false

          newState.doc.descendants((node, pos) => {
            if (!!node.type && (node.type.name === 'todo_item')) {
              const { blockId, ...rest} = node.attrs
              if (blockId === undefined || blockId === null || blockId === '') {
                // Adds a unique id to a node
                newTr.setNodeMarkup(pos, undefined, { blockId: uuid.v4(), ...rest })
                modified = true
              }
            }
          })

          if (modified) {
            return newTr
          }
        }
      })
    ]
  }

This plugin is useful for anyone need to add some attributes to new nodes

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chrisjbrown picture chrisjbrown  路  3Comments

santicros picture santicros  路  3Comments

leandromatos picture leandromatos  路  4Comments

agentq15 picture agentq15  路  3Comments

git-mischa picture git-mischa  路  3Comments