diff --git a/js/maxlength.js b/js/maxlength.js
index af816cb..29978f1 100644
--- a/js/maxlength.js
+++ b/js/maxlength.js
@@ -26,14 +26,25 @@
         if ($(this).hasClass('maxlength_js_truncate_html')) {
           options['truncateHtml'] = true;
         }
-        $(this).charCount(options);
+        if ($(this).data('maxlength-type') == 'word') {
+          $(this).wordCount(options);
+        } else {
+          $(this).charCount(options);
+        }
       });
     },
     detach: function(context, settings) {
       $('.maxlength', context).removeOnce('maxlength', function() {
-        $(this).charCount({
-          action: 'detach'
-        });
+        if ($(this).data('maxlengthType')) {
+          $(this).wordCount({
+            action: 'detach'
+          });
+        } else {
+          $(this).charCount({
+            action: 'detach'
+          });
+        }
+
       });
     }
   };
@@ -113,6 +124,94 @@
   };
 
   /**
+   * Based on the calculate method, will calc the number of words instead of the number of characters
+   *
+   * @param obj
+   * @param options
+   * @param count
+   * @param wysiwyg
+   * @param getter
+   * @param setter
+   */
+  ml.calculateWords = function (obj, options, count, wysiwyg, getter, setter)
+  {
+    var counter = $('#' + obj.attr('id') + '-' + options.css);
+    var limit = parseInt(options.maxWord);
+    var text;
+
+    if (typeof ml[getter] == 'function') {
+      text = ml[getter](wysiwyg);
+    } else {
+      text = obj.val();
+    }
+
+    if (count == undefined) {
+      if (options.truncateHtml) {
+        text = ml.strip_tags(text);
+      }
+      else {
+        text = ml.twochar_lineending(text);
+      }
+    }
+
+    // Have to do this so that the count doesn't get borked.
+    if (wysiwyg) {
+        text = ml.strip_tags(text);
+        text = text.replace(/&nbsp;/g, '');
+    }
+
+    var words = $.trim(text).split(/\s+/);
+    if (text.length == 0) {
+      count = 0;
+    }
+    else {
+      count = words.length;
+    }
+
+    var textarea = $('#' + obj.attr('id'));
+    var realTextarea = textarea[0];
+
+    if (count > limit){
+
+      var len = textarea.val().length;
+
+      if (options.enforce) {
+          textarea.attr("maxlength", len);
+
+          if (typeof(realTextarea.validity) !== undefined) {
+              var validString = Drupal.t(
+                  'Content limited to @limit words. You are currently using @count. Please shorten your text.'
+                  , {'@limit': limit, '@count': count});
+              realTextarea.setCustomValidity(validString);
+          }
+      }
+    }
+    else {
+      $('#' + obj.attr('id')).removeAttr("maxlength");
+
+        if (typeof(realTextarea.validity) !== undefined) {
+            realTextarea.setCustomValidity('');
+        }
+    }
+
+    var available = limit - count;
+
+    if (available <= options.warning) {
+      counter.addClass(options.cssWarning);
+    }
+    else {
+      counter.removeClass(options.cssWarning);
+    }
+
+    /*
+    if (options.enforce && available <= 0) {
+      obj.val(obj.val().substr(0, obj.val().length - 1));
+    }
+    */
+    counter.html(options.counterText.replace('@limit', limit).replace('@remaining', available).replace('@count', count));
+  }
+
+  /**
    * Replaces line ending with to chars, because PHP-calculation counts with two chars
    * as two characters.
    *
@@ -282,6 +381,53 @@
 
   };
 
+  $.fn.wordCount = function (options)
+  {
+      var defaults = {
+          warning: 10,
+          css: 'counter',
+          counterElement: 'div',
+          cssWarning: 'messages warning',
+          cssExceeded: 'error',
+          counterText: Drupal.t('Content limited to @limit words, remaining: <strong>@remaining</strong>'),
+          action: 'attach',
+          enforce: false,
+          truncateHtml: false
+      };
+
+      var options = $.extend(defaults, options);
+      ml.options[$(this).attr('id')] = options;
+
+    if (options.action == 'detach') {
+      $(this).removeClass('maxlength-processed');
+      $('#' + $(this).attr('id') + '-' + options.css).remove();
+      delete ml.options[$(this).attr('id')];
+      return 'removed';
+    }
+
+    var counterElement = $('<' + options.counterElement + ' id="' + $(this).attr('id') + '-' + options.css + '" class="' + options.css + '"></' + options.counterElement + '>');
+    if ($(this).next('div.grippie').length) {
+      $(this).next('div.grippie').after(counterElement);
+    } else {
+      $(this).after(counterElement);
+    }
+
+    /* Remove the maxlength attribute from the textfield otherwise browsers can
+     * stop the word count working
+     */
+    $(this).removeAttr('maxlength');
+    options.maxWord = $(this).attr("data-maxlength");
+
+    ml.calculateWords($(this), options);
+    $(this).keyup(function() {
+      ml.calculateWords($(this), options);
+    });
+    $(this).change(function() {
+      ml.calculateWords($(this), options);
+    });
+
+  };
+
   /**
    * Integrate with WYSIWYG
    * Detect changes on editors and invoke ml.calculate()
@@ -364,16 +510,27 @@
           } else {
             ml.options[e.editor.element.getId()].truncateHtml = false;
           }
-          // Add the events on the editor.
-          e.editor.on('key', function(e) {
-            setTimeout(function(){ml.ckeditorChange(e)}, 100);
-          });
-          e.editor.on('paste', function(e) {
-            setTimeout(function(){ml.ckeditorChange(e)}, 500);
-          });
-          e.editor.on('elementsPathUpdate', function(e) {
-            setTimeout(function(){ml.ckeditorChange(e)}, 100);
-          });
+          if (editor.data('maxlength-type') == 'word') {
+            e.editor.on('key', function(e) {
+              setTimeout(function(){ml.ckeditorWordChange(e)}, 100);
+            });
+            e.editor.on('paste', function(e) {
+              setTimeout(function(){ml.ckeditorWordChange(e)}, 500);
+            });
+            e.editor.on('elementsPathUpdate', function(e) {
+              setTimeout(function(){ml.ckeditorWordChange(e)}, 100);
+            });
+          } else {
+            e.editor.on('key', function(e) {
+              setTimeout(function(){ml.ckeditorChange(e)}, 100);
+            });
+            e.editor.on('paste', function(e) {
+              setTimeout(function(){ml.ckeditorChange(e)}, 500);
+            });
+            e.editor.on('elementsPathUpdate', function(e) {
+              setTimeout(function(){ml.ckeditorChange(e)}, 100);
+            });
+          }
         }
       });
     }
@@ -390,6 +547,12 @@
     }
   };
 
+  ml.ckeditorWordChange = function (e)
+  {
+    var options = $.extend({}, ml.options[e.editor.element.getId()]);
+    ml.calculateWords($('#' + e.editor.element.getId()), options, ml.strip_tags(ml.ckeditorGetData(e)).length, e, 'ckeditorGetData', 'ckeditorSetData');
+  };
+
   // Gets the data from the ckeditor.
   ml.ckeditorGetData = function(e) {
     return e.editor.getData();
diff --git a/maxlength.module b/maxlength.module
index 2473fbb..f117fac 100644
--- a/maxlength.module
+++ b/maxlength.module
@@ -29,11 +29,25 @@ function maxlength_element_info_alter(&$cache) {
 function maxlength_pre_render($element) {
   if (((isset($element['#maxlength']) && $element['#maxlength'] > 0) ||(isset($element['#attributes']['maxlength']) && $element['#attributes']['maxlength'] > 0)) &&
         isset($element['#maxlength_js']) && $element['#maxlength_js'] === TRUE) {
-    if ($element['#type'] == 'textarea' && !isset($element['#attributes']['maxlength'])) {
+    $maxlengthType = isset($element['#maxlength_js_type']) ? $element['#maxlength_js_type'] : 'character';
+
+    if ($element['#type'] == 'textarea' && !isset($element['#attributes']['maxlength']) && $maxlengthType != 'word') {
       $element['#attributes']['maxlength'] = $element['#maxlength'];
     }
-    $element['#attributes']['class'][] = 'maxlength';
+
+    if ($maxlengthType == 'word') {
+      if (isset($element['#maxlength'])) {
+        $element['#attributes']['data-maxlength'] = $element['#maxlength'];
+      } else {
+        $element['#attributes']['data-maxlength'] = $element['#attributes']['maxlength'];
+      }
+
+    }
+
     $element['#attached']['js'][] = drupal_get_path('module', 'maxlength') . '/js/maxlength.js';
+    $element['#attributes']['class'][] = 'maxlength';
+
+    $element['#attributes']['data-maxlength-type'] = $maxlengthType;
   }
   return $element;
 }
@@ -68,6 +82,21 @@ function maxlength_form_field_ui_field_edit_form_alter(&$form, &$form_state, $fo
         ),
       ),
     );
+    $form['instance']['widget']['settings']['maxlength_js_type'] = array(
+      '#type' => 'select',
+      '#title' => 'Maxlength Type',
+      '#descrption' => 'Whether you want the count based on number of characters, or words',
+      '#options' => array('word' => 'Word', 'character' => 'Character'),
+      '#default_value' => isset($form['#instance']['widget']['settings']['maxlength_js_type'])
+         ? $form['#instance']['widget']['settings']['maxlength_js_type'] : 'character',
+     );
+     $form['instance']['widget']['settings']['maxlength_js_label'] = array(
+       '#type' => 'textarea',
+       '#rows' => 2,
+       '#title' => t('Count down message'),
+       '#default_value' =>  isset($form['#instance']['widget']['settings']['maxlength_js_label']) ? $form['#instance']['widget']['settings']['maxlength_js_label'] : MAXLENGTH_DEFAULT_JS_LABEL,
+       '#description' => t('The text used in the Javascript message under the input, where "@limit", "@remaining" and "@count" are replaced by the appropriate numbers.'),
+     );
   }
   // Add settings for textfield widgets
   $fields = array('text_textfield');
@@ -79,14 +108,6 @@ function maxlength_form_field_ui_field_edit_form_alter(&$form, &$form_state, $fo
       '#default_value' => isset($form['#instance']['widget']['settings']['maxlength_js']) ? $form['#instance']['widget']['settings']['maxlength_js'] : NULL,
     );
   }
-
-  $form['instance']['widget']['settings']['maxlength_js_label'] = array(
-    '#type' => 'textarea',
-    '#rows' => 2,
-    '#title' => t('Count down message'),
-    '#default_value' =>  isset($form['#instance']['widget']['settings']['maxlength_js_label']) ? $form['#instance']['widget']['settings']['maxlength_js_label'] : MAXLENGTH_DEFAULT_JS_LABEL,
-    '#description' => t('The text used in the Javascript message under the input, where "@limit", "@remaining" and "@count" are replaced by the appropriate numbers.'),
-  );
 }
 
 /**
@@ -101,7 +122,7 @@ function maxlength_field_attach_form($entity_type, $entity, &$form, &$form_state
     }
   }
   if (isset($elements)) {
-    _maxlength_children($form, $elements);    
+    _maxlength_children($form, $elements);
   }
 }
 
@@ -126,6 +147,10 @@ function _maxlength_children(&$element, $ms_elements) {
       $element[$child]['#maxlength'] = isset($element[$child]['#maxlength']) ? $element[$child]['#maxlength'] : $ms_elements[$element[$child]['#field_name']]['widget']['settings']['maxlength_js'];
       $element[$child]['#maxlength_js'] = TRUE;
 
+      if (isset($ms_elements[$element[$child]['#field_name']]['widget']['settings']['maxlength_js_type'])) {
+        $element[$child]['#maxlength_js_type'] = $ms_elements[$element[$child]['#field_name']]['widget']['settings']['maxlength_js_type'];
+      }
+
       $maxlength_js_label = !empty($ms_elements[$element[$child]['#field_name']]['widget']['settings']['maxlength_js_label']) ?
         $ms_elements[$element[$child]['#field_name']]['widget']['settings']['maxlength_js_label'] : MAXLENGTH_DEFAULT_JS_LABEL;
       $maxlength_js_label = t($maxlength_js_label);
@@ -159,6 +184,13 @@ function maxlength_process_element($element, &$form_state) {
     $element['#attributes']['class'][] = 'maxlength_js_truncate_html';
     unset($element['#maxlength']);
   }
+
+  if (isset($element['#maxlength_js_type']) && $element['#maxlength_js_type'] == 'word') {
+    $element['#element_validate'][] = 'maxlength_validate_input';
+    $element['#attributes']['maxlength'] = $element['#maxlength'];
+    unset($element['#maxlength']);
+  }
+
   return $element;
 }
 
@@ -172,9 +204,20 @@ function maxlength_validate_input(&$element, &$form_state) {
     // Compute the length of the text, without counting the tags, and consider
     // the "enter" characters as only one character.
     $value = filter_xss(str_replace(array("\r\n", '&nbsp;'), array(' ', ' '), $element['#value']), array());
-    if (drupal_strlen($value) > $element['#attributes']['maxlength']) {
-      form_error($element, t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'], '%max' => $element['#attributes']['maxlength'], '%length' => drupal_strlen($value))));
+
+    if($element['#maxlength_js_type'] == 'word'){
+      $wordArray = preg_split('/\s+/', $value);
+      $wordCount = count($wordArray);
+      if ($wordCount > $element['#attributes']['maxlength']) {
+        form_error($element, t('!name cannot be longer than %max words but is currently %length words long.', array('!name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'], '%max' => $element['#attributes']['maxlength'], '%length' => $wordCount)));
+      }
+    }
+    else{
+      if (drupal_strlen($value) > $element['#attributes']['maxlength']) {
+        form_error($element, t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'], '%max' => $element['#attributes']['maxlength'], '%length' => drupal_strlen($value))));
+      }
     }
+
     // giving the element back the #maxlength, maybe some other modules requires it.
     $element['#maxlength'] = $element['#attributes']['maxlength'];
   }
@@ -210,7 +253,7 @@ function maxlength_form_node_type_form_alter(&$form, &$form_state, $form_id) {
     $form['submission']['maxlength_js'] = array(
       '#type' => 'textfield',
       '#title' => 'Maxlength JS',
-      '#description' => t('The maximum length of the field in characters. Can be maximum 255 characters.'),   
+      '#description' => t('The maximum length of the field in characters. Can be maximum 255 characters.'),
       '#default_value' => variable_get('maxlength_js_' . $form['#node_type']->type, ''),
       '#element_validate' => array('maxlength_node_title_validate'),
     );
@@ -220,18 +263,18 @@ function maxlength_form_node_type_form_alter(&$form, &$form_state, $form_id) {
       '#title' => t('Count down message'),
       '#default_value' =>  variable_get('maxlength_js_label_' . $form['#node_type']->type, MAXLENGTH_DEFAULT_JS_LABEL),
       '#description' => t('The text used in the Javascript message under the input, where "@limit", "@remaining" and "@count" are replaced by the appropriate numbers.'),
-    ); 
+    );
   }
 }
 
 /**
  * Checks if the title field of the node is not set to more then 255 chars, because Drupal Core cannot handle this
  */
-function maxlength_node_title_validate($element, &$form_state, $form) { 
+function maxlength_node_title_validate($element, &$form_state, $form) {
    if (!empty($element['#value']) && !is_numeric($element['#value'])) {
      form_error($element, t('This field needs to be numeric'));
-   } 
+   }
    if (!empty($element['#value']) && is_numeric($element['#value']) && $element['#value'] > 255) {
      form_error($element, t('Note titles can be maximum 255 characters long.'));
-   }   
+   }
 }
