DEV Community

Arnaud Joubay
Arnaud Joubay

Posted on • Originally published at paraside.in on

Auto-linking URLs with Trix Editor and StimulusJS

The https://trix-editor.org is fantastic, but there's one simple thing I expected to be built-in that isn't: copy/pasting a URL should create a link automatically instead of inserting the link as plain text.

Thinking of it, it's not so surprising because there are many things one could want to do instead, like embedding a video or a tweet. But it's a common request, and the GitHub issue includes a solution with jQuery that I used to build my Stimulus controller.

So, without further ado, here's a simple 2 steps rails tutorial to add URL auto-linking to your forms.

The controller

Create a /app/javascript/controller/trix_paste_controller.js file and copy/paste the code below.

import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    document.addEventListener("paste", this.pasteHandler.bind(this));
  }

  disconnect() {
    document.removeEventListener("paste", this.pasteHandler.bind(this))
  }

  pasteHandler(event) {
    const pastedText = event.clipboardData?.getData?.("Text")
    if (!!pastedText && !!pastedText.match(/^(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})$/ig)) {
      this.pasteUrl(pastedText)
    }
  }

  pasteUrl(pastedText) {
    const editor = this.element.editor
    let currentText = editor.getDocument().toString()
    let currentSelection = editor.getSelectedRange()
    let textWeAreInterestedIn = currentText.substring(0, currentSelection[0])
    let startOfPastedText = textWeAreInterestedIn.lastIndexOf(pastedText)
    editor.recordUndoEntry("Auto Link Paste")
    editor.setSelectedRange([startOfPastedText, currentSelection[0]])
    editor.activateAttribute('href', pastedText)
    editor.setSelectedRange(currentSelection)
  }
}

Enter fullscreen mode Exit fullscreen mode

Your forms

And now, anytime you want need this auto-linking feature, just reference the controller like so:

= f.rich_text_area :content, data: { controller: "trix-paste" }

Enter fullscreen mode Exit fullscreen mode

That's it, and it's "trix-paste" and not "trix-autolink" because I have further plans for this controller.


That's it! Follow me here or @sowenjub on twitter for more

Oldest comments (1)

Collapse
 
emilianolch profile image
Emiliano López

Thanks for this post.

I made a little change to your code. Instead of adding and removing the event listeners in the javascript code, you can put data: { action: 'paste->trix-paste#pasteHandler' } into rich_text_area options.