On connect, I want to add some markup that is connected to an action within the same controller. Is this possible? How is it done?
This is what I am trying so far in my tricksmods controller:
addEmbedButton() {
const buttonHTML = '<button type="button" class="trix-button" data-trix-attribute="embed" data-action="click->tricksmods#showembed" title="Embed" tabindex="-1">Embed</button>'
this.buttonGroupBlockTools.insertAdjacentHTML("beforeend", buttonHTML)
}
showembed(){
console.log('showembed')
}
The markup is added, but the showembed action is not fired on click.
I worked this out. I needed to use the toolbarElement of the trix editor to get at my button and dialog.
import { Controller } from "@hotwired/stimulus"
import Trix from 'trix'
import Rails from "@rails/ujs"
export default class extends Controller {
static get targets() {
return [ "field" ]
}
connect() {
this.addEmbedButton()
this.addEmbedDialog()
this.eventListenerForEmbedButton()
this.eventListenerForAddEmbedButton()
}
addEmbedButton() {
const buttonHTML = '<button type="button" class="trix-button tricks-embed" data-trix-attribute="embed" data-trix-action="embed" data-action="click->tricks#showembed" title="Embed" tabindex="-1">Embed</button>'
this.buttonGroupBlockTools.insertAdjacentHTML("beforeend", buttonHTML)
}
addEmbedDialog() {
const dialogHTML = `<div class="trix-dialog trix-dialog--link" data-trix-dialog="embed" data-trix-dialog-attribute="embed" data-tricks-target="embeddialog">
<div class="trix-dialog__link-fields">
<input type="text" name="embed" class="trix-input trix-input--dialog" placeholder="Paste your URL" aria-label="embed code" required="" data-trix-input="" disabled="disabled">
<div class="trix-button-group">
<input type="button" class="trix-button trix-button--dialog" data-trix-custom="add-embed" value="Add">
</div>
</div>
</div>`
this.dialogsElement.insertAdjacentHTML("beforeend", dialogHTML)
}
showembed(e){
console.log('showembed')
const dialog = this.toolbarElement.querySelector('[data-trix-dialog="embed"]')
const embedInput = this.dialogsElement.querySelector('[name="embed"]')
if (event.target.classList.contains("trix-active")) {
event.target.classList.remove("trix-active");
dialog.classList.remove("trix-active");
delete dialog.dataset.trixActive;
embedInput.setAttribute("disabled", "disabled");
} else {
event.target.classList.add("trix-active");
dialog.classList.add("trix-active");
dialog.dataset.trixActive = "";
embedInput.removeAttribute("disabled");
embedInput.focus();
}
}
eventListenerForEmbedButton() {
this.toolbarElement.querySelector('[data-trix-action="embed"]').addEventListener("click", e => {
this.showembed(e)
})
}
eventListenerForAddEmbedButton() {
this.dialogsElement.querySelector('[data-trix-custom="add-embed"]').addEventListener("click", event => {
console.log('embeddy')
const content = this.dialogsElement.querySelector("[name='embed']").value
if (content) {
let _this = this
let formData = new FormData()
formData.append("content", content)
Rails.ajax({
type: 'PATCH',
url: '/admin/embed.json',
data: formData,
success: ({content, sgid}) => {
const attachment = new Trix.Attachment({content, sgid})
_this.element.editor.insertAttachment(attachment)
_this.element.editor.insertLineBreak()
}
})
}
})
}
//////////////// UTILS ////////////////////////////////////////////////////
get buttonGroupBlockTools() {
return this.toolbarElement.querySelector("[data-trix-button-group=block-tools]")
}
get buttonGroupTextTools() {
return this.toolbarElement.querySelector("[data-trix-button-group=text-tools]")
}
get buttonGroupFileTools(){
return this.toolbarElement.querySelector("[data-trix-button-group=file-tools]")
}
get dialogsElement() {
return this.toolbarElement.querySelector("[data-trix-dialogs]")
}
get toolbarElement() {
return this.element.toolbarElement
}
}