Im using tinyMCe
for my project.Everything is working fine but now i want to restrict the number of character that will be insert into tinyMce
text
The solution below works good for me:
1 - in the html code of the textarea it is necessary to include the value of maxlength and id of textarea.
2 - in script part, code below. If you want, uncomment the alert() line, and put your message.
<script type="text/javascript">
tinymce.init ({
...
...
setup: function(ed) {
var maxlength = parseInt($("#" + (ed.id)).attr("maxlength"));
var count = 0;
ed.on("keydown", function(e) {
count++;
if (count > maxlength) {
// alert("You have reached the character limit");
e.stopPropagation();
return false;
}
});
},
<textarea type="text" id="test" name="test" maxlength="10"></textarea>
There is no tinymce configuration setting max_chars
, except you implement it yourself:
tinyMCE.init({
...
max_chars : "10",
setup : function(ed) {
ed.onKeyDown.add(function(ed, evt) {
if ( $(ed.getBody()).text().length > ed.getParam('max_char')){
e.preventDefault();
e.stopPropagation();
return false;
}
});
}
});
This is the solution that worked for me.
I basically took the code provided by @needfulthing and fixed the errors and improved it.
function initTinymce(){
tinymce.init({
selector: '.richtext-editable',
plugins: ['paste'],
max_chars: 50000, // max. allowed chars
setup: function (ed) {
var allowedKeys = [8, 13, 16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 46];
ed.on('keydown', function (e) {
if (allowedKeys.indexOf(e.keyCode) != -1) return true;
if (tinymce_getContentLength() + 1 > this.settings.max_chars) {
e.preventDefault();
e.stopPropagation();
return false;
}
return true;
});
ed.on('keyup', function (e) {
tinymce_updateCharCounter(this, tinymce_getContentLength());
});
},
init_instance_callback: function () { // initialize counter div
$('#' + this.id).prev().append('<div class="char_count" style="text-align:right"></div>');
tinymce_updateCharCounter(this, tinymce_getContentLength());
},
paste_preprocess: function (plugin, args) {
var editor = tinymce.get(tinymce.activeEditor.id);
var len = editor.contentDocument.body.innerText.length;
if (len + args.content.length > editor.settings.max_chars) {
alert('Pasting this exceeds the maximum allowed number of ' + editor.settings.max_chars + ' characters for the input.');
args.content = '';
}
tinymce_updateCharCounter(editor, len + args.content.length);
}
});
function tinymce_updateCharCounter(el, len) {
$('#' + el.id).prev().find('.char_count').text(len + '/' + el.settings.max_chars);
}
function tinymce_getContentLength() {
return tinymce.get(tinymce.activeEditor.id).contentDocument.body.innerText.length;
}
}
Just to improve a little bit the good example given by Vladimir Miroshnichenko, to get a more accurate count, mainly for languages with accented characters.
I also inlcude the Javascript SpellChecker as the tinyMCE's one (4.1) cannot be used anymore. So the ed.addButton() will include a button in the toolbar to call $Spelling.SpellCheckInWindow('editors'). That perfectly works with tinyMCE 4.1.7.
I also added a count of words, if you prefer to trig the alarm on word instead of characters.
<textarea id="paragraph1" name="description_edit"><?=htmlspecialchars($this->company->description);?></textarea>
<div><span>Characters left:</span> <span id="chars_left"></span></div>
<script type="text/javascript" src="tinymce/tinymce.min.js"></script>
<script type="text/javascript" src="JavaScriptSpellCheck/include.js"></script>
<script>
var max_chars = 300; //max characters
var max_for_html = 1000; //max characters for html tags
var allowed_keys = [8, 13, 16, 17, 18, 20, 33, 34, 35,36, 37, 38, 39, 40, 46];
var chars_without_html = 0;
function alarmChars(){
if(chars_without_html > (max_chars - 25)){
$('#chars_left').css('color','red');
}else{
$('#chars_left').css('color','gray');
}
}
$(function() {
tinymce.init({
selector: "textarea#paragraph1",
theme: "modern",
plugins: [
"advlist autolink lists charmap preview hr anchor pagebreak",
"visualblocks visualchars insertdatetime nonbreaking",
"directionality paste textcolor"
],
menubar:false,
statusbar:false,
toolbar: "bold italic underline | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist | charmap | preview | Spellcheck",
setup : function(ed) {
ed.addButton('Spellcheck', {
title : 'Spellcheck',
image : '/img/dict.png',
onclick : function() {
// Add you own code to execute something on click
$Spelling.SpellCheckInWindow('editors');
}
});
ed.on("KeyDown", function(ed,evt) {
whtml = tinyMCE.activeEditor.getContent();
without_html = whtml.replace(/(<([^>]+)>)/ig,"");
without_html = without_html.replace(/&([A-za- z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);/ig,'$1');
without_html = without_html.replace(/…/ig,'...');
without_html = without_html.replace(/’/ig,'\'');
without_html = $.trim(without_html.replace(/&([A-za-z]{2})(?:lig);/ig,'$1'));
chars_without_html = without_html.length;
chars_with_html = whtml.length;
wordscount = without_html.split(/[ ]+/).length; // Just to get the wordcount, in case...
var key = ed.keyCode;
$('#chars_left').html(max_chars - chars_without_html);
if(allowed_keys.indexOf(key) != -1){
alarmChars();
return;
}
if (chars_with_html > (max_chars + max_for_html)){
ed.stopPropagation();
ed.preventDefault();
}else if (chars_without_html > max_chars-1 && key != 8 && key != 46){
alert('Characters limit!');
ed.stopPropagation();
ed.preventDefault();
}
alarmChars();
}
);
},
});
whtml = $("#paragraph1").text();
without_html = whtml.replace(/(<([^>]+)>)/ig,"");
without_html = without_html.replace(/&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);/ig,'$1');
without_html = without_html.replace(/…/ig,'...');
without_html = without_html.replace(/’/ig,'\'');
without_html = $.trim(without_html.replace(/&([A-za-z]{2})(?:lig);/ig,'$1'));
chars_without_html = without_html.length;
$('#chars_left').html(max_chars - chars_without_html);
alarmChars();
});
I hope it will help as tinyMCE team seems to be a bit stubborn on this subject...