﻿/**
 * jQuery Maxlength plugin
 * @version		$Id: jquery.maxlength.js 13 2009-03-13 23:08:36Z emil@anon-design.se $
 * @package		jQuery maxlength 1.0.3
 * @copyright	Copyright (C) 2009 Emil Stjerneman / http://www.anon-design.se
 * @license		GNU/GPL, see LICENSE.txt
  */

(function($) 
{

	$.fn.maxlength = function(options)
	{
		var settings = jQuery.extend(
		{
			events:				[], // Array of events to be triggerd
			maxCharacters:		0, // characters limit
			status:				true, // true to show status indicator bewlow the element
		    hardLimit :			false,
			statusClass:		"maxLengthStatus", // the class on the status div
			statusText:			"characters left", // the status text
			notificationClass:	"maxLengthAlert",	// Will be added to the emement when maxlength is reached
			showAlert: 			false, // true to show a regular alert message
			alertText:			"You have typed too many characters.", // Text in the alert message
            slider:             true // Use counter slider
		}, options );
		
		// Add the default event
		$.merge(settings.events, ['keyup']);

		return this.each(function() 
		{
			var item = $(this);
			var charactersLength = $(this).val().length;
			var limit;
			if (settings.maxCharacters > 0)
			{
				limit = settings.maxCharacters;
			}
			else if (item.attr('maxlength') != undefined)
			{
				limit = item.attr('maxlength');
			}
			else
			{
				return false;
			}
			//Validate
			if(!validateElement()) 
			{
				return false;
			}
			
			// Loop through the events and bind them to the element
			$.each(settings.events, function (i, n) {
				item.bind(n, function(e) {
					charactersLength = item.val().length;
					checkChars();
				});
			})
			if (settings.hardLimit) {
				 
				item.bind('keydown', limitCheck);
			}

			// Insert the status div
			if(settings.status) 
			{
				item.after($("<div/>").addClass(settings.statusClass).html('-'));
				updateStatus();
			}

			// Remove the status div
			if(!settings.status) 
			{
				var removeThisDiv = item.next("div");
				
				if(removeThisDiv) {
					removeThisDiv.remove();
				}

			}
						  
            // Slide counter
			if(settings.slider) {
				item.next().hide();
				
				item.focus(function(){
					item.next().slideDown('fast');
				});

				item.blur(function(){
					item.next().slideUp('fast');
				}); 
			}

			function limitCheck(event) {
				charactersLength = $(this).val().length;
				var exceeded = charactersLength >= limit;
				var code = event.keyCode;
				if ( !exceeded )
					return;

				switch (code) {
					case 8:  // allow delete
					case 9:
					case 17:
					case 36: // and cursor keys
					case 35:
					case 37: 
					case 38:
					case 39:
					case 40:
					case 46:
						return;
					default:
						return false;
				}


			}

			function checkChars() 
			{
				var valid = true;
				
				// Too many chars?
				if(charactersLength >= limit) 
				{
					// Too may chars, set the valid boolean to false
					valid = false;
					// Add the notifycation class when we have too many chars
					item.addClass(settings.notificationClass);
					// Cut down the string
					item.val(item.val().substr(0,limit));
					// Show the alert dialog box, if its set to true
					showAlert();
				} 
				else 
				{
					// Remove the notification class
					if(item.hasClass(settings.notificationClass)) 
					{
						item.removeClass(settings.notificationClass);
					}
				}

				if(settings.status)
				{
					updateStatus();
				}
			};
			
			// Update the status text
			function updateStatus()
			{
				var charactersLeft = limit - charactersLength;
				
				if(charactersLeft < 0) 
				{
					charactersLeft = 0;
				}

				item.next("div").html(charactersLeft + " " + settings.statusText);
			};
			
			// Shows an alert msg
			function showAlert() 
			{
				if(settings.showAlert)
				{
					alert(settings.alertText);
				}
			};

			// Check if the element is valid.
			function validateElement() 
			{
				var ret = false;
				
				if(item.is('textarea')) {
					ret = true;
				} else if(item.filter("input[type=text]")) {
					ret = true;
				} else if(item.filter("input[type=password]")) {
					ret = true;
				}

				return ret;
			};

		});
	};
})(jQuery);

