Question

Je travaille actuellement sur une application de vente interne pour l'entreprise pour laquelle je travaille et je dispose d'un formulaire qui permet à l'utilisateur de modifier l'adresse de livraison.

Maintenant, je pense que cela serait beaucoup plus joli si la zone de texte que j'utilise pour les détails de l'adresse principale occupait simplement la zone du texte qu'elle contient et se redimensionnait automatiquement si le texte était modifié.

En voici actuellement une capture d'écran.

ISO Address

Des idées?


@Chris

C'est un bon point, mais il y a des raisons pour lesquelles je souhaite le redimensionner.Je veux que la zone qu'il occupe soit la zone des informations qu'il contient.Comme vous pouvez le voir sur la capture d'écran, si j'ai une zone de texte fixe, elle occupe beaucoup d'espace vertical.

Je peux réduire la police, mais j'ai besoin que l'adresse soit grande et lisible.Maintenant, je peux réduire la taille de la zone de texte, mais j'ai ensuite des problèmes avec les personnes qui ont une ligne d'adresse qui prend 3 ou 4 lignes (une en prend 5).Le fait de devoir demander à l'utilisateur d'utiliser une barre de défilement est un non-non majeur.

Je suppose que je devrais être un peu plus précis.Je recherche un redimensionnement vertical et la largeur n'a pas autant d'importance.Le seul problème qui se produit avec cela est que le numéro ISO (le grand "1") est placé sous l'adresse lorsque la largeur de la fenêtre est trop petite (comme vous pouvez le voir sur la capture d'écran).

Il ne s’agit pas d’avoir un truc ;il s'agit d'avoir un champ de texte que l'utilisateur peut modifier et qui ne prendra pas d'espace inutile, mais affichera tout le texte qu'il contient.

Mais si quelqu'un propose une autre façon d'aborder le problème, je suis également ouvert à cela.


J'ai un peu modifié le code car il agissait un peu bizarrement.Je l'ai modifié pour qu'il s'active lors de la saisie, car il ne prendrait pas en compte le caractère qui vient d'être saisi.

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;
};
Était-ce utile?

La solution

Facebook le fait lorsque vous écrivez sur les murs des gens, mais ne redimensionne que verticalement.

Le redimensionnement horizontal me semble être un gâchis, à cause du retour à la ligne, des longues lignes, etc., mais le redimensionnement vertical semble être plutôt sûr et agréable.

Aucun des nouveaux utilisateurs de Facebook que je connais n'en a jamais parlé ou n'a été confus.J'utiliserais cela comme preuve anecdotique pour dire « allez-y, mettez-le en œuvre ».

Du code JavaScript pour le faire, en utilisant Prototype (parce que c'est ce que je connais) :

<!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>

PS :Évidemment, ce code JavaScript est très naïf et mal testé, et vous ne voudrez probablement pas l'utiliser sur des zones de texte contenant des romans, mais vous voyez l'idée générale.

Autres conseils

Une amélioration de certaines de ces réponses consiste à laisser CSS faire une plus grande partie du travail.

L'itinéraire de base semble être :

  1. Créez un élément conteneur pour contenir le textarea et un caché div
  2. En utilisant Javascript, conservez le textareaLe contenu de est synchronisé avec le divc'est
  3. Laissez le navigateur faire le travail de calcul de la hauteur de ce div
  4. Parce que le navigateur gère le rendu/dimensionnement des éléments cachés div, nous évitons définir explicitement l’attribut textareala hauteur.

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>

Voici une autre technique pour redimensionner automatiquement une zone de texte.

  • Utilise la hauteur des pixels au lieu de la hauteur des lignes :gestion plus précise du retour à la ligne si une police proportionnelle est utilisée.
  • Accepte soit l'ID, soit l'élément en entrée
  • Accepte un paramètre facultatif de hauteur maximale - utile si vous préférez ne pas laisser la zone de texte s'étendre au-delà d'une certaine taille (garder le tout à l'écran, éviter de casser la mise en page, etc.)
  • Testé sur Firefox 3 et Internet Explorer 6

Code:(JavaScript vanille 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";
   }
}

Démo :(utilise jQuery, cible la zone de texte dans laquelle je tape en ce moment - si vous avez Pyromane installé, collez les deux échantillons dans la console et testez sur cette page)

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

Probablement la solution la plus courte :

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

De cette façon, vous n'avez pas besoin de divs cachés ou quoi que ce soit du genre.

Note:tu devras peut-être jouer avec this.style.height = (this.scrollHeight) + "px"; en fonction de la façon dont vous stylisez la zone de texte (hauteur de ligne, remplissage et ce genre de choses).

Voici un Prototype version de redimensionnement d'une zone de texte qui ne dépend pas du nombre de colonnes dans la zone de texte.Il s'agit d'une technique supérieure car elle vous permet de contrôler la zone de texte via CSS ainsi que d'avoir une zone de texte à largeur variable.De plus, cette version affiche le nombre de caractères restants.Bien qu'elle ne soit pas demandée, il s'agit d'une fonctionnalité très utile et elle est facilement supprimée si elle n'est pas souhaitée.

//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'));
  }
});

Créez le widget en appelant new Widget.Textarea('element_id').Les options par défaut peuvent être remplacées en les passant en tant qu'objet, par ex. new Widget.Textarea('element_id', { max_length: 600, min_height: 50}).Si vous souhaitez le créer pour toutes les zones de texte de la page, procédez comme :

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

Voici une solution avec JQuery:

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

abc est un teaxtarea.

Vérifiez le lien ci-dessous: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
    });
});

En y revenant, je l'ai rendu un peu plus propre (même si quelqu'un qui a une bouteille pleine sur Prototype/JavaScript pourrait suggérer des améliorations ?).

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

Il suffit d'appeler avec :

new TextAreaResize('textarea_id_name_here');

J'ai fait quelque chose d'assez simple.J'ai d'abord mis le TextArea dans un DIV.Deuxièmement, j'ai fait appel au ready fonction à ce 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)));
});

Simple.Il s'agit de la hauteur maximale du div une fois rendu, divisée par la hauteur d'une TextArea d'une ligne.

J'avais besoin de cette fonction pour moi-même, mais aucune de celles d'ici ne fonctionnait comme j'en avais besoin.

J'ai donc utilisé le code d'Orion et je l'ai modifié.

J'ai ajouté une hauteur minimale, afin que lors de la destruction, elle ne devienne pas trop petite.

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

Aimez la réponse de @memical.

Cependant j'ai trouvé quelques améliorations.Vous pouvez utiliser le jQuery height() fonction.Mais soyez conscient des pixels de remplissage en haut et en bas.Sinon, votre zone de texte grandira trop vite.

$(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);
  });
});

Ma solution n'utilisant pas jQuery (car parfois il n'est pas nécessaire que ce soit la même chose) est ci-dessous.Bien qu'il n'ait été testé qu'en Internet Explorer 7, afin que la communauté puisse indiquer toutes les raisons pour lesquelles cela est faux :

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

Jusqu'à présent, j'aime vraiment son fonctionnement, et je ne me soucie pas des autres navigateurs, donc je vais probablement l'appliquer à toutes mes zones de texte :

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

Voici une extension du widget Prototype que Jeremy a posté le 4 juin :

Cela empêche l'utilisateur de saisir plus de caractères si vous utilisez des limites dans les zones de texte.Il vérifie s'il reste des caractères.Si l'utilisateur copie du texte dans la zone de texte, le texte est coupé au maximum.longueur:

/**
 * Prototype Widget: Textarea
 * Automatically resizes a textarea and displays the number of remaining chars
 * 
 * From: http://stackoverflow.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'));
  }
});

@memical avait une solution géniale pour définir la hauteur de la zone de texte lors du chargement de la page avec jQuery, mais pour mon application, je voulais pouvoir augmenter la hauteur de la zone de texte à mesure que l'utilisateur ajoutait plus de contenu.J'ai construit la solution de memical avec ce qui suit :

$(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));
        }
    });
});

Ce n'est pas très fluide, mais ce n'est pas non plus une application orientée client, donc la fluidité n'a pas vraiment d'importance.(Si cela avait été orienté client, j'aurais probablement simplement utilisé un plugin jQuery de redimensionnement automatique.)

Pour ceux qui codent pour IE et rencontrent ce problème.IE a une petite astuce qui le rend 100 % CSS.

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

Vous pouvez même fournir une valeur pour rows="n" qu'IE ignorera, mais que d'autres navigateurs utiliseront.Je déteste vraiment le codage qui implémente les hacks IE, mais celui-ci est très utile.Il est possible que cela ne fonctionne qu'en mode Quirks.

Internet Explorer, Safari, Chrome et Opéra les utilisateurs doivent se rappeler de définir explicitement la valeur de la hauteur de ligne en CSS.Je crée une feuille de style qui définit les propriétés initiales de toutes les zones de texte comme suit.

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

Voici une fonction que je viens d'écrire dans jQuery pour le faire - vous pouvez la porter vers Prototype, mais ils ne prennent pas en charge la « vivacité » de jQuery, donc les éléments ajoutés par les requêtes Ajax ne répondront pas.

Cette version non seulement s'étend, mais elle se contracte également lorsque vous appuyez sur Supprimer ou Retour arrière.

Cette version s'appuie sur jQuery 1.4.2.

Apprécier ;)

http://pastebin.com/SUKeBtnx

Usage:

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

ou (n'importe quel sélecteur jQuery par exemple)

$("textarea").textareacontrol();

Il a été testé sur Internet Explorer 7/Internet Explorer 8, Firefox 3.5 et Chrome.Tout fonctionne bien.

En utilisant ASP.NET, faites simplement ceci :

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top