PageSourceSearch

https://www.taghvim.com/static/js/jquery.simplyCountable.js

js taghvim.com collected 2026-10-02 13:05:37 UTC 4,479 bytes, 137 lines download raw bytes

1/*
2* jQuery Simply Countable plugin
3* Provides a character counter for any text input or textarea
4* 
5* @version  0.4.2
6* @homepage http://github.com/aaronrussell/jquery-simply-countable/
7* @author   Aaron Russell (http://www.aaronrussell.co.uk)
8*
9* Copyright (c) 2009-2010 Aaron Russell ([email protected])
10* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
11* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
12*/
13
14(function($){
15
16  $.fn.simplyCountable = function(options){
17    
18    options = $.extend({
19      counter:            '#counter',
20      countType:          'characters',
21      maxCount:           140,
22      strictMax:          false,
23      countDirection:     'down',
24      safeClass:          'safe',
25      overClass:          'over',
26      thousandSeparator:  ',',
27      onOverCount:        function(){},
28      onSafeCount:        function(){},
29      onMaxCount:         function(){}
30    }, options);
31
32    var navKeys = [33,34,35,36,37,38,39,40];
33
34    return $(this).each(function(){
35
36      var countable = $(this);
37      var counter = $(options.counter);
38      if (!counter.length) { return false; }
39      
40      var countCheck = function(){
41             
42        var count;
43        var revCount;
44        
45        var reverseCount = function(ct){
46          return ct - (ct*2) + options.maxCount;
47        }
48        
49        var countInt = function(){
50          return (options.countDirection === 'up') ? revCount : count;
51        }
52        
53        var numberFormat = function(ct){
54          var prefix = '';
55          if (options.thousandSeparator){
56            ct = ct.toString();          
57            // Handle large negative numbers
58            if (ct.match(/^-/)) { 
59              ct = ct.substr(1);
60              prefix = '-';
61            }
62            for (var i = ct.length-3; i > 0; i -= 3){
63              ct = ct.substr(0,i) + options.thousandSeparator + ct.substr(i);
64            }
65          }
66          return prefix + ct;
67        }
68
69        var changeCountableValue = function(val){
70          countable.val(val).trigger('change');
71        }
72        
73        /* Calculates count for either words or characters */
74        if (options.countType === 'words'){
75          count = options.maxCount - $.trim(countable.val()).split(/\s+/).length;
76          if (countable.val() === ''){ count += 1; }
77        }
78        else { count = options.maxCount - countable.val().length; }
79        revCount = reverseCount(count);
80        
81        /* If strictMax set restrict further characters */
82        if (options.strictMax && count <= 0){
83          var content = countable.val();
84          if (count < 0) {
85            options.onMaxCount(countInt(), countable, counter);
86          }
87          if (options.countType === 'words'){
88            var allowedText = content.match( new RegExp('\\s?(\\S+\\s+){'+ options.maxCount +'}') );
89            if (allowedText) {
90              changeCountableValue(allowedText[0]);
91            }
92          }
93          else { changeCountableValue(content.substring(0, options.maxCount)); }
94          count = 0, revCount = options.maxCount;
95        }
96        
97        counter.text(numberFormat(countInt()));
98        
99        /* Set CSS class rules and API callbacks */
100        if (!counter.hasClass(options.safeClass) && !counter.hasClass(options.overClass)){
101          if (count < 0){ counter.addClass(options.overClass); }
102          else { counter.addClass(options.safeClass); }
103        }
104        else if (count < 0 && counter.hasClass(options.safeClass)){
105          counter.removeClass(options.safeClass).addClass(options.overClass);
106          options.onOverCount(countInt(), countable, counter);
107        }
108        else if (count >= 0 && counter.hasClass(options.overClass)){
109          counter.removeClass(options.overClass).addClass(options.safeClass);
110          options.onSafeCount(countInt(), countable, counter);
111        }
112        
113      };
114      
115      countCheck();
116
117      countable.on('keyup blur paste', function(e) {
118        switch(e.type) {
119          case 'keyup':
120            // Skip navigational key presses
121            if ($.inArray(e.which, navKeys) < 0) { countCheck(); }
122            break;
123          case 'paste':
124            // Wait a few miliseconds if a paste event
125            setTimeout(countCheck, (e.type === 'paste' ? 5 : 0));
126            break;
127          default:
128            countCheck();
129            break;
130        }
131      });
132
133    });
134    
135  };
136
137})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.