w3schools tag tab style change attribute javascript html css prototypejs

javascript - tag - Autosizing área de texto usando prototipo



title html w3schools (18)

Actualmente estoy trabajando en una aplicación de ventas interna para la empresa para la que trabajo, y tengo un formulario que permite al usuario cambiar la dirección de entrega.

Ahora creo que se vería mucho mejor, si el área de texto que estoy usando para los detalles de la dirección principal ocupara solo el área del texto, y cambie el tamaño automáticamente si el texto fue cambiado.

Aquí hay una captura de pantalla de eso actualmente.

¿Algunas ideas?

@Chris

Un buen punto, pero hay razones por las que quiero que cambie el tamaño. Quiero que el área que ocupa sea el área de la información contenida en ella. Como puede ver en la captura de pantalla, si tengo un área de texto fija, ocupa una gran cantidad de espacio vertical.

Puedo reducir la fuente, pero necesito que la dirección sea grande y legible. Ahora puedo reducir el tamaño del área de texto, pero luego tengo problemas con las personas que tienen una línea de dirección que toma 3 o 4 (una toma 5) líneas. Necesitar que el usuario use una barra de desplazamiento es un gran no-no.

Creo que debería ser un poco más específico. Estoy buscando el cambio de tamaño vertical, y el ancho no importa tanto. El único problema que ocurre con eso es que el número ISO (el "1" grande) se coloca debajo de la dirección cuando el ancho de la ventana es demasiado pequeño (como se puede ver en la captura de pantalla).

No se trata de tener un truco; se trata de tener un campo de texto que el usuario puede editar que no ocupará espacio innecesario, pero mostrará todo el texto en él.

Aunque si alguien viene con otra forma de abordar el problema, estoy abierto a eso también.

Modifiqué un poco el código porque estaba actuando un poco raro. Lo cambié para activar en keyup, porque no tomaría en consideración el personaje que acaba de escribir.

resizeIt = function() { var str = $(''iso_address'').value; var cols = $(''iso_address'').cols; var linecount = 0; $A(str.split("/n")).each(function(l) { linecount += 1 + Math.floor(l.length / cols); // Take into account long lines }) $(''iso_address'').rows = linecount; };


Aquí hay otra técnica para autosizing un área de texto.

  • Utiliza la altura del píxel en lugar de la altura de la línea: un manejo más preciso del ajuste de línea si se usa una fuente proporcional.
  • Acepta ID o elemento como entrada
  • Acepta un parámetro de altura máxima opcional: útil si prefiere no dejar que el área de texto crezca más allá de un cierto tamaño (mantener todo en pantalla, evitar el diseño, etc.)
  • Probado en Firefox 3 e Internet Explorer 6

Código: (JavaScript simple)

function FitToContent(id, maxHeight) { var text = id && id.style ? id : document.getElementById(id); if (!text) return; /* Accounts for rows being deleted, pixel value may need adjusting */ if (text.clientHeight == text.scrollHeight) { text.style.height = "30px"; } var adjustedHeight = text.clientHeight; if (!maxHeight || maxHeight > adjustedHeight) { adjustedHeight = Math.max(text.scrollHeight, adjustedHeight); if (maxHeight) adjustedHeight = Math.min(maxHeight, adjustedHeight); if (adjustedHeight > text.clientHeight) text.style.height = adjustedHeight + "px"; } }

Demo: (usa jQuery, targets en el área de texto en el que estoy escribiendo ahora mismo - si tiene Firebug instalado, pegue las dos muestras en la consola y pruébelas en esta página)

$("#post-text").keyup(function() { FitToContent(this, document.documentElement.clientHeight) });


Aquí hay una extensión del widget Prototype que Jeremy publicó el 4 de junio:

Impide que el usuario ingrese más caracteres si usa límites en áreas de texto. Comprueba si quedan caracteres. Si el usuario copia texto en el área de texto, el texto se cortará al máximo. longitud:

/** * Prototype Widget: Textarea * Automatically resizes a textarea and displays the number of remaining chars * * From: http://.com/questions/7477/autosizing-textarea * Inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js */ if (window.Widget == undefined) window.Widget = {}; Widget.Textarea = Class.create({ initialize: function(textarea, options){ this.textarea = $(textarea); this.options = $H({ ''min_height'' : 30, ''max_length'' : 400 }).update(options); this.textarea.observe(''keyup'', this.refresh.bind(this)); this._shadow = new Element(''div'').setStyle({ lineHeight : this.textarea.getStyle(''lineHeight''), fontSize : this.textarea.getStyle(''fontSize''), fontFamily : this.textarea.getStyle(''fontFamily''), position : ''absolute'', top: ''-10000px'', left: ''-10000px'', width: this.textarea.getWidth() + ''px'' }); this.textarea.insert({ after: this._shadow }); this._remainingCharacters = new Element(''p'').addClassName(''remainingCharacters''); this.textarea.insert({after: this._remainingCharacters}); this.refresh(); }, refresh: function(){ this._shadow.update($F(this.textarea).replace(//n/g, ''<br/>'')); this.textarea.setStyle({ height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle(''lineHeight'').replace(''px'', '''')), this.options.get(''min_height'')) + ''px'' }); // Keep the text/character count inside the limits: if($F(this.textarea).length > this.options.get(''max_length'')){ text = $F(this.textarea).substring(0, this.options.get(''max_length'')); this.textarea.value = text; return false; } var remaining = this.options.get(''max_length'') - $F(this.textarea).length; this._remainingCharacters.update(Math.abs(remaining) + '' characters remaining'')); } });


Aquí hay una función que acabo de escribir en jQuery para hacerlo: puedes transferirla a Prototype , pero no admiten la "vitalidad" de jQuery, por lo que los elementos agregados por las solicitudes de Ajax no responderán.

Esta versión no solo se expande, sino que también se contrae cuando se presiona eliminar o retroceder.

Esta versión se basa en jQuery 1.4.2.

Disfrutar;)

http://pastebin.com/SUKeBtnx

Uso:

$("#sometextarea").textareacontrol();

o (cualquier selector de jQuery, por ejemplo)

$("textarea").textareacontrol();

Fue probado en Internet Explorer 7 / Internet Explorer 8 , Firefox 3.5 y Chrome. Todo funciona bien


Aquí hay una solución con JQuery :

$(document).ready(function() { var $abc = $("#abc"); $abc.css("height", $abc.attr("scrollHeight")); })

abc es una teaxtarea .


Aquí hay una versión prototipo de cambiar el tamaño de un área de texto que no depende del número de columnas en el área de texto. Esta es una técnica superior porque le permite controlar el área de texto a través de CSS, así como también tener un área de texto de ancho variable. Además, esta versión muestra la cantidad de caracteres restantes. Si bien no se solicita, es una característica muy útil y se elimina fácilmente si no se desea.

//inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js if (window.Widget == undefined) window.Widget = {}; Widget.Textarea = Class.create({ initialize: function(textarea, options) { this.textarea = $(textarea); this.options = $H({ ''min_height'' : 30, ''max_length'' : 400 }).update(options); this.textarea.observe(''keyup'', this.refresh.bind(this)); this._shadow = new Element(''div'').setStyle({ lineHeight : this.textarea.getStyle(''lineHeight''), fontSize : this.textarea.getStyle(''fontSize''), fontFamily : this.textarea.getStyle(''fontFamily''), position : ''absolute'', top: ''-10000px'', left: ''-10000px'', width: this.textarea.getWidth() + ''px'' }); this.textarea.insert({ after: this._shadow }); this._remainingCharacters = new Element(''p'').addClassName(''remainingCharacters''); this.textarea.insert({after: this._remainingCharacters}); this.refresh(); }, refresh: function() { this._shadow.update($F(this.textarea).replace(//n/g, ''<br/>'')); this.textarea.setStyle({ height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle(''lineHeight'').replace(''px'', '''')), this.options.get(''min_height'')) + ''px'' }); var remaining = this.options.get(''max_length'') - $F(this.textarea).length; this._remainingCharacters.update(Math.abs(remaining) + '' characters '' + (remaining > 0 ? ''remaining'' : ''over the limit'')); } });

Crea el widget llamando al new Widget.Textarea(''element_id'') . Las opciones predeterminadas se pueden anular pasándolas como un objeto, por ejemplo, new Widget.Textarea(''element_id'', { max_length: 600, min_height: 50}) . Si desea crearlo para todas las áreas de texto en la página, haga algo como:

Event.observe(window, ''load'', function() { $$(''textarea'').each(function(textarea) { new Widget.Textarea(textarea); }); });


Compruebe el siguiente enlace: http://james.padolsey.com/javascript/jquery-plugin-autoresize/

$(document).ready(function () { $(''.ExpandableTextCSS'').autoResize({ // On resize: onResize: function () { $(this).css({ opacity: 0.8 }); }, // After resize: animateCallback: function () { $(this).css({ opacity: 1 }); }, // Quite slow animation: animateDuration: 300, // More extra space: extraSpace:20, //Textarea height limit limit:10 }); });


Facebook lo hace, cuando escribes en las paredes de las personas, pero solo cambia el tamaño verticalmente.

El cambio de tamaño horizontal me parece un desastre debido al ajuste de palabras, las líneas largas, etc., pero el cambio de tamaño vertical parece ser bastante seguro y agradable.

Ninguno de los nuevos usuarios de Facebook que conozco han mencionado algo al respecto o han estado confundidos. Usaría esto como evidencia anecdótica para decir ''adelante, implementarlo''.

Algún código JavaScript para hacerlo, usando Prototype (porque eso es con lo que estoy familiarizado):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <script src="http://www.google.com/jsapi"></script> <script language="javascript"> google.load(''prototype'', ''1.6.0.2''); </script> </head> <body> <textarea id="text-area" rows="1" cols="50"></textarea> <script type="text/javascript" language="javascript"> resizeIt = function() { var str = $(''text-area'').value; var cols = $(''text-area'').cols; var linecount = 0; $A(str.split("/n")).each( function(l) { linecount += Math.ceil( l.length / cols ); // Take into account long lines }) $(''text-area'').rows = linecount + 1; }; // You could attach to keyUp, etc. if keydown doesn''t work Event.observe(''text-area'', ''keydown'', resizeIt ); resizeIt(); //Initial on load </script> </body> </html>

PD: Obviamente, este código JavaScript es muy ingenuo y no está bien probado, y es probable que no quieras usarlo en cajas de texto con novelas en ellas, pero entiendes la idea general.


He hecho algo bastante fácil. Primero puse el TextArea en un DIV. En segundo lugar, he llamado a la función de ready para este script.

<div id="divTable"> <textarea ID="txt" Rows="1" TextMode="MultiLine" /> </div> $(document).ready(function () { var heightTextArea = $(''#txt'').height(); var divTable = document.getElementById(''divTable''); $(''#txt'').attr(''rows'', parseInt(parseInt(divTable .style.height) / parseInt(altoFila))); });

Sencillo. Es la altura máxima del div una vez que se representa, dividido por la altura de un TextArea de una fila.


Los usuarios de Internet Explorer, Safari, Chrome y Opera deben recordar establecer explícitamente el valor de altura de línea en CSS. Hago una hoja de estilo que establece las propiedades iniciales para todos los cuadros de texto de la siguiente manera.

<style> TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial } </style>


Me gusta la respuesta de @memical.

Sin embargo, encontré algunas mejoras. Puede usar la función jQuery height() . Pero tenga en cuenta los píxeles de relleno y los fondos de relleno. De lo contrario, su área de texto crecerá demasiado rápido.

$(document).ready(function() { $textarea = $("#my-textarea"); // There is some diff between scrollheight and height: // padding-top and padding-bottom var diff = $textarea.prop("scrollHeight") - $textarea.height(); $textarea.live("keyup", function() { var height = $textarea.prop("scrollHeight") - diff; $textarea.height(height); }); });


Mi solución no usa jQuery (porque a veces no tienen que ser lo mismo) a continuación. Aunque solo se probó en Internet Explorer 7 , la comunidad puede señalar todas las razones por las que esto es incorrecto:

textarea.onkeyup = function () { this.style.height = this.scrollHeight + ''px''; }

Hasta ahora realmente me gusta cómo está funcionando, y no me importan otros navegadores, así que probablemente lo aplique a todas mis áreas de texto:

// Make all textareas auto-resize vertically var textareas = document.getElementsByTagName(''textarea''); for (i = 0; i<textareas.length; i++) { // Retain textarea''s starting height as its minimum height textareas[i].minHeight = textareas[i].offsetHeight; textareas[i].onkeyup = function () { this.style.height = Math.max(this.scrollHeight, this.minHeight) + ''px''; } textareas[i].onkeyup(); // Trigger once to set initial height }


Necesitaba esta función para mí, pero ninguna de las que funcionaban aquí funcionaba como las necesitaba.

Entonces usé el código de Orion y lo cambié.

Agregué en una altura mínima, para que en la destrucción no sea demasiado pequeño.

function resizeIt( id, maxHeight, minHeight ) { var text = id && id.style ? id : document.getElementById(id); var str = text.value; var cols = text.cols; var linecount = 0; var arStr = str.split( "/n" ); $(arStr).each(function(s) { linecount = linecount + 1 + Math.floor(arStr[s].length / cols); // take into account long lines }); linecount++; linecount = Math.max(minHeight, linecount); linecount = Math.min(maxHeight, linecount); text.rows = linecount; };


Para aquellos que están codificando IE y se encuentran con este problema. IE tiene un pequeño truco que lo hace 100% CSS.

<TEXTAREA style="overflow: visible;" cols="100" ....></TEXTAREA>

Incluso puede proporcionar un valor para rows = "n" que IE ignorará, pero otros navegadores usarán. Realmente odio la codificación que implementa IE hacks, pero este es muy útil. Es posible que solo funcione en el modo Quirks.


Probablemente la solución más corta:

jQuery(document).ready(function(){ jQuery("#textArea").on("keydown keyup", function(){ this.style.height = "1px"; this.style.height = (this.scrollHeight) + "px"; }); });

De esta manera no necesitas ningún divs oculto ni nada de eso.

Nota: puede que tenga que jugar con this.style.height = (this.scrollHeight) + "px"; dependiendo de cómo estilo el área de texto (altura de línea, relleno y ese tipo de cosas).


Solo volviendo a visitar esto, lo he hecho un poco más ordenado (aunque alguien que está lleno de botella en Prototype / JavaScript podría sugerir mejoras?).

var TextAreaResize = Class.create(); TextAreaResize.prototype = { initialize: function(element, options) { element = $(element); this.element = element; this.options = Object.extend( {}, options || {}); Event.observe(this.element, ''keyup'', this.onKeyUp.bindAsEventListener(this)); this.onKeyUp(); }, onKeyUp: function() { // We need this variable because "this" changes in the scope of the // function below. var cols = this.element.cols; var linecount = 0; $A(this.element.value.split("/n")).each(function(l) { // We take long lines into account via the cols divide. linecount += 1 + Math.floor(l.length / cols); }) this.element.rows = linecount; } }

Solo llame con:

new TextAreaResize(''textarea_id_name_here'');


Un refinamiento de algunas de estas respuestas es dejar que CSS haga más del trabajo.

La ruta básica parece ser:

  1. Crea un elemento contenedor para contener el área de textarea y un div oculto
  2. Usando Javascript, mantenga los contenidos de la textarea de textarea sincronizados con los div ''s
  3. Deje que el navegador haga el trabajo de calcular la altura de ese div
  4. Debido a que el navegador maneja la representación / dimensionamiento del div oculto, evitamos establecer explícitamente la altura de la zona de texto.

document.addEventListener(''DOMContentLoaded'', () => { textArea.addEventListener(''change'', autosize, false) textArea.addEventListener(''keydown'', autosize, false) textArea.addEventListener(''keyup'', autosize, false) autosize() }, false) function autosize() { // Copy textarea contents to div browser will calculate correct height // of copy, which will make overall container taller, which will make // textarea taller. textCopy.innerHTML = textArea.value.replace(//n/g, ''<br/>'') }

html, body, textarea { font-family: sans-serif; font-size: 14px; } .textarea-container { position: relative; } .textarea-container > div, .textarea-container > textarea { word-wrap: break-word; /* make sure the div and the textarea wrap words in the same way */ box-sizing: border-box; padding: 2px; width: 100%; } .textarea-container > textarea { overflow: hidden; position: absolute; height: 100%; } .textarea-container > div { padding-bottom: 1.5em; /* A bit more than one additional line of text. */ visibility: hidden; width: 100%; }

<div class="textarea-container"> <textarea id="textArea"></textarea> <div id="textCopy"></div> </div>


Usando ASP.NET, simplemente haz esto:

<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Automatic Resize TextBox</title> <script type="text/javascript"> function setHeight(txtarea) { txtarea.style.height = txtdesc.scrollHeight + "px"; } </script> </head> <body> <form id="form1" runat="server"> <asp:TextBox ID="txtarea" runat= "server" TextMode="MultiLine" onkeyup="setHeight(this);" onkeydown="setHeight(this);" /> </form> </body> </html>


@memical tenía una @memical solución para establecer la altura del área de texto en la carga de la página con jQuery, pero para mi aplicación quería aumentar la altura del área de texto a medida que el usuario agregaba más contenido. Construí la solución de memical con lo siguiente:

$(document).ready(function() { var $textarea = $("p.body textarea"); $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); $textarea.keyup(function(){ var current_height = $textarea.css("height").replace("px", "")*1; if (current_height + 5 <= $textarea.attr("scrollHeight")) { $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); } }); });

No es muy sencillo, pero tampoco es una aplicación orientada al cliente, por lo que la suavidad en realidad no importa. (Si esto hubiera estado orientado al cliente, probablemente hubiera usado un plugin jQuery de cambio de tamaño automático).