2009-08-17 26 views

Respuesta

63

Aquí es un plugin que va a hacer lo que está buscando:

El plugin:

(function($){ 

$.fn.autoGrowInput = function(o) { 

    o = $.extend({ 
     maxWidth: 1000, 
     minWidth: 0, 
     comfortZone: 70 
    }, o); 

    this.filter('input:text').each(function(){ 

     var minWidth = o.minWidth || $(this).width(), 
      val = '', 
      input = $(this), 
      testSubject = $('<tester/>').css({ 
       position: 'absolute', 
       top: -9999, 
       left: -9999, 
       width: 'auto', 
       fontSize: input.css('fontSize'), 
       fontFamily: input.css('fontFamily'), 
       fontWeight: input.css('fontWeight'), 
       letterSpacing: input.css('letterSpacing'), 
       whiteSpace: 'nowrap' 
      }), 
      check = function() { 

       if (val === (val = input.val())) {return;} 

       // Enter new content into testSubject 
       var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,' ').replace(/</g, '&lt;').replace(/>/g, '&gt;'); 
       testSubject.html(escaped); 

       // Calculate new width + whether to change 
       var testerWidth = testSubject.width(), 
        newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth, 
        currentWidth = input.width(), 
        isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth) 
             || (newWidth > minWidth && newWidth < o.maxWidth); 

       // Animate width 
       if (isValidWidthChange) { 
        input.width(newWidth); 
       } 

      }; 

     testSubject.insertAfter(input); 

     $(this).bind('keyup keydown blur update', check); 

    }); 

    return this; 

}; 

})(jQuery); 

EDIT: encontrado en: Is there a jQuery autogrow plugin for text fields?

+3

solo una observación, este complemento no funciona al pegar texto, y también evita que el usuario presione y mantenga presionada una tecla. –

+0

¿Por qué no hacer directamente 'testSubject.text (val)' en lugar de escapar 'val'? –

+0

@DennisPlucinik agregar un enlace al evento 'input' debería ayudar a solucionar el problema de pegar – philfreo

10

No creo que haya una solución perfecta para ese problema porque no se puede detectar el ancho real del texto ingresado en el elemento de entrada. Todo depende de la fuente que esté utilizando, la configuración del zoom en el navegador, etc.

Sin embargo, si puede elegir una fuente donde realmente pueda calcular el número de píxeles que tiene el texto (esta es la parte más difícil pero supongo que tratar de estimarlo de alguna manera). Puede usar esto para cambiar el ancho de su campo de entrada.

$('input').keyup(function() { 
    // I'm assuming that 1 letter will expand the input by 10 pixels 
    var oneLetterWidth = 10; 

    // I'm also assuming that input will resize when at least five characters 
    // are typed 
    var minCharacters = 5; 
    var len = $(this).val().length; 
    if (len > minCharacters) { 
     // increase width 
     $(this).width(len * oneLetterWidth); 
    } else { 
     // restore minimal width; 
     $(this).width(50); 
    } 
}); 
+0

+1 para un código simple y conciso que realmente funciona! –

+1

Este pequeño fragmento fue todo lo que necesitaba. También agregué dos reglas CSS simples para que la expansión y la contratación parezcan mejores para el usuario: transición: ancho 0.4s; -webkit-transition: ancho 0.4s;/* Safari */ –

0

Por defecto, la anchura de entrada es controlado por el parámetro size, que para type="text" corresponde al número de caracteres de ancho que debería ser.

Dado que esto se mide en caracteres y no en píxeles, el tamaño de píxel real se controla con la fuente (de ancho fijo) en uso.

+0

Si configura un ancho para la entrada en CSS al cambiar los parámetros de tamaño no tendrá ningún efecto en el ancho real del elemento. – RaYell

8

(Editado: utilizando el .text() método en lugar de .html() para obtener todo el formato correcto.)

Hola, no sé si sigues buscando, pero me encontré con esto cuando estaba buscando un script para hacer lo mismo. Así que espero que esto ayude a cualquiera que esté tratando de hacer esto, o algo similar.

function editing_key_press(e){ 
    if(!e.which)editing_restore(this.parentNode); 
    var text = $('<span>') 
     .text($(this).val()) 
     .appendTo(this.parentNode); 
    var w = text.innerWidth(); 
    text.remove(); 
    $(this).width(w+10); 
} 

La lógica de este código es poner el contenido en la página en un lapso y luego obtiene el ancho de este contenido y lo elimina. El problema que tuve fue que tuve que ejecutarlo tanto en Keydown como en KeyUp para que funcionara correctamente.

Espero que esto ayude, tal vez no porque he estado haciendo jquery durante un corto período de tiempo.

Gracias

George

+0

¡Esto fue perfecto! Agregué .hide() al texto, solo en caso de que un lapso de texto siguiera apareciendo, no se vería. –

+2

Me gusta, pero no funciona cuando tipeo espacios. – CoderDennis

+0

Para que funcione con espacios, uno podría reemplazar todo "" por " " antes de insertarlo en el elemento ficticio span. –

2

que utilizan seize's answer, pero realizan estos cambios:

  • entre el ajuste de isValidWidthChange y // Animate width:

    if (!isValidWidthChange && newWidth > minWidth && newWidth > o.maxWidth) { 
        newWidth = o.maxWidth; 
        isValidWidthChange = true; 
    } 
    

    De esta manera la entrada crecerá a medida grande como lo has permitido cuando sus contenidos son demasiado grandes para caber dentro del ancho máximo.

  • Después $(this).bind('keyup keydown blur update', check);:

    // Auto-size when page first loads 
    check(); 
    
1

Ver este plugin jQuery: https://github.com/padolsey/jQuery.fn.autoResize

Acabo de probar hacia fuera con textareas y funciona! Admite el crecimiento automático de áreas de texto, entrada [tipo = texto] e ingreso [tipo = contraseña].

UPD. Parece que el autor original eliminó el repositorio de github. El complemento no se ha actualizado en mucho tiempo y resultó ser bastante defectuoso. Solo puedo sugerirle que encuentre una mejor solución. Hice una solicitud de extracción de este complemento hace algún tiempo, así que tengo a copy of it en mi cuenta github, úsela solo en caso de que quiera mejorarla, ¡no es a prueba de balas!

Además, encontré que ExtJS framework tiene implementación de autosize para campos de texto, vea la propiedad de configuración grow. Si bien no es tan fácil extraer esta pequeña parte de la lógica del marco, puede darte algunas buenas ideas sobre el enfoque.

+0

Ese enlace lleva a la página 404 de GitHub. – CoderDennis

+0

Sí, el autor lo eliminó. Ver mi respuesta actualizada. –

0

Estaba pensando en lo mismo. TextBox debe redimensionarse a medida que el usuario escribe texto en él. Nunca lo usé, pero tengo una idea de cómo hacerlo. Algo como esto:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
    <head> 
    <meta http-equiv="content-type" content="text/html; charset=windows-1250"> 
    <meta name="generator" content="PSPad editor, www.pspad.com"> 
    <title></title> 
    </head> 
    <body> 

    <table border="1"> 
    <tr> 
    <td> 
     <span id="mySpan"> 
     <span id="mySpan2"></span> 
     <input id="myText" type="text" style="width:100%" onkeyup="var span = document.getElementById('mySpan2');var txt = document.getElementById('myText'); span.innerHTML=txt.value;"> 
     </span> 
    </td> 
    <td> 
      sss 
    </td> 
    </tr> 
</table> 

    </body> 
</html> 
6

que tiene un plugin de jQuery en GitHub: https://github.com/MartinF/jQuery.Autosize.Input

Se utiliza el mismo enfoque que apoderarse de respuesta, pero tienen algunos de los cambios mencionados en los comentarios.

Se puede ver un ejemplo vivo aquí: http://jsfiddle.net/mJMpw/6/

Ejemplo:

<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' /> 

input[type="data-autosize-input"] { 
    width: 90px; 
    min-width: 90px; 
    max-width: 300px; 
    transition: width 0.25s;  
} 

Usted sólo tiene que utilizar CSS para definir min/max-width y utilizar una transición de la anchura si quieres un bonito efecto .

Puede especificar el espacio/distancia hasta el final como el valor en notación json para el atributo data-autosize-input en el elemento de entrada.

Por supuesto, también se puede simplemente inicializarlo usando jQuery

$("selector").autosizeInput(); 
+1

¡Hermoso amigo! –

+1

Tu ejemplo de violín no funciona en chrome :-( – Lombas

+0

por favor arregla tu violinista – Seabizkit

0

probar este código:

var newTextLength = Math.floor($("input#text).val() * .80); 
$("input#text").attr("size",newTextLength); 
Cuestiones relacionadas