django-quill-editor icon indicating copy to clipboard operation
django-quill-editor copied to clipboard

Client side validation

Open buswedg opened this issue 2 years ago • 0 comments

I just had a play around with this in order to get client side validation working for my use case. Not sure if there is interest in a PR. But in short, I modified django_quill.js to also check the length of the text input (via their getText() method) on input change. And then compared that to minlength, maxlength and required attrs from the django formfield. Depending on the check, I'm just adding a class attribute to the parent div of the quill editor, e.g. 'ql-invalid' and then using tailwinds group inheritance to show a red border/ help text to the user.

Some sample code below.

{% load static %}
<div id="quill-container-{{ id }}" class="vLargeTextField django-quill-widget-container group">
    <div id="quill-widget-{{ id }}" class="django-quill-widget border border-1 was-validated:group-[.ql-valid]:border-green-600 was-validated:group-[.ql-invalid]:border-red-600" data-config="{{ config }}" data-type="django-quill"></div>
    <input
        id="quill-input-{{ id }}"
        name="{{ name }}"
        type="hidden"
        {% if final_attrs.minlength %}minlength="{{ final_attrs.minlength }}"{% endif %}
        {% if final_attrs.maxlength %}maxlength="{{ final_attrs.maxlength }}"{% endif %}
        {% if final_attrs.required == True %}required="required"{% endif %}>
    <p class="valid-message was-validated:group-[.ql-valid]:block absolute mt-1 hidden text-xs text-green-600">
      Looks good! </p>
    <p class="invalid-message was-validated:group-[.ql-invalid]:block absolute mt-1 hidden text-xs text-red-600">
      {{ final_attrs.help_text }} </p>
    <script>
        (function () {
            var wrapper = new QuillWrapper('quill-container-{{ id }}', 'quill-widget-{{ id }}', 'quill-input-{{ id }}', JSON.parse('{{ config|safe|escapejs }}'));
            {% if quill and quill.delta %}
                var contents = JSON.parse('{{ quill.delta|safe|escapejs }}');
                wrapper.quill.setContents(contents);
            {% elif quill and quill.html %}
                wrapper.quill.clipboard.dangerouslyPasteHTML(0, `{{ quill.html|safe }}`)
            {% elif value %}
                try {
                    var value = JSON.parse('{{ value|safe|escapejs }}');
                    wrapper.quill.setContents(JSON.parse(value['delta']));
                }
                catch (e) {
                    wrapper.quill.clipboard.dangerouslyPasteHTML(0, `{{ value|safe }}`)
                }
            {% endif %}
        })();
    </script>
</div>
function checkQuillValid(value, required, minLength, maxLength) {
  return !(
    (required && value.length === 0) ||
    (minLength && value.length < minLength) ||
    (maxLength && value.length > maxLength)
  );
}

As a side note -- the actual length of the field data going to the db will be much greater than that on the client side check. Since it includes the content of both the delta and html dict keys. So, I'm using this to help enforce some control on the client side, but the max_length parameter doesn't match that of the model field.

buswedg avatar Feb 04 '23 22:02 buswedg