JSFiddle - React, Tailwind, and code Playground

by ifandelse

HTML

<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
<script src="https://raw.github.com/cowboy/jquery-throttle-debounce/v1.1/jquery.ba-throttle-debounce.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css">
<div data-role="fieldcontain">
    <label for="question1">Nothing but Max Limit</label>
    <textarea id="question1" name="question1" maxlength="100"></textarea>
</div>
<div data-role="fieldcontain">
    <label for="question2">Max Limit with OnBlur Counter</label>
    <textarea id="question2" name="question2" maxlength="100" data-show-counter="true"></textarea>
</div>

<div data-role="fieldcontain">
    <label for="question3">Max Limit with Sync'd Counter</label>
    <textarea id="question3" name="question3" maxlength="100" data-show-counter="true"  data-sync-counter="true"></textarea>
</div>

CSS

label { float: left; width: 230px;}
div { clear: both; }
div canvas { display: inline-block; margin: 0 5px; position: relative; top: 2px; left: 4px; }
li.ui-li-count { display: inline-block }

JavaScript

(function() {
  return (function($) {
    $.fn.mobileMaxLength = function(options) {
      options = $.extend(true, {}, $.fn.mobileMaxLength.defaults, options);
      return this.each(function() {
        var context, counter, enforceMax, frequency, item, maxLen, showCounter, syncCounter, throttledUpdate, updateCounter;
        counter = void 0;
        context = void 0;
        item = $(this);
        maxLen = item.attr("maxlength") || options.maxLength;
        showCounter = item.data("show-counter") || options.showCounter;
        syncCounter = item.data("sync-counter") || options.syncCounter;
        frequency = item.data("counter-frequency") || options.counterFrequency;
        enforceMax = function() {
          if (item.val().length >= maxLen) {
            return item.val(item.val().substr(0, maxLen));
          }
        };
        updateCounter = function() {
          counter.width = counter.width;
          context.textBaseline = options.counterBaseline;
          context.font = options.counterFont;
          return context.fillText(maxLen - item[0].value.length, 0, 0);
        };
        throttledUpdate = _.throttle(function() {
          return _.defer(updateCounter);
        }, frequency);
        if (maxLen) {
          item.bind("blur", function() {
            enforceMax();
            if (showCounter) {
              return updateCounter();
            }
          });
          if (showCounter) {
            counter = document.createElement("canvas");
            counter.width = options.counterWidth;
            counter.height = options.counterHeight;
            context = counter.getContext("2d");
            updateCounter();
            $("<" + options.counterElement + ">", $.extend({}, options.counterElemOptions, {
              html: counter
            })).insertAfter(item);
            if (syncCounter) {
              item.bind("keyup", throttledUpdate);
            }
          }
        }
        return item;
      });
    };
    return...