We have an in-house developed file/image/document manager plugin for TinyMCE that is still being ported over to jQuery. In the mean time, some of our projects that rely on having these features need to use the Prototype-based version of TinyMCE & jQuery.noConflict(). This works fine however with unobtrusive validation in ASP.NET MVC 3 the validation on submit happens before the TinyMCE callback to copy the TinyMCE'ed contents to the form field is triggered. Is it possible to hook into a pre-validation event in the unobtrusive validation?
问题:
回答1:
If you are using submit buttons to post the form, try this:
$("input[type='submit']").click(function () {
tinyMCE.triggerSave();
});
If you're not using submit buttons, just hook into whatever event happens immediately before form submission and call tinyMCE.triggerSave().
回答2:
Another way to go about this which gives you more control is in the TinyMCE initialization. This works well except for one case: the last TinyMCE instance you exit does not trigger the onDeactivate event within TinyMCE (it is only trigger when you go to another TinyMCE instance). So here is a way to work around this -- so far it seems to work well but YMMV.
Note: I would use this in conjunction with the accepted answer. This code triggers the validation as content is being edited in TinyMCE.
tinyMCE.init({
...
setup: ValidationTinyMceSetup
});
And our setup method:
function ValidationTinyMceSetup(editor) {
var $textarea = $('#' + editor.editorId);
// method to use to save editor contents to backend input field (TinyMCE hides real input and syncs it up
// with values on form submit) -- we need to sync up the hidden input fields and call the valid()
// method from jQuery unobtrusive validation if it is present
function save(editor) {
if (editor.isDirty) {
editor.save();
var $input = $('#' + editor.editorId);
if (typeof $input.valid === 'function')
$input.valid();
}
}
// Save tinyMCE contents to input field on key/up down (efficiently so IE-old friendly)
var typingTimerDown, typingTimerUp;
var triggerDownSaveInterval = 1000; // time in ms
var triggerUpSaveInterval = 500; // time in ms
editor.onKeyDown.add(function (editor) {
clearTimeout(typingTimerDown);
typingTimerDown = setTimeout(function () { save(editor) }, triggerDownSaveInterval);
});
editor.onKeyUp.add(function () {
clearTimeout(typingTimerUp);
typingTimerUp = setTimeout(function () { save(editor) }, triggerUpSaveInterval);
});
// Save tinyMCE contents to input field on deactivate (when focus leaves editor)
// this is via TAB
editor.onKeyDown.add(function (editor, event) {
if (event.keyCode === 9)
save(editor);
});
// this is when focus goes from one editor to another (however the last one never
// triggers -- need to enter another TinyMCE for event to trigger!)
editor.onDeactivate.add(function (editor) {
save(editor);
});
}
Finally, a bonus item that is completely unrelated: you can add a character counter by including this function in your JavaScript source:
function CharacterCountDisplay(current, max) {
if (current <= max) {
return current + ' of ' + max + ' characters max';
}
else {
return '<span style="color: red;">' + current + '</span> of ' + max + ' characters';
}
}
And in the above ValidationTinyMceSetup
method add:
// check for character count data-val
var character_max = $textarea.attr('data-val-lengthignoretags-max');
if (typeof character_max === 'undefined' || character_max === false) {
character_max = $textarea.attr('data-val-length-max');
}
if (typeof character_max !== 'undefined' && character_max !== false) {
var character_count = function (editor) {
var currentLength = $(editor.getDoc().body).text().length;
editor.dom.setHTML(tinymce.DOM.get(editor.id + '_path_row'), CharacterCountDisplay(currentLength, character_max));
};
// on load show character count
editor.onInit.add(character_count);
// while typing update character count
editor.onKeyUp.add(character_count);
}
To use simply add a data-val-length-max="250"
to your textarea tag or whatever it is you're using TinyMCE on!