Ionaru / easy-markdown-editor

EasyMDE: A simple, beautiful, and embeddable JavaScript Markdown editor. Delightful editing for beginners and experts alike. Features built-in autosaving and spell checking.
https://stackblitz.com/edit/easymde
MIT License
2.39k stars 316 forks source link

Support minlength & required HTML validations #105

Open thesecretmaster opened 5 years ago

thesecretmaster commented 5 years ago

Is your feature request related to a problem? Please describe. I use HTML5 based validations whenever possible, because my site needs to support noscript users, but I like to improve the experience for users who do enable javascript. As part of that, I added easymde to the project for use in all of our markdown text editors. This was mostly great until I realized that my client side validations suddenly stopped working for my javascript enabled users, resulting in lost work when they attempted to submit work that didn't pass validations (since easymde ignores HTML5 validations), so it was sent to the server then rejected (and they were redirected back to the editor page, which no longer contained their content).

Describe the solution you'd like There are two possible solutions to this problem: 1) easymde can check for the html attributes minlength and required when an editor is created, then show a warning when focus leaves the editor or 2) easymde can find it's parent form and add a submit listener, which will stop the form from submitting and show an error message if the validations don't pass.

Describe alternatives you've considered I considered moving back to straight textareas, but I'd like to avoid that if possible. The only other alternative I can think of is writing a wrapper myself that listens to form submits, finds all the easymde children of the form, gets their values, and runs the validations. However, I'm not sure how simple this would be with codemirror.

Ionaru commented 5 years ago

A temporary workaround is enabling autosaving. This should prevent your users from losing their work. After a successful submit, you can clear the autosaved data.

In the meantime I will look into form validation for the editor. (PRs are welcome too 😉)

thesecretmaster commented 5 years ago

My JS isn't great, but I think it'd look something like this:


function on_initialization() {
        const editor = the_original_textarea;
        const cm = the_codemirror_instance;
        if (editor.hasAttribute('minlength')) {
          validations['minlength'] = editor.getAttribute('minlength');
        }
        if (editor.hasAttribute('maxlength')) {
          validations['maxlength'] = editor.getAttribute('maxlength');
        }
        if (editor.hasAttribute('required')) {
          validations['required'] = true;
        }
        // This is needed because otherwise the form won't submit, because the original textarea seems empty
        editor.removeAttribute('required');
        editor.removeAttribute('minlength');
        editor.removeAttribute('maxlength');
        editor.form.addEventListener('submit', function(e) {
          const char_count = cm.getValue().length;
          const minlength_passed = !validations.hasOwnProperty('minlength') || (char_count != 0 && char_count > validations.minlength);
          const maxlength_passed = !validations.hasOwnProperty('maxlength') || char_count < validations.maxlength;
          const required_passed = !validations.hasOwnProperty('required') || char_count > 0;
          if (!(minlength_passed && maxlength_passed && required_passed)) {
            alert("HTML5 Validations Failed"); // or some other way to show the error
            e.preventDefault();
          }
        })
}
NicoHood commented 3 years ago

@thesecretmaster Is there a way to patch this externally without recompiling easy-markdown? I am not a javascript expert (yet).

I'd also like to see this feature, together with https://github.com/Ionaru/easy-markdown-editor/issues/125

terfex commented 3 years ago

My JS isn't great, but I think it'd look something like this:

function on_initialization() {
        const editor = the_original_textarea;
        const cm = the_codemirror_instance;
        if (editor.hasAttribute('minlength')) {
          validations['minlength'] = editor.getAttribute('minlength');
        }
        if (editor.hasAttribute('maxlength')) {
          validations['maxlength'] = editor.getAttribute('maxlength');
        }
        if (editor.hasAttribute('required')) {
          validations['required'] = true;
        }
        // This is needed because otherwise the form won't submit, because the original textarea seems empty
        editor.removeAttribute('required');
        editor.removeAttribute('minlength');
        editor.removeAttribute('maxlength');
        editor.form.addEventListener('submit', function(e) {
          const char_count = cm.getValue().length;
          const minlength_passed = !validations.hasOwnProperty('minlength') || (char_count != 0 && char_count > validations.minlength);
          const maxlength_passed = !validations.hasOwnProperty('maxlength') || char_count < validations.maxlength;
          const required_passed = !validations.hasOwnProperty('required') || char_count > 0;
          if (!(minlength_passed && maxlength_passed && required_passed)) {
            alert("HTML5 Validations Failed"); // or some other way to show the error
            e.preventDefault();
          }
        })
}

@thesecretmaster have you had a chance to test this by any chance? If not, I'll try to test this but looks promising. Although I find it odd to see such a feature missing.