diff --git maxlength.inc maxlength.inc
index 790a7a6..aea3ad4 100644
--- maxlength.inc
+++ maxlength.inc
@@ -7,21 +7,20 @@
 function _maxlength_content_form_alter(&$form, &$form_state, $form_id) {
   $type = $form['type']['#value'];
   // update the title as needed
-  if (isset($form['title'])) {
-    $form['title']['#after_build'] = array('_maxlength_format_element');
-    $form['title']['#max_length_properties'] = array($form['title']['#default_value'], 'title', 'title', $type);
+  if (isset($form['title']) && ($values = _maxlength_get_values('title', $type))) {
+    $form['title']['#max_length_properties'] = $values;
   }
 
   // Update the body as needed
-  if (isset($form['body_field']['body'])) {
-    $form['body_field']['body']['#after_build'] = array('_maxlength_format_element');
-    $form['body_field']['body']['#max_length_properties'] = array($form['body_field']['body']['#default_value'], 'body', 'body', $type);
+  if (isset($form['body_field']['body']) && ($values = _maxlength_get_values('title', $type))) {
+    $form['body_field']['body']['#max_length_properties'] = $values;
   }
 
 
   if (module_exists('content')) {
     // Get a list of all the CCK fields for this content type
-    $list = array_keys(content_fields(NULL, $type));
+    $info = content_types($type);
+    $list = array_keys($info['fields']);
 
     // Update CCK fields as needed
     foreach ($list as $field) {
@@ -29,8 +28,9 @@ function _maxlength_content_form_alter(&$form, &$form_state, $form_id) {
         foreach (element_children($form[$field]) as $key) {
           // For example #markup doens't have a #type element.
           if (!empty($form[$field][$key]['#type']) && _maxlength_is_supported_widget($form[$field][$key]['#type'])) {
-            $form[$field][$key]['#after_build'] = array('_maxlength_format_element');
-            $form[$field][$key]['#max_length_properties'] = array($form[$field][$key]['#default_value']['value'], $field, str_replace('_', '-', $field) .'-'. $key .'-value', $type);
+            if ($values = _maxlength_get_values($field, $type)) {
+              $form[$field][$key]['#max_length_properties'] = $values;
+            }
           }
         }
       }
@@ -77,20 +77,20 @@ function _maxlength_content_type_form_alter(&$form, &$form_state, $form_id) {
       '#field_suffix' => t('characters'),
       '#return_value' => 1,
       '#size' => 4,
-      '#default_value' => variable_get('maxlength_' . $label .'_'. $type, ''),
+      '#default_value' => variable_get('maxlength_' . $label .'_'. $type, MAXLENGTH_DEFAULT_LENGTH),
       '#description' => t('Maximum number of characters allowed for the !type field of this content type. Leave blank for an unlimited size.', array('!type' => $label)) .'<br/>'.
       '<b>'. t('Please remember, it counts all characters, including HTML, so may not work as expected with rich text editors e.g. FCKeditor / tinyMCE.') .'</b>',
-        );
+    );
     $form['submission']['maxlength_' . $label]['maxlength_' . $label .'_js'] = array(
       '#type' => 'checkbox',
       '#title' => t('Enable remaining characters countdown for the !label', array('!label' => ucwords($label))),
-      '#default_value' => variable_get('maxlength_' . $label .'_js_'. $type, '0'),
+      '#default_value' => variable_get('maxlength_' . $label .'_js_'. $type, MAXLENGTH_DEFAULT_USE_JS),
       '#description' => t('This will enable a Javascript based count down, as well as the client side validation for the !type field of this content type. If no limit set this is ignored.', array('!type' => $label)),
     );
     $form['submission']['maxlength_' . $label]['maxlength_' . $label .'_text'] = array(
       '#type' => 'textarea',
       '#title' => t('!label count down message', array('!label' => ucwords($label))),
-      '#default_value' => variable_get('maxlength_' . $label .'_text_'. $type, 'Content limited to !limit characters, remaining: <strong>!remaining</strong>'),
+      '#default_value' => variable_get('maxlength_' . $label .'_text_'. $type, MAXLENGTH_DEFAULT_TEXT),
       '#description' => t('The text used in the Javascript message under the !type input, where "!limit", "!remaining" and "!count" are replaced by the appropriate numbers.', array('!type' => $label)),
     );
   }
@@ -101,19 +101,19 @@ function _maxlength_cck_form_alter(&$form, &$form_state, $form_id) {
     '#type' => 'textfield',
     '#title' => t('Maxlength limit'),
     '#description' => t('If you want to use maxlength interactive counter and validation on a CCK field, let\'s leave the normal CCK length unlimited and set this value to the desired one to let maxlength count the real length of the text'),
-    '#maxlength' => 6,
-    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'], '0'),
+    '#max_length_properties' => 6,
+    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'], MAXLENGTH_DEFAULT_LENGTH),
   );
   $form['field']['maxlength_' . $form['field_name']['#value'] .'_js'] = array(
     '#type' => 'checkbox',
     '#title' => t('Enable remaining characters countdown for this field'),
-    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'] .'_js', '0'),
+    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'] .'_js', MAXLENGTH_DEFAULT_USE_JS),
     '#description' => t('This will enable a Javascript based count down, as well as the client side validation for this field. If no limit set this is ignored.'),
   );
   $form['field']['maxlength_' . $form['field_name']['#value'] .'_text'] = array(
     '#type' => 'textarea',
     '#title' => t('Count down message'),
-    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'] .'_text', 'Content limited to !limit characters, remaining: <strong>!remaining</strong>'),
+    '#default_value' => variable_get('maxlength_' . $form['field_name']['#value'] .'_text', MAXLENGTH_DEFAULT_TEXT),
     '#description' => t('The text used in the Javascript message under the input, where "!limit", "!remaining" and "!count" are replaced by the appropriate numbers.'),
   );
   $form['#submit'][] = '_maxlength_cck_form_submit';
@@ -127,19 +127,19 @@ function _maxlength_cck_form_submit($form, &$form_state) {
 }
 
 function _maxlength_get_values($field = 'body', $type = '') {
-  $values = '';
+  $values = array();
   $values['limit'] = FALSE;
 
   //CCK
   if (strpos($field, 'field_') === 0) {
-    $values['limit'] = variable_get('maxlength_' . $field, FALSE);
-    $values['use_js'] = variable_get('maxlength_' . $field .'_js', FALSE);
-    $values['text'] = variable_get('maxlength_' . $field .'_text', FALSE);
+    $values['limit'] = variable_get('maxlength_' . $field, MAXLENGTH_DEFAULT_TEXT);
+    $values['use_js'] = variable_get('maxlength_' . $field .'_js', MAXLENGTH_DEFAULT_USE_JS);
+    $values['text'] = variable_get('maxlength_' . $field .'_text', MAXLENGTH_DEFAULT_TEXT);
   } //body and title
   elseif ($type != '') {
-    $values['limit'] = variable_get('maxlength_' . $field .'_'. $type, FALSE);
-    $values['use_js'] = variable_get('maxlength_' . $field .'_js_'. $type, FALSE);
-    $values['text'] = variable_get('maxlength_' . $field .'_text_'. $type, FALSE);
+    $values['limit'] = variable_get('maxlength_' . $field .'_'. $type, MAXLENGTH_DEFAULT_TEXT);
+    $values['use_js'] = variable_get('maxlength_' . $field .'_js_'. $type, MAXLENGTH_DEFAULT_USE_JS);
+    $values['text'] = variable_get('maxlength_' . $field .'_text_'. $type, MAXLENGTH_DEFAULT_TEXT);
   }
 
   if ($values['limit']) {
diff --git maxlength.js maxlength.js
index 81ee115..61b1eef 100644
--- maxlength.js
+++ maxlength.js
@@ -9,7 +9,7 @@ Drupal.maxLength_limit = function (field) {
     return;
   }
   var limit = Drupal.settings.maxlength[id];
-  var maxlength = $('#maxlength-' + id.substr(5));
+  var maxlength = $('#maxlength-' + id);
   maxlength.show_count = false;
   maxlength.span_remaining_count = maxlength.find('span.maxlength-counter-remaining');
   maxlength.find('span.maxlength-count', function() {
diff --git maxlength.module maxlength.module
index e780927..7492fa7 100644
--- maxlength.module
+++ maxlength.module
@@ -5,12 +5,16 @@
  *   Enables a max length countdown on node body, title and CCK textfields.
  */
 
+define('MAXLENGTH_DEFAULT_TEXT', 'Content limited to !limit characters, remaining: <strong>!remaining</strong>');
+define('MAXLENGTH_DEFAULT_USE_JS', TRUE);
+define('MAXLENGTH_DEFAULT_LENGTH', 0);
+
 /**
  * Implementation of hook_help().
  */
 function maxlength_help($path, $arg) {
   switch ($path) {
-    case 'admin/help#maxlength':
+    case 'admin/help#max_length_properties':
     case 'admin/modules#description':
       return t('Sets a maximum length for body fields and shows a counter that is updated as you type.');
       break;
@@ -21,6 +25,9 @@ function maxlength_help($path, $arg) {
  * Implementation of hook_form_alter().
  */
 function maxlength_form_alter(&$form, &$form_state, $form_id) {
+  // This is not ideal, but will allow anyone to use the #maxlength element
+  $form['#after_build'][] = 'maxlength_after_build';
+
   // Editing the content
   if ($form['#id'] == 'node-form') {
     module_load_include('inc', 'maxlength', 'maxlength');
@@ -67,43 +74,6 @@ function maxlength_remove_field_variables($field_name) {
 }
 
 /**
- * Implementation of hook_nodeapi().
- */
-function maxlength_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
-  if ($op != 'validate') {
-    return;
-  }
-  // Core fields, CCK takes care of CCK fields, no need to validate them
-  $core_fields = $fields = array('title', 'body');
-  module_load_include('inc', 'content', 'includes/content.crud');
-  if (module_exists('content')) {
-    $content_type_info = content_types($node->type);
-    $fields = array_merge($fields, array_keys($content_type_info['fields']));
-  }
-
-  foreach ($fields as $field) {
-    if (in_array($field, $core_fields)) {
-      $limit = intval(variable_get('maxlength_' . $field .'_'. $node->type, ''));
-    }
-    else {
-      $limit = intval(variable_get('maxlength_' . $field, ''));
-    }
-    if ($limit > 0) {
-      $form = $a3;
-      // line breaks can be stored 2 or more chars, breaking the count.
-      $text = is_string($node->$field) ? $node->$field : $node->{$field}[0]['value'];
-
-      $text = str_replace("\r\n", '#', $text);
-      $text = str_replace("\n", '#', $text);
-      $text = str_replace("\r", '#', $text);
-      if (drupal_strlen($text) > $limit) {
-        form_set_error($field, t('The !field field has exceeded its maximum number of characters (!limit).', array('!limit' => $limit, '!field' => $field)));
-      }
-    }
-  }
-}
-
-/**
  * Implementation of hook_node_type().
  */
 function maxlength_node_type($op, $info) {
@@ -132,28 +102,63 @@ function maxlength_node_type($op, $info) {
 }
 
 /**
+ * Finds all the elements in the form that request #checkall behaviour
+ * and respond. 
+ */
+function maxlength_after_build($element) {
+  maxlength_recursive($element);
+  return $element;
+}
+
+/**
+ * Finds all the elements in the form that request #checkall behaviour
+ * and respond. 
+ */
+function maxlength_recursive(&$elements) {
+  foreach (element_children($elements) as $key) {
+    if (isset($elements[$key]) && $elements[$key]) {
+      if (!empty($elements[$key]['#max_length_properties'])) {
+        _maxlength_format_element($elements[$key]);
+      }
+
+      maxlength_recursive($elements[$key]);
+    }
+  }
+}
+
+/**
  * Formats a form element to use maxlength value and use js.
  * It's not moved to maxlength.inc because Form API calls it even when form_alter is not called
  *
  * @arg array $element
  *   The form element which should be maxlengthed.
- * @return
- *   Maxlength-enabled form element
  *
  */
-function _maxlength_format_element($element) {
-  static $processed = array();
+function _maxlength_format_element(&$element) {
+  static $js_added = FALSE;
   module_load_include('inc', 'maxlength', 'maxlength');
-  $value = $element['#max_length_properties'][0];
-  $field = $element['#max_length_properties'][1];
-  $id = $element['#max_length_properties'][2];
-  $type = $element['#max_length_properties'][3];
 
-  $values = _maxlength_get_values($field, $type);
+  // Allow for a short hand method.
+  if (!is_array($element['#max_length_properties'])) {
+    $element['#max_length_properties'] = array(
+      'limit' => $element['#max_length_properties'],
+    );
+  }
 
-  if ($values !== FALSE && isset($values['limit']) && $values['limit'] && $values['use_js']) {
-    $path = drupal_get_path('module', 'maxlength');
-    drupal_add_js($path .'/maxlength.js');
+  $element['#max_length_properties'] += array(
+    'text' => MAXLENGTH_DEFAULT_TEXT,
+    'use_js' => MAXLENGTH_DEFAULT_USE_JS,
+    'value_key' => 'default_value',
+  );
+
+  $values = $element['#max_length_properties'];
+  if ($values['use_js']) {
+    if (empty($js_added)) {
+      $path = drupal_get_path('module', 'maxlength');
+      drupal_add_js($path . '/maxlength.js');
+      $js_added = TRUE;
+    }
+    $value = !empty($element[$values['#value_key']]) ? $element[$values['#value_key']] : '';
 
     $remaining = $values['limit'] - drupal_strlen($value);
 
@@ -167,21 +172,38 @@ function _maxlength_format_element($element) {
         'error'
       );
 
-      $element['#default_value'] = drupal_substr($element['#default_value'], 0, $values['limit']);
+      $element[$values['#value_key']] = drupal_substr($element['#default_value'], 0, $values['limit']);
       $remaining = 0;
     }
 
-    if (in_array($element['#id'], $processed) === FALSE) {
+    // Make sure #id was set
+    if (!isset($element['#id'])) {
+      $element['#id'] = form_clean_id('edit-'. implode('-', $element['#parents']));
+    }
+
+    if (empty($element['#maxlength_processed'])) {
       $js_settings = array(
         'maxlength' => array(
-          'edit-'. $id => $values['limit'],
+          $element['#id'] => $values['limit'],
         ),
       );
       drupal_add_js($js_settings, 'setting');
+      $element['#maxlength_processed'] = TRUE;
     }
-    $element['#suffix'] = '<div id="maxlength-'. $id .'"
+    $element['#suffix'] = '<div id="maxlength-'. $element['#id'] .'"
       class="maxlength-counter">' . t($values['text'], array('!limit' => $values['limit'], '!count' => '<span class="maxlength-count">' . drupal_strlen($value) .'</span>', '!remaining' => '<span class="maxlength-counter-remaining">' . $remaining . '</span>')) . '</div>';
-    $processed[] = $element['#id'];
+    $element['#element_validate'][] = 'maxlength_validate_element';
+  }
+}
+
+/**
+ * Element validate that checks the length of the text to see if it is valid.
+ */
+function maxlength_validate_element($element, &$form_state) {
+  $text = $element['#value'];
+  $text = str_replace("\r\n", '#', $text);
+  $text = str_replace(array("\n", "\r"), '#', $text);
+  if (drupal_strlen($text) > $element['#max_length_properties']['limit']) {
+    form_error($element, t('!field has exceeded its maximum number of characters (!limit).', array('!limit' => $element['#max_length_properties']['limit'], '!field' => $element['#title'])));
   }
-  return $element;
 }
