Rails 7: Action Text: forward form: option to hidden input


ActionText is a power-packed tool designed to build WYSIWYG editors for our Rails applications easily. Action Text brings rich text content and editing to Rails. It includes the Trix editor that handles everything from formatting to links to quotes to lists to embedded images and galleries.

Trix’s <trix-editor> doesn’t support the form property like <textarea> or other form fields.

For example, consider the following HTML and event listener:

<form action="/articles" method="post">
  <textarea name="content"></textarea>

  <button type="submit">Save</button>
</form>

<script>
  addEventListener("keydown", ({ key, metaKey, target }) => {
    if (target.form && key == "Enter" && (metaKey || ctrlKey)) {
      form.requestSubmit()
    }
  })
</script>

Here, the target is an instance of HTMLTextAreaElement that relies on the [HTMLTextAreaElement.form][] property for access to its associated <form>(returns a reference to the parent form element).

Given the way the [form] attribute can reference a <form> element that is not an ancestor, that same event listener would continue to work with this HTML:

Declaring a [form] attribute with another <form> element’s [id] value can associate a field to a <form> that is not an ancestor. That means that the same event listener from above would continue to work with the following HTML:

<textarea name="content" form="new_article"></textarea>

<form id="new_article" action="/articles" method="post">
  <button type="submit">Save</button>
</form>

Unfortunately, if the <textarea> element were replaced with a <trix-editor>, the event listener’s reliance on accessing the form as a property would break, since the <trix-editor> custom element doesn’t declare that property.

So, how to provide property access for <trix-editor> elements, similar to how an <input> or <textarea> element can access a form outside of its direct tree of ancestors via the form="..." attribute and the corresponding .form property?

To achieve this, we can use ActionText::TagHelper#rich_text_area_tag. rich_text_area_tag returns a trix-editor tag that instantiates the Trix JavaScript editor, as well as a hidden field that Trix will write to on changes, so that the content will be sent on form submissions.

rich_text_area_tag "content", form: "other_form"
# <input type="hidden" name="content" id="trix_input_post_1" form="other_form">
# <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>

To know more about the fix, checkout this PR.

Join Our Newsletter