2
\$\begingroup\$

I wrote my first jQuery plugin. It counts characters in a similar way to what StackExchange uses for comment entries. You can see it in action with this fiddle.

I feel that it's messy, but I can't explain why. One of the default options is defined outside the defaults hash because it uses a self-reference, and the method for flashing the text seems out of place. I'm also a little worried about how it handles form submission, and its prevention when the minimum number of characters is not met.

I'm not very fluent with jQuery so I expect this to be atrocious. I would love to hear some feedback as to why, or how it could be improved.

The form is submitted via ajax, using Rails' unobtrusive JS.

(function ($) {
 "use strict";
 $.fn.counter = function (options) {
 var defaults = {
 minimumSize: 15,
 minimumWarning: " more to go...",
 maximumSize: 25,
 maximumWarning: " characters remaining...",
 warningSize: 20,
 targetClass: '.help-block'
 };
 defaults.defaultText = "Enter at least " + defaults.minimumSize + " characters."; 
 options = $.extend(defaults, options);
 function count(elem) {
 var size = elem.val().length, target = elem.siblings(options.targetClass);
 if (size === 0) {
 target.html(options.defaultText);
 } else if (size < options.minimumSize) {
 target.html((options.minimumSize - size) + options.minimumWarning);
 } else if (size >= options.minimumSize && size < options.warningSize) {
 target.html('&nbsp;');
 } else if (size >= options.warningSize && size < options.maximumSize) {
 target.html((options.maximumSize - size) + options.maximumWarning);
 } else if (size >= options.maximumSize) {
 elem.val(elem.val().substring(0, options.maximumSize));
 target.html("0" + options.maximumWarning);
 }
 }
 this.each(function () {
 var elem = $(this);
 count(elem);
 elem.keyup(function () {
 count(elem);
 });
 elem.closest('form').submit(function () {
 if (elem.val().length < options.minimumSize) {
 $(this).find(options.targetClass).fadeOut('fast').fadeIn('fast').fadeOut('fast').fadeIn('fast');
 return false;
 }
 });
 return elem;
 });
 };
})(jQuery);
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Nov 27, 2012 at 19:41
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I suggest storing your defaults in a location that can be reached by the developers, and automatically filling in the minsize if minsize is included in the default text. For example,

(function ($) {
 "use strict";
 $.fn.counter = function (options) {
 options = $.extend($.fn.counter.defaults, options);
 function defaultText() {
 return options.defaultText.replace(/minsize/ig,options.minimumSize);
 }
 function count(elem) {
 var size = elem.val().length, target = elem.siblings(options.targetClass);
 if (size === 0) {
 target.html(defaultText());
 } else if (size < options.minimumSize) {
 target.html((options.minimumSize - size) + options.minimumWarning);
 } else if (size >= options.minimumSize && size < options.warningSize) {
 target.html('&nbsp;');
 } else if (size >= options.warningSize && size < options.maximumSize) {
 target.html((options.maximumSize - size) + options.maximumWarning);
 } else if (size >= options.maximumSize) {
 elem.val(elem.val().substring(0, options.maximumSize));
 target.html("0" + options.maximumWarning);
 }
 }
 this.each(function () {
 var elem = $(this);
 count(elem);
 elem.keyup(function () {
 count(elem);
 });
 elem.closest('form').submit(function () {
 if (elem.val().length < options.minimumSize) {
 $(this).find(options.targetClass).fadeOut('fast').fadeIn('fast').fadeOut('fast').fadeIn('fast');
 return false;
 }
 });
 return elem;
 });
 };
 $.fn.counter.defaults = {
 minimumSize: 15,
 minimumWarning: ' more to go...',
 maximumSize: 25,
 maximumWarning: ' characters remaining...',
 warningSize: 20,
 targetClass: '.help-block',
 defaultText: 'Enter at least minsize characters.'
 };
})(jQuery);
answered Nov 27, 2012 at 20:29
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.