最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to restrict number of characters per line in textarea? - Stack Overflow

programmeradmin2浏览0评论

I have one Ext JS TextArea. There I want to restrict my characters to 15 characters in each line and total number of lines should be not more than 10.

What I am tring to do here is

function(){
    var myValue = this.getValue();
    var myValueData = myValue.split(/\r*\n/);
    myValueData.length = 10;    
}

Ideally it should ommit all the lines after line number 10, but is not happening. Also how to restrict only upto 15 characters per line?

I have one Ext JS TextArea. There I want to restrict my characters to 15 characters in each line and total number of lines should be not more than 10.

What I am tring to do here is

function(){
    var myValue = this.getValue();
    var myValueData = myValue.split(/\r*\n/);
    myValueData.length = 10;    
}

Ideally it should ommit all the lines after line number 10, but is not happening. Also how to restrict only upto 15 characters per line?

Share Improve this question edited Aug 2, 2018 at 0:15 Bharata 14.2k6 gold badges43 silver badges53 bronze badges asked Jul 24, 2018 at 6:22 DavidDavid 4,28111 gold badges41 silver badges89 bronze badges 8
  • Will this post help? – Andrew.Wolphoe Commented Jul 24, 2018 at 6:27
  • I don't want to show the message. I want to the wrap the things. – David Commented Jul 24, 2018 at 6:33
  • You can just remove the alert, the code will still work without it. – Andrew.Wolphoe Commented Jul 24, 2018 at 6:34
  • Nope. Text are disappearing. – David Commented Jul 24, 2018 at 7:06
  • Yep, they use js to prevent more text from appearing which mean if you exceed the limit the text won't show. Something like if you type the number 16 character someone will press backspace for you. – Andrew.Wolphoe Commented Jul 24, 2018 at 7:08
 |  Show 3 more comments

8 Answers 8

Reset to default 5

You can give that one a try, not perfect, but should work.

Maybe its be better instead using the change listeners, overwriting setValue or setRawValue functions on the component.

https://fiddle.sencha.com/#view/editor&fiddle/2js1

   {
                xtype: 'textareafield',
                grow: true,
                name: 'message',
                fieldLabel: 'Message',
                anchor: '100%',
                listeners: {
                    change: function (cmp, newVal, oldVal) {
                        var arrayForEachLine = newVal.split(/\r\n|\r|\n/g);
                        var newVal = [];
                        Ext.Array.each(arrayForEachLine, function (line, index) {
                            if (line.length >= 10) {
                                offset = line;
                                while (offset.length > 0) {
                                    newVal.push(offset.substring(0, 10));
                                    offset = offset.substring(10);
                                }

                            } else {
                                newVal.push(line);
                            }
                            if (index === 10) return false;
                            if (newVal.length >= 10) {
                                newVal = newVal.slice(0, 10);
                                return false;
                            }
                        });
                        cmp.suspendEvent('change');
                        cmp.setValue(newVal.join('\n'));
                        cmp.resumeEvent('change');
                    }
                }
            }

This can be achieved by using the change listener. I have created a demo (fiddle). Please look at the fiddle as the code there is neat and has comments too. Please look at my change listener code below:

listeners: {
                change: function () { 
                    var myValue = Ext.getCmp('myField').getValue(); 
                    var lines = myValue.split("\n"); 
                    if (lines.length > 10) { 
                        alert("You've exceeded the 10 line limit!"); 
                        Ext.getCmp('myField').setValue(textAreaValue); 
                    } else { //if num of lines <= 10
                        for (var i = 0; i < lines.length; i++) { /
                            if (lines[i].length > 15) { /
                                alert("Length exceeded in line " + (i+1)); 
                                Ext.getCmp('myField').setValue(textAreaValue); 
                            } else if (lines[i].length <= 15 && i == lines.length - 1) { 
                                textAreaValue = myValue; 
                            }

                        }
                    }

                }
            }

Please mark this as an answer if this answer solved your problem as this will also help other people in future. If there is anything wrong with this answer please let me know in the comments. I am sorry if something's wrong as I am not an extjs expert. But I still tried.

This problem is prefect for regex...

My solution focuses on the "max char width" and "max line number" requirements which I don't consider to be the same as "max char count" due to wrapping on words. Because this solution uses plain regex it works best with plain-text with newline chars \n for line breaks rather than html.

This function is idempotent which means it's output can be piped into it's input without issue. It's also very efficient because it's pure regex. Both of these attributes make it perfect for dropping into an onchange handler to update text on every key-press without incurring large performance penalties.

const fit = (str, w = 80, h = 24) => {
    w = new RegExp(`(?![^\\n]{1,${w}}$)([^\\n]{1,${w}})\\s`, 'g');
    str = str.replace(w, '$1\n');
    h = new RegExp(`(((^|\\n)[^\\n]*){${h}})((($|\\n)[^\\n]*)+)`);
    str = str.replace(h, '$1');
    return str;
};

This function will format the string into the given width / height, but it does so in a very agreeable way: The wrapping regex is considerate of existing new lines which is why it's idempotent, and breaks lines between words not through them. For an in depth explanation of how the word wrap regex works and why it's robust, see my answer for word wrapping strings in JavaScript with regex:

Wrap Text In JavaScript

To restrict textarea character length you can use the following attribute maxlength .

<textarea maxlength="50">

To truncate a string or number.

text_truncate = function(str, length, ending) {
if (length == null) {
  length = 100;
}
if (ending == null) {
  ending = '...';
}
if (str.length > length) {
  return str.substring(0, length - ending.length) + ending;
} else {
  return str;
}
};

you can call it by

text_truncate(yourContentToTruncate,15);

This solution is using pure JavaScript.

The basic idea is creating an array of chunks made of 15 characters with .match(/.{1,10}/g) and then, joining the array with a line break join("\n") to create an string again. The number of lines are restricted just removing the remaining chunks using splice(10, chunks.length - 1).

We are using .onkeyup event, but could be another event, that's because the code is not fired until we release a key. But this code also works if we paste text inside the textarea because the event is fired as well.

document.getElementById("textArea").onkeyup = function() {

  var text = this.value.replace("\n", "");

  if (text.length > 15) {

    var chunks = text.match(/.{1,15}/g);

    if (chunks.length > 10) { 

      chunks.splice(10, chunks.length - 1);

      alert("if text have more than 10 lines is removed");
    }

    this.value = chunks.join("\n");

  }
};
<textarea rows="18" cols="50" id="textArea">
</textarea>

In the place where you are specifying the textarea field, you need to set 'enforceMaxLength' attribute to true and then set 'maxLength' attribute to number of characters as your limit. Please find the following sample code for extjs. In the example i have set the restriction of no more than 10 characters. Hope this helps.

Ext.create('Ext.form.Panel', {
title: 'Contact Info',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
    xtype: 'textarea',
    name: 'name',
    fieldLabel: 'Name',
    enforceMaxLength:true,
    maxLength:10,
    allowBlank: false  // requires a non-empty value
}]

});

for 10 line accept condition

$(document).ready(function(){

    var lines = 10;
    var linesUsed = $('#linesUsed');

    $('#countMe').keydown(function(e) {

        newLines = $(this).val().split("\n").length;
        linesUsed.text(newLines);

        if(e.keyCode == 13 && newLines >= lines) {
            linesUsed.css('color', 'red');
            return false;
        }
        else {
            linesUsed.css('color', '');
        }
    });
});

I have written the solution which puts cuted characters to the start of the next line. Only 10 lines are allowed, in each line 15 characters.

Solution with Ext JS

Unfortunately, snippets on SO do not work with Ext JS.

And because of this you can see it on this codepen.io link.

Ext.application(
{
    name: 'ExtApp',
    launch: function ()
    {
        Ext.create('Ext.form.Panel',
        {
            title: 'Sample TextArea',
            bodyPadding: 10,
            renderTo: Ext.getBody(),
            title: 'Restricted number of characters per line in textarea',
            height: 500,
            width: 700,
            items:
            [{
                xtype: 'textareafield',
                grow: true,
                fieldLabel: 'Please write your text:',
                height: 320,
                width: 480,
                listeners:
                {
                    change: function(self, newVal)
                    {
                        var chunks = newVal.split(/\r*\n/g),
                            lastLineCutedTxt = '';

                        for(var i = 0; i < chunks.length; i++)
                        {
                            chunks[i] = lastLineCutedTxt + chunks[i];

                            if(chunks[i].length > 15)
                            {
                                lastLineCutedTxt = chunks[i].slice(15);
                                chunks[i] = chunks[i].slice(0, 15);
                            }
                            else lastLineCutedTxt = '';
                        }

                        if(lastLineCutedTxt != '')
                            chunks.push(lastLineCutedTxt);

                        self.suspendEvent('change');
                        self.setValue(chunks.slice(0, 10).join('\n'));
                        self.resumeEvent('change');
                    }
                }
            }]
        });
    }
});
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/ext-all.js"></script>
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/classic/theme-triton/resources/theme-triton-all.css">
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/classic/theme-triton/theme-triton.js"></script>

Solution with pure JavaScript

var txtArea = document.getElementById('txt-area')
txtArea.onkeyup = function(e)
{
    var chunks = this.value.split(/\r*\n/g),
        lastLineCutedTxt = '';

    for(var i = 0; i < chunks.length; i++)
    {
        chunks[i] = lastLineCutedTxt + chunks[i];

        if(chunks[i].length > 15)
        {
            lastLineCutedTxt = chunks[i].slice(15);
            chunks[i] = chunks[i].slice(0, 15);
        }
        else lastLineCutedTxt = '';
    }

    if(lastLineCutedTxt != '')
        chunks.push(lastLineCutedTxt);

    this.value = chunks.slice(0, 10).join('\n');

};
<textarea id="txt-area" rows="16" cols="35"></textarea>

发布评论

评论列表(0)

  1. 暂无评论