Счетчик текстовых сообщений / обратный отсчет с отрицательными числами и правоприменение

Я работал над добавлением счетчика символов в поле TEXTAREA. Есть много, много решений, доступных онлайн для этой задачи.

Решение "Стоп в ноль"
Проблема, с которой я сталкиваюсь, заключается в том, что практически все решения заканчивают ввод пользователя на 0. Это эффективно, я думаю, но это не оптимально с точки зрения удобства для пользователя. Например, если пользователь вставляет текст в TEXTAREA, и текст превышает ограничение поля, это решение с остановкой в ​​нуле будет резко обрезать лишний текст. Затем пользователь должен найти пропавший контент, а затем отредактировать свое сообщение, отправить вторую форму или что-то другое.

Решение для "отрицательного числа символов"
Другие решения позволяют пользователю вводить все, что они хотят. Счетчик символов из положительного в отрицательный. Проблема с этими счетчиками заключается в отсутствии принудительного применения: они позволяют пользователям отправлять форму даже с отрицательным количеством символов.

Решение для Twitter
Я думаю, что Twitter имеет это право. Они позволяют пользователям вводить все, что они хотят, и выделяют лишний текст с отрицательным количеством символов (и цветным фоном, который мне не нужен). Они отключают кнопку отправки, пока счетчик отрицательный.

Мое (неполное) решение
Работая со сторонним кодом, который я нашел через Google, я разработал счетчик символов, который отлично работает с точки зрения количества. Но, будучи немного новичком в JS, я не смог закодировать правоприменительную часть.

Вот мой вопрос:
Как мне получить код для предотвращения отправки формы, когда счетчик имеет отрицательное число?

HTML

<form action="" method="post">

<div>
<textarea name="comments" id="comments" cols="50" rows="10"></textarea>
</div>

<div>
<input type="submit">
</div>

</form>

CSS

form div {
    position: relative;
}

form .counter {
    position: absolute;
    left: 300px;
    bottom: -25px;
    font-size: 25px;
    font-weight: bold;
    color: #ccc;
    }

form .warning {color: orange;}

form .exceeded {color: red;}

JavaScript

<script src="/js/jquery.js"></script>

<script>

(function($) {

    $.fn.charCount = function(options){

        // default configuration properties
        var defaults = {    
            allowed: 100,       
            warning: 25,
            css: 'counter',
            counterElement: 'span',
            cssWarning: 'warning',
            cssExceeded: 'exceeded',
            counterText: ''
        }; 

        var options = $.extend(defaults, options); 

        function calculate(obj){
            var count = $(obj).val().length;
            var available = options.allowed - count;
            if(available <= options.warning && available >= 0){
                $(obj).next().addClass(options.cssWarning);
            } else {
                $(obj).next().removeClass(options.cssWarning);
            }
            if(available < 0){
                $(obj).next().addClass(options.cssExceeded);
            } else {
                $(obj).next().removeClass(options.cssExceeded);
            }
            $(obj).next().html(options.counterText + available);
        };

        this.each(function() {              
            $(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
            calculate(this);
            $(this).keyup(function(){calculate(this)});
            $(this).change(function(){calculate(this)});
        });

    };

})(jQuery);

</script>

<script>
    $(document).ready(function(){   
        $("#comments").charCount();
    });
</script>

https://jsfiddle.net/nyc212/sk5kfopw/

2 ответа

Решение

Я изменил ваш плагин, чтобы принять кнопку отправки в качестве первого параметра. Если вы хотите, чтобы он был более динамичным:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title></title>
 <style>
  form div {
   position: relative;
  }

  form .counter {
   position: absolute;
   left: 300px;
   bottom: -25px;
   font-size: 25px;
   font-weight: bold;
   color: #ccc;
  }

  form .warning {
   color: orange;
  }

  form .exceeded {
   color: red;
  }
 </style>
 <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
 <script>
  (function($) {

   $.fn.charCount = function(btnsub, options){
   
    this.btnsub = btnsub;
        
    // default configuration properties
    var defaults = { 
     allowed: 100,  
     warning: 25,
     css: 'counter',
     counterElement: 'span',
     cssWarning: 'warning',
     cssExceeded: 'exceeded',
     counterText: ''
    }; 
   
    var options = $.extend(defaults, options); 
  
    function calculate(obj,btnsub){
    
     btnsub.attr("disabled", "disabled");

     var count = $(obj).val().length;
     var available = options.allowed - count;
     if(available <= options.warning && available >= 0){
      $(obj).next().addClass(options.cssWarning);
     } else {
      $(obj).next().removeClass(options.cssWarning);
     }
     if(available < 0){
      $(obj).next().addClass(options.cssExceeded);
     } else {
      $(obj).next().removeClass(options.cssExceeded);
      btnsub.removeAttr("disabled");
     }
     
     $(obj).next().html(options.counterText + available);
    };
    
    this.each(function() {     
     $(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
     
     calculate(this, btnsub);

     $(this).keyup(function(){calculate(this,btnsub)});
     $(this).change(function(){calculate(this,btnsub)});
    });
   
   };

  })(jQuery);

  $(document).ready(function(){ 
   $("#comments").charCount($("#btnsub"));
  });

 </script>
</head>
<body>
 <form method="post">

  <div>
   <textarea name="comments" id="comments" cols="50" rows="10"></textarea>
  </div>

  <div>
   <input type="submit" id="btnsub">
  </div>

 </form>
</body>
</html>

Я бы попробовал либо отключив кнопку отправки с помощью disabled атрибут или предотвращение отправки формы с использованием e.preventDefault, Я обновил вашу скрипку... просто раскомментируйте любой из вариантов

https://jsfiddle.net/sk5kfopw/1/

Другие вопросы по тегам