2009-02-17 3 views
31

Szukam javascript, który może ograniczyć liczbę linii (przez wiersz mam na myśli tekst zakończony przez użytkownika naciśnięcie klawisza enter na klawiaturze) użytkownik jest w stanie wprowadzić w textarea. Znalazłem rozwiązania, ale po prostu nie działają lub zachowują się naprawdę dziwnie. Najlepszym rozwiązaniem byłaby wtyczka jQuery, która może wykonać pracę - podobnie jak CharLimit, ale powinna być w stanie ograniczyć liczbę wierszy tekstu, a nie liczbę znaków.Ograniczanie liczby wierszy w textarea

Z góry dziękuję.

+3

Określenie "linii". Widoczne linie? Linie rozdzielone przez "\ n" lub coś innego? – alphadogg

Odpowiedz

22

Ten potęga pomocy (prawdopodobnie najlepiej przy użyciu jQuery, onDomReady i dyskretnie dodanie keydown zdarzenia do pola tekstowego), ale przetestowane w IE7 i FF3:

<html> 
    <head><title>Test</title></head> 
    <body> 
    <script type="text/javascript"> 
     var keynum, lines = 1; 

     function limitLines(obj, e) { 
     // IE 
     if(window.event) { 
      keynum = e.keyCode; 
     // Netscape/Firefox/Opera 
     } else if(e.which) { 
      keynum = e.which; 
     } 

     if(keynum == 13) { 
      if(lines == obj.rows) { 
      return false; 
      }else{ 
      lines++; 
      } 
     } 
     } 
     </script> 
    <textarea rows="4" onkeydown="return limitLines(this, event)"></textarea> 
    </body> 
</html> 

* Edit - wyjaśnienie: To łapie przyciśnięcie jeśli klawisz ENTER jest wciśnięty i po prostu nie dodaje nowego wiersza, jeśli linie w obszarze tekstowym są takie same jak wiersze tekstu. W przeciwnym razie zwiększa liczbę linii.

+4

Ma to problem, gdy użytkownik trafi w backspace prowadzący do usunięcia całej linii, co ograniczy liczbę dostępnych wierszy, i ewentualnie usunąć wszystkie wiersze pozostawiając tylko jedną linię do zapisu. Nie radzi sobie również dobrze, gdy użytkownik wprowadza wiele znaków, które powodują przejście do nowej linii, ale utworzona linia nie została zliczona, aby ograniczyć linię. –

+0

Dziękuję bardzo marktucks – Visme

+1

również kończy się niepowodzeniem na pastę. – Anas

3

Liczba linii widocznych/wyświetlanych dla danego bloku tekstu może się różnić w zależności od przeglądarki, użytych czcionek itp. Należy ustawić minimalną czcionkę i rozmiar czcionki, aby pół-niezawodne liczenie linii wyświetlania.

AKTUALIZACJA: Widzę zmianę. Wtedy coś w stylu kevchadders code powinno dla ciebie zrobić dobrze. Będziesz potrzebował js, który zlicza znaki i '\ r \ n oraz sprawdza limit zdefiniowany przez użytkownika. Ponadto, jeśli nie używasz jego skryptu, upewnij się, że korzystasz z tego, który obejmuje sprawdzanie przedziału czasu i/lub zdarzenia onKeyDown/onKeyUp w obszarze tekstowym. Być może dlatego niektóre skrypty, które wypróbowałeś, wydają się "zachowywać dziwnie".

+0

Wygląda jak empi zredagowane pytanie na ya;) Linia == "\ n" –

1

Jest to zasadniczo to samo, co odpowiedź Ivana, przy użyciu jQuery. Przetestowałem to na własny projekt; wydaje się działać dobrze.

<script type="text/javascript" charset="utf-8"> 
    $(function() 
    { 
    function getLines(id) 
    { 
     return $('#' + id).val().split("\n").length 
    } 

    $('#testing').keyup(function() 
    { 
    var allowedNumberOfLines = 4; 

    if(getLines('testing') > allowedNumberOfLines) 
    { 
     modifiedText = $(this).val().split("\n").slice(0, allowedNumberOfLines); 
     $(this).val(modifiedText.join("\n")); 
    } 
    }); 
}); 
</script> 
+0

getLines (id) powinno być getLines (el) gdzie $ ("# testing") jest wysyłane bezpośrednio do funkcji getLines. Łatwa optymalizacja. – jamtoday

+1

Ale czy to działa z automatycznie zapakowanymi słowami podczas pisania? Twoja funkcja polega tylko na nowych liniach. – acme

14

Jak to zrobić z jQuery:

Bind do keyDown wydarzeniem textarea.

function limitTextareaLine(e) { 
    if(e.keyCode == 13 && $(this).val().split("\n").length >= $(this).attr('rows')) { 
     return false; 
    } 
} 
+0

Cześć Maciej, dziękuję za odpowiedź. Czy możesz podać przykład tego? – chainwork

+0

@chainwork Pewnie. [Przykład] (http://jsbin.com/ufeyom/2/edit) – Maciej

+7

Ta strategia kończy się niepowodzeniem, gdy użytkownik wklei nowe linie do obszaru tekstowego. –

3

(Sporządzono w jquery). Nie jest idealny, ale dba o opakowanie. Nie deponuje tylko końca wiersza (\ n).
Zdarzenie przewijania jquery ma problemy z mozilla i firefox, jeśli właściwość przepełnienia css w textarea nie jest automatyczna, w przeciwnym razie usuń odpowiednie linie i ustaw przepełnienie ukryte. Może pomóc w zmianie rozmiaru css: brak i stała wysokość.

$('#textarea').scroll(function() { 
    $(this).css("overflow", "hidden");  /* for the mozilla browser problem */ 
    $(this).animate({scrollTop: $(this).outerHeight()}); 
    while ($(this).scrollTop() > 0) {  /* for the copy and paste case */    
     lines=$(this).val().slice(0,-1); 
     $(this).val(lines); 
    } 
    $(this).css("overflow", "auto");  /* For the mozilla browser problem */ 
}); 
0

Rozszerzyłem go nieco, aby wykryć nawet przepełnienie bez ręcznego łamania linii. Jest to dla textarea o ustalonym rozmiarze z "overflow: hidden".

W tej chwili moje rozwiązanie powoduje, że czcionka jest mniejsza, jeśli nie pasuje do textarea. I jeśli to możliwe, powiększa go jeszcze bardziej.

var keynum, allowedLines = 5, defaultFontSize = 13/*px*/; 

$(document).ready(function() { 
    $("textarea").keydown(function(e, obj) { 
     if(window.event) 
      keynum = e.keyCode; 
     else if (e.which) 
      keynum = e.which; 

     if (keynum == 13 && allowedLines <= $(this).val().split("\n").length) 
      return false; 
    }); 
    $("textarea").keyup(function(e, obj) { 
     // Avoid copy-paste 
     if (allowedLines < $(this).val().split("\n").length) {    
      lines = $(this).val().split("\n").slice(0, allowedLines); 
      $(this).val(lines.join('\n')); 
     } 

     // Check overflow 
     if ((this.clientHeight < this.scrollHeight)) { 
      while ((this.clientHeight < this.scrollHeight)) { 
       currFontSize = $(this).css('font-size'); 
       finalNum = parseFloat(currFontSize, 11); 
       stringEnding = currFontSize.slice(-2); 
       $(this).css('font-size', (finalNum-1) + stringEnding); 
      } 
     } else if ($(this).css('fontSize') != defaultFontSize+'px') { 
      while ($(this).css('font-size') != defaultFontSize+'px') { 
       // First lets increase the font size 
       currFontSize = $(this).css('font-size'); 
       finalNum = parseFloat(currFontSize, 11); 
       stringEnding = currFontSize.slice(-2); 
       $(this).css('font-size', (finalNum+1) + stringEnding); 
       // lets loop until its enough or it gets overflow again 
       if(this.clientHeight < this.scrollHeight) { 
        // there was an overflow and we have to recover the value 
        $(this).css('font-size', currFontSize); 
        break; 
       } 
      } 
     } 
    }); 
}); 
4

To rozwiązanie działa:

<script type="text/javascript"> 
    function limitTextarea(textarea, maxLines, maxChar) { 
     var lines = textarea.value.replace(/\r/g, '').split('\n'), lines_removed, char_removed, i; 
     if (maxLines && lines.length > maxLines) { 
      lines = lines.slice(0, maxLines); 
      lines_removed = 1 
     } 
     if (maxChar) { 
      i = lines.length; 
      while (i-- > 0) if (lines[i].length > maxChar) { 
       lines[i] = lines[i].slice(0, maxChar); 
       char_removed = 1 
      } 
      if (char_removed || lines_removed) { 
       textarea.value = lines.join('\n') 
      } 
     } 
    } 
</script> 

i tekst obszar byłby

<asp:TextBox ID="myWishTB" runat="server" Height="185px" TextMode="MultiLine" 
      Style="overflow: auto;" Width="95%" 
      onkeyup="limitTextarea(this,10,80)"> 
</asp:TextBox> 

w regularnych HTML:

<textarea id="textareaID" onkeyup="limitTextarea(this,5,100)" cols="20" rows="5"> </textarea> 
1

jQuery przykład. Działa to zarówno w przypadku pisania, jak i wklejania.

//Limit to # of rows in textarea or arbitrary # of rows 
    $('#yourtextarea').bind('change keyup', function(event) { 
    //Option 1: Limit to # of rows in textarea 
    rows = $(this).attr('rows'); 
    //Optiion 2: Limit to arbitrary # of rows 
    rows = 6; 

    var value = ''; 
    var splitval = $(this).val().split("\n"); 

    for(var a=0;a<rows && typeof splitval[a] != 'undefined';a++) { 
     if(a>0) value += "\n"; 
     value += splitval[a]; 
    } 
    $(this).val(value); 
    });