web-dev-qa-db-fra.com

Existe-t-il un plug-in jQuery autogrow pour les champs de texte?

J'ai un trouvé divers plugins pour autogrowing un textarea , mais pas les champs de texte. Est-ce que quelqu'un sait s'il en existe?

65
Brad Gessler

Voici un plugin qui fera ce que vous recherchez:

EDIT: J'ai corrigé le plugin conformément au commentaire de Mathias. :)

Voir une démo ici: http://jsfiddle.net/rRHzY

Le 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,'&nbsp;').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);
145
James

J'ai un plugin jQuery sur GitHub: https://github.com/MartinF/jQuery.Autosize.Input

Il utilise la même approche que James répond mais a certains des changements mentionnés dans les commentaires.

Vous pouvez voir un exemple en direct ici: http://jsfiddle.net/mJMpw/6/

Exemple:

<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;    
}

Vous utilisez simplement css pour définir min/max-width et utilisez une transition sur la largeur si vous voulez un effet Nice.

Vous pouvez spécifier l'espace/la distance jusqu'à la fin en tant que valeur en notation json pour l'attribut data-autosize-input sur l'élément input.

Bien sûr, vous pouvez aussi simplement l'initialiser en utilisant jQuery

$("selector").autosizeInput();
9
MartinF

Bon plugin, merci! J'ai toutefois changé deux choses qui semblaient mieux fonctionner dans mon projet.

  1. J'ai changé la balise TESTER en DIV, pour éviter d'obtenir un "Appel inattendu à un accès à une méthode ou à une propriété" dans IE8 (même si votre démo fonctionne dans IE8. Y avait-il une raison particulière pour utiliser une balise HTML personnalisée?
  2. Après l’instruction bind près de la fin du code, j’ai ajouté un appel à check () afin de redimensionner la zone de texte immédiatement après le chargement de la page, au cas où elle aurait déjà un contenu au démarrage.

J'espère que cela t'aides.

7
JP.

je voulais juste partager une petite amélioration à l'excellent plugin de James. Ajoutez ce code à la déclaration CSS de l'élément testeur pour prendre en compte l'indentation du texte:

textIndent: 0

Sans cette option, dans certaines situations, l'élément de test peut hériter par inadvertance de l'indentation du texte, ce qui annule la taille de l'entrée.

Comme JP, je souhaitais également redimensionner l’entrée à la taille correcte dès le début, ce que j’ai fait un peu différemment, en enchaînant "trigger ('keyup") "à l’appel de méthode autoGrowInput, par exemple:

$('#contact_form').autoGrowInput({comfortZone: 7, minWidth: 10, maxWidth: 200}).trigger('keyup');

En passant, je me suis inscrit sur ce site uniquement pour commenter la solution de James et je suis un peu ennuyé de constater que je ne peux pas, car je n'ai pas assez de points de réputation pour commencer. Désolé si j'ai manqué quelque chose, mais cela semble vouloir dire que je dois poster ceci est un commentaire sur la question principale plutôt que plus adéquatement sur la solution de James.

4
Michael

J'avais aussi remplacé

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

à

$(this).bind('keyup blur update', check).bind('keydown', function() {
    setTimeout(check);
});

afin que le champ soit redimensionné juste après avoir été rendu par le navigateur. Cela débarrasserait le terrain de quelques bavardages.

2
Sergei Morozov

J'ai créé un plugin pour l'entrée de type text, qui recrée ce comportement. Il a quelques autres caractéristiques uniques. Vous pouvez voir un exemple et voir la documentation du plugin. @james answer a quelques problèmes pour coller du texte de grande taille dans l'entrée. Pour résoudre ce problème, j'ai apporté quelques modifications à son code. Voici un demo , pour cet exemple.

(function($){        
    $.fn.autoGrowInput = function(o) {

        o = $.extend({
            maxWidth: 200,
            minWidth: 1,
            comfortZone: 1,
          width: 1
        }, o);

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

            var minWidth = o.minWidth || $(this).width(),
                maxWidth = o.maxWidth,
                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,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);

                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                    newWidth = testerWidth + o.comfortZone,
                    currentWidth = input.width();

                   if (testerWidth < minWidth) {
                       newWidth = minWidth;
                   } else if (testerWidth > maxWidth) {
                       newWidth = maxWidth;
                   } 

                   input.width(newWidth + o.comfortZone);  
            };

            testSubject.insertAfter(input);

            $(this).bind('input', check);

        });

        return this;

    };

})(jQuery);
2
ajorquera

J'ai créé un plugin appelé input-autogrow pour résoudre ce problème pour mes propres projets. Ce plugin était à l'origine basé sur James answer mais a été amélioré à bien des égards.

https://github.com/westonganger/input-autogrow

input-autogrow est un plugin pour la saisie automatique des entrées. Ce plugin est différent des autres parce que le plus souvent, les balises textarea sont ciblées, cette bibliothèque est plutôt ciblée sur les balises d’entrée. Nécessite une bibliothèque DOM telle que jQuery, Zepto ou toute autre prise en charge des plugins $ .fn.

Voici quelques exemples d'utilisation.

/* Makes elements readonly if they already have the readonly attribute */
$('input.autogrow').inputAutogrow();

/* Manually trigger update */
$('input.autogrow').trigger('autogrow');
/* or */
$('input.autogrow').trigger('change');

/* Custom Options */
$('input.autogrow').inputAutogrow({maxWidth: 500, minWidth: 25, trailingSpace: 10});

/* Remove autogrow from input */
$('input.autogrow').inputAutogrow('destroy');
0
Weston Ganger

Si vous souhaitez que la zone de texte s'agrandisse lorsque la chaîne qu'elle contient dépasse sa largeur, une solution de ce type pourrait fonctionner pour vous ... Elle détecte l'attribut size de la zone de texte. Si la longueur de la chaîne dépasse cet attribut, la zone de texte est étendue à la longueur de la chaîne lors de la modification de clé.

Dans le script ci-dessous, "#test" est un identifiant de zone de texte.

<script language="javascript" type="text/javascript">
$(document).ready(function(){
    $("#test").keyup(function(){
        if($("#test").attr("size") < $("#test").val().length){
            size = $("#test").val().length;
            $("#test").attr("size",size);
        }
    })
});
</script>
0
BraedenP

Awsome plugin James! Merci. J’ai ajouté la suggestion de vérification à la fin de JP, bien que très efficace. 

De plus, j’ai ajouté quelques modifications de ma part .. Je voulais définir la taille maximale de l’entrée si la largeur modifiée dépassait la largeur maximale, alors j’ai ajouté:

else if (widthexceeds){
    input.width(o.maxWidth);
}

en dessous de la vérification si isValidWidthChange où widthexceeds = newWidth > o.maxWidth

0
Snigdha Batra

Assez drôle dans IE overflow: visible est pris très au sérieux. Vous pouvez obtenir cet effet en appliquant un débordement: visible sur vos éléments d’entrée. Pas sûr si des astuces CSS similaires existent pour les navigateurs modernes.

0
tbranyen