0

I'm trying to implement some maxlength function on SCEditor, which doesn't take into account original textarea maxlength attribute.

By then I'm using the SelectionchangedEvent handler, to get value and substring it if necessary, and replacing it with val() from SCEditor API.

That works so far but the val() function will set value and place caret at the beginning, so if user continues writing it will write at top then substring the bottom, and set back caret on top, one line above previous one. I don't want that !

So I came across solutions like : stackoverflow

That doesn't seem to work unfornatunately : jsfiddle

var instance = $('textarea').sceditor({
    plugins: 'bbcode',
    width: '100%',
    style: 'http://www.sceditor.com/minified/jquery.sceditor.default.min.css'
}).sceditor('instance');

$('#caretend').click(function() {
    placeCaretAtEnd(instance);
});

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el.getBody().get(0));
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el.getBody().get(0));
        textRange.collapse(false);
        textRange.select();
    }
}
<link href="http://www.sceditor.com/minified/jquery.sceditor.default.min.css" rel="stylesheet"/>

<div><a href="#" id="caretend">Place caret at end</a></div>
<div><textarea></textarea></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.sceditor.com/minified/jquery.sceditor.bbcode.min.js"></script>

Am i missing something right here ? Or is it just this plugin in conflict with the function ?

And finally, I also found some interesting post here : stackoverflow but I don't see how to use in it in the intended way.

Any advice very welcome, thanks a lot in advance.

William
  • 11
  • 2

1 Answers1

1

Well, finally found how to, hoping this could help someone in the future !

Here is my solution, on how to limit input length on SCEditor

Create a flag array that will be used to detect changes on contenteditable, I found that more effective and cross browser compatible that common handlers.

var sceFlag = { "id1" : 0, "id2" : 0 (...) };

Function to placeCaretAtEnd :

function placeCaretAtEnd(instance){
    var rangeHelper = instance.getRangeHelper();
    var range = rangeHelper.cloneSelected();
    if ('selectNodeContents' in range) {
      var bodyChildren = instance.getBody()[0].children;
       range.selectNodeContents(bodyChildren[bodyChildren.length - 1]);
      range.collapse(false);
      rangeHelper.selectRange(range);
    }

Function to substring value if above max length :

function SCElength(instance,len){
  var d = len - instance.val().length;
  if(d<0){
  instance.val(instance.val().substr(0,len));
  placeCaretAtEnd(instance);
}

Function to listen to focus and blur events and check if contenteditable has changed :

function SCEFocusBlur(instance,len,id){
instance.getBody()
    .focus(function() {
        sceFlag[id] = 1;
        checkSCEInput(instance,len,id);
        $(this).data("initialText", $(this).html());
    });
instance.getBody()
    .blur(function() {
        sceFlag[id] = 0;
        if ($(this).data("initialText") !== $(this).html()) {
            checkSCEInput(instance,len,id);
        }
    });

Function to check value recursively while flag is 1

function checkSCEInput(instance,len,id){
if(sceFlag[id] = 1){
    SCElength(instance,len);
    setTimeout(function() {
        checkSCEInput(instance,len);
    }, 1000);
}

Then all you have to do is create the sceditor like this :

$("textarea").sceditor({
        plugins: "bbcode",
        style: "css/sceditor.min.css",
        width: "auto",
        height: "110",
        toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|size,color,removeformat|bulletlist,orderedlist,horizontalrule,emoticon",
    });

And call SCEFocusBlur with the instance, the maxlength int and the id associated to the flag :

SCEFocusBlur($("textarea").sceditor('instance'),maxlength,id);

Any thoughts on it very welcome ! Have a good day :)

William
  • 11
  • 2