AngularJS + TinyMCE: ng-maxlength does not work on <textarea>

I want to limit the maximum length of the text so that it does not exceed the length of the column in the database. I put this restriction on the backend, and now I want to use it in the interface.

I am using TinyMCE v4.3.3 with the angular -ui-tinymce v0.0.12 plugin and AngularJS v1.4.6.

JS:

var tinymceOpts = { toolbar: false, menubar: false, // do not add <p></p> from the start: forced_root_block: '' } 

HTML:

 <textarea ui-tinymce="tinymceOpts" ng-model="body" name="body" ng-maxlength="100" required> {{ body }} </textarea> <span ng-show="form.body.$error.maxlength" class="error"> Reached limit! </span> 

As you can see, I use the ng-maxlength attribute to limit the length of <textarea> .

Expected result: the input is confirmed, and the error message is displayed only if the length of the content (with the included tags) has exceeded the limit (in this case, 100 characters).

Actual result:
Screenshot

The input state of the form is set to invalid when the input contains some text (regardless of length).


The number of characters (in the lower right corner) is calculated for testing:

 this.getCharCount = function() { var tx = editor.getContent({format: 'raw'}); return tx.length; }; 
+6
source share
3 answers

The problem is that TinyMCE uses its own <iframe> to edit text content and writes it back to your <textarea> for special events. No wonder ng-maglength doesn't work here.

To achieve what you want, you will need to check the contents of the editor itself and prohibit entering more characters in case you reach the maximum length.

+1
source

I managed to get it to work! It was necessary to disable SCE in AngularJS mode:

 angular.module('myApp', ['ui.tinymce']) .config(['$sceProvider', function($sceProvider) { $sceProvider.enabled(false); }]) .controller('myCtrl', ['$scope', function($scope) { // ... }]); 

jsFiddle

! Beware of security vulnerabilities!

Strict Context Shielding ( SCE ) is a mode in which AngularJS requires binding in certain contexts to obtain a value that is marked as safe for use in this context. With SCE disabled, AngularJS can display arbitrary HTML in a <div> , and rendering of user-managed inputs creates security vulnerabilities.

0
source

I believe that you really want the TinyMCE directive to calculate the "length" of visible characters, as opposed to counting characters in <textarea> . TinyMCE is about to embed its own iFrame on the page, and the editor is part of this iFrame - it's not <textarea> .

When you put a check on <textarea> , you are asking Angular to count the characters in <textarea> ... this will be a problem for you. The problem is that standard directives just count characters, so a simple (empty) HTML sample is:

<p></p>

It will really count as 7 characters if there is really no β€œvisible” content. I built a custom directive for another editor, and as a result, I used the jQuery .text() function against HTML. This removes all HTML tags and provides an approximate number of actual text characters in the editor. This is part of the code in the directive:

 var jStrippedString = jQuery(modelValue).text().trim(); return (maxlength < 0) || ngModelCtrl.$isEmpty(jStrippedString) || (jStrippedString.length <= maxlength); 

I believe that you need to create a custom Attribute directive that will allow you to capture model data for the editor and perform this check yourself, rather than just counting the characters in <textarea> .

0
source

All Articles