简体   繁体   中英

Why does the title of my Bootstrap tooltip only change once with the keydown event in jQuery?

I have text inputs and textareas that I would like to show the user how many characters they have used out of the limit. So I add a tooltip to every element that has a data-maxlength attribute. I create the tooltip for the current text input that includes the length and the maxlength values(x / 250 characters) every time a key is pressed. The problem is that the value of the title attribute of the tooltip never changes after you stop typing for the first time. Here is a jsFiddle to show you.

The jQuery

$(document).ready(function(){
    $('[data-maxlength]').each(function(){
        $(this).on('keyup', function(){
            $(this).tooltip({
                selector: 'data-toggle="tooltip"',
                placement: 'bottom',
                trigger: 'manual',
                title: $(this).val().length + ' / ' + $(this).data('maxlength') + ' characters used.'
            });
            $(this).tooltip('show');
        });
    });
});

The HTML:

<textarea name="description" data-maxlength="250"></textarea>

Thanks for your time.

The title is set only on first key-event, try this:

title: function() {return $('[data-maxlength]').val().length + ' / ' + $(this).data('maxlength') + ' characters used.';}

see: How do JavaScript closures work?

I agree with dreamveivers comment, so this would be a better implementation:

 $(document).ready(function(){ $('[data-maxlength]').each(function(){ var maxText = ' / ' + $(this).data('maxlength') + ' characters used.'; var tooltip = $(this).tooltip({ selector: 'data-toggle="tooltip"', placement: 'bottom', trigger: 'manual' }); $(this).on('keyup', function(){ tooltip.attr('title', $(this).val().length + maxText) .tooltip('fixTitle') .tooltip('show'); }); }); });
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <textarea name="description" data-maxlength="250"></textarea>

see: Change Twitter Bootstrap Tooltip content on click

This seems to fix your problem:

$(document).ready(function(){

    $('[data-maxlength]').each(function(){
        $(this).on('keyup', function(){
            $(this).attr('data-original-title', $(this).val().length + ' / ' + $(this).data('maxlength') + ' characters used.');

            $(this)
              .tooltip({
                selector: 'data-toggle="tooltip"',
                placement: 'bottom'
            })
            .data('placement', 'bottom');

            $(this).tooltip('show');
        });
    });
});

https://jsfiddle.net/vw49te7d/

As found here: Change Twitter Bootstrap Tooltip content on click

Actually this is valid issue which has already been in github issue log & so far there hasn't been any major update on this from past 2+ yrs.

Github issue page

Workaround:

  1. Initialize the tooltip for all text area outside .each() since there is no need to loop through all the elements by class selector txtarea [Usage of class selector is far more better than attribute selector in terms of performance].
  2. Update the attr which holds the title info of the tooltip inside keyup callback

$(this).attr('data-original-title', $(this).val().length + ' / ' + $(this).data('maxlength') + ' characters used.');

Live Demo @ JSFiddle

I noticed that every time I use .tooltip() for an element (ex. textarea), when the tooltip is displayed, there is always a <div> appended as the next sibling of the element (ex. textarea). The appended <div> has class tooltip . And inside the <div> there is an element with class tooltip-inner which contains the text that is the displayed message in the tooltip. Here is the example of the appended <div> :

<div style="top: 63px; left: 9.5px; display: block;" id="tooltip59349" class="tooltip fade bottom in" role="tooltip">
  <div style="left: 50%;" class="tooltip-arrow"></div>
  <div class="tooltip-inner">
    <span class="n-char">0</span> / 250 characters used.
  </div>
</div>

So, my solution is to replace the text inside that .tooltip-inner . In this solution you don't have to call .tooltip('show') everytime you want to change the title. You won't see blinked tooltip on every keyup.

$(document).ready(function(){
    $('[data-maxlength]').each(function(){
      $(this).tooltip({
        placement: 'bottom',
        trigger: 'focus',
        html: true,
        title: '<span class="n-char">' + $(this).val().length + '</span> / ' + $(this).data('maxlength') + ' characters used.'
      });

      $(this).on('focus keyup', function(){
        $(this).next('.tooltip').find('.tooltip-inner .n-char').text($(this).val().length);
      });
    });
});

https://jsfiddle.net/mikhsan/okpLzg5c/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM