This question follows a previous post on the issue.
If I correctly understood it from a previous post on the issue, it possible to execute JS script on richtext field/block as long as it isn't import content from external source, i.e. doesn't raises a security issue.
I tried to execute the following script on a richtextfield and/or richtextblock. This script runs on charblock and richtextfield, but without the richtext filter.
I feed the data through my Admin and the script fails to run. I wondered if executing JS on richtext is possible at all, and if so how should I define the settings so when it passed to Draft.JS it isn't blocked due to security considerations.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$(".show-hide-btn").click(function() {
var id = $(this).data("id");
$("#half-" + id).toggle();//hide/show..
$("#full-" + id).toggle();
})
})
</script>
{% with text=page.intro %}
{% if text|wordcount > 10 %}
<p class="half-content" id="half-{{page.id}}">{{text|richtext|truncatewords:10}}<a data-id="{{page.id}}" href="javascript:void();" class="show-hide-btn"><br>Read more</a></p>
<p class="full-content" id="full-{{page.id}}" style="display: none;">{{ text|richtext }}<a data-id="{{page.id}}" href="javascript:void();" class="show-hide-btn">Read less</a></p>
{% else %}
<p>
{{ text }}
</p>
{% endif %}
{% endwith %}
Wagtail intentionally filters out Javascript from rich text content to prevent users with limited permissions from inserting malicious code, but I don't think that's the issue here, since the Javascript code exists in the template and is being applied to a container element around the rich text content - it's not part of the rich text content itself.
I think the problem is that rich text content contains <p>
elements of its own. In HTML it's not valid to nest <p>
elements inside other <p>
elements, so when the browser encounters the first <p>
element of the rich text content, it'll treat that as closing the <p class="half-content">
element and starting a new paragraph. As a result, your Javascript code will be showing and hiding an empty element, while the actual text content exists outside of that element.
Changing the <p class="half-content">
and <p class="full-content">
elements to something like a <div>
- which can contain <p>
elements - should fix this.