Add a Modal from a Redactor Field in Craft CMS
I had a client request that they be able to add a modal pop-up to content with a form from their CRM within a redactor field. There is no out of the box way to do this, but it's not difficult.
I did this by using the formattingAdd
option in the redactor Config file, using the Retcon plugin to add Alpine Js Attributes to the pop-up trigger text and a new field to hold the pop-up content.
In the redactor config file add the following to formattingAdd which will then create an a link with a class of open-popup. I wanted to use a span, however on saving the trigger text blends in with the regular text even when using the style attribute below.
"Form Pop-up": {
"title": "Form Pop-up",
"api": "module.inline.format",
"args": {
"tag": "a",
"class": "open-popup",
"type": "toggle",
"style": {
"color":"blue"
}
}
},
In order to get the trigger text to open the modal I needed to add some Alpine Js directives which I was unable to get to work with the redactor config above. Instead I used the Retcon plugin which I am already using on this site.
Additionally the rich text field and pop-up code need to be wrapped in a div with these alpine js attributes x-data="{ 'isPopupOpen': false }" @keydown.escape="isPopupOpen = false"
To get the alpine directives added use this code and replace block.copy
with the name of your redactor field.
On thing to note is that the Retcon plugin does not like the @ character which means that @click
will create errors. In this case just use the longer option in Alpine x-on:
{{ block.copy | retcon([
['attr', 'h2 + h3', { class: 'h3-big' }, false],
['attr', 'span.open-popup', { class: 'text-blueBrand-dark cursor-pointer font-bold', 'x-on:click':'isPopupOpen = true' }, false],
]) }}
Next I added a field for the pop-up content to be entered. For my client this is a form that is created in their CRM. and then place that code in the template.
{# check if popup is in use #}
{% if block.popUp is defined and block.popUp|length %}
<!-- overlay -->
<div
class="overflow-auto bg-black bg-opacity-50 h-screen w-screen top-0 left-0"
x-show="isPopupOpen"
x-cloak
:class="{ 'fixed inset-0 z-10 flex items-center justify-center': isPopupOpen }">
<!-- dialog -->
<div
class="bg-white shadow-2xl m-4 sm:m-8 p-8 pt-4 sm:w-5/6 md:w-auto md:max-w-2/3 w-full mx-4 md:mx-8 relative"
x-show="isPopupOpen"
@click.away="isPopupOpen = false"
>
<button type="button" @click="isPopupOpen = false" class="absolute top-0 right-0 mr-4 mt-4">✖</button>
<div class="w-full flex flex-row justify-center">
{#
use retcon to add an alpine directive 'x-on:click'
to close the mobile on submit
#}
{{ block.popUp|raw| retcon([
['attr', 'input[type="submit"]', { class: '', 'x-on:click': 'isPopupOpen = false' }, false]
]) }}
</div>
</div><!-- /dialog -->
</div>
<!-- end overlay -->
{% endif %}
The full code for this matrix block is in this text file.