diff --git a/i18n_field/i18n_field.module b/i18n_field/i18n_field.module
index 599041a..f39a6a7 100644
--- a/i18n_field/i18n_field.module
+++ b/i18n_field/i18n_field.module
@@ -163,77 +163,91 @@ function i18n_field_field_formatter_view($entity_type, $entity, $field, $instanc
   return $element;
 }
 
-/**
- * Implements hook_field_widget_properties_alter().
- *
- * This is called for the entity edit form and for the fields edit form
- */
-function i18n_field_field_widget_properties_alter(&$widget, $context) {
-  // Skip the node type edit fields by checking for existing entity
-  if (!empty($context['entity']) && !empty($widget['module']) && function_exists($function = $widget['module'] . '_field_widget_form')) {
-    $widget['module'] = 'i18n_field';
-    $widget['i18n_field_callbacks'][] = $function;
-  }
-}
 
 /**
- * Field API callback to rewrite field element
+ * Implements hook_field_widget_form_alter().
  *
  * Translate:
  * - Title (label)
  * - Description (help)
  * - Default value
  * - List options
- * @see field_default_form()
  */
-function i18n_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+function i18n_field_field_widget_form_alter(&$element, &$form_state, $context) {
   global $language;
+
+  // Skip the node type edit fields by checking for existing entity
+  if (empty($element['#entity'])) {
+    return;
+  }
+
+  // Skip if we are missing any of the parameters
+  if (empty($context['field']) || empty($context['instance']) || empty($context['langcode'])) {
+    return;
+  }
+  $field = $context['field'];
+  $instance = $context['instance'];
+  $langcode = $context['langcode'];
+
   // The field language may affect some variables (default) but not others (description will be in current page language)
   $i18n_langcode = empty($element['#language']) || $element['#language'] == LANGUAGE_NONE ? $language->language : $element['#language'];
+
   // Translate instance to current page language and set to form_state
   // so it will be used for validation messages later.
   $instance_current = i18n_string_object_translate('field_instance', $instance);
   if (isset($form_state['field'][$instance['field_name']][$langcode]['instance'])) {
     $form_state['field'][$instance['field_name']][$langcode]['instance'] = $instance_current;
   }
-  // Now replace some form elements one at a time.
-  $delta = $element['#delta'];
-  // Translate field title if set
-  if (!empty($instance_current['label']) && !empty($element['#title'])) {
-    $element['#title'] = $instance_current['label'];
-  }
-  // Translate field description if set
-  if (!empty($instance_current['description']) && !empty($element['#description'])) {
-    $element['#description'] = $instance_current['description'];
-  }
-  // Translate default value if exists and the current value is the default
-  if (($translate = i18n_field_type_info($field['type'], 'translate_default')) && !empty($instance['default_value'][$delta]['value']) && !empty($items[$delta]['value']) && $instance['default_value'][$delta]['value'] === $items[$delta]['value']) {
-    $items[$delta]['value'] = $translate($instance, $items[$delta]['value'], $i18n_langcode);
+
+  // Translate field title if set and it is the default one.
+  // When cardinality is 1, $element['value'] is used instead.
+  if (!empty($instance_current['label']) && $instance_current['label'] != $instance['label']) {
+    if (!empty($element['#title']) && $element['#title'] == $instance['label']) {
+      $element['#title'] = $instance_current['label'];
+    }
+    if (isset($element['value']) && !empty($element['value']['#title']) && $element['value']['#title'] == $instance['label']) {
+      $element['value']['#title'] = $instance_current['label'];
+    }
   }
 
-  // Redirect through original module_field_widget_form()
-  if (!empty($instance['widget']['i18n_field_callbacks'])) {
-    foreach ($instance['widget']['i18n_field_callbacks'] as $function) {
-      $element = $function($form, $form_state, $field, $instance_current, $langcode, $items, $delta, $element);
+  // Translate field description if set and it is the default one.
+  // When cardinality is 1, $element['value'] is used instead.
+  if (!empty($instance_current['description']) && $instance_current['description'] != $instance['description']) {
+    if (!empty($element['#description']) && $element['#description'] == $instance['description']) {
+      $element['#description'] = $instance_current['description'];
+    }
+    if (isset($element['value']) && !empty($element['value']['#description']) && $element['value']['#description'] == $instance['description']) {
+      $element['value']['#description'] = $instance_current['description'];
     }
   }
+
   // Translate list options
-  if (($translate = i18n_field_type_info($field['type'], 'translate_options')) && !empty($field['settings']['allowed_values'])) {
+  if (!empty($element['#options']) && ($translate = i18n_field_type_info($field['type'], 'translate_options')) && !empty($field['settings']['allowed_values'])) {
     $element['#options'] = $translate($field, $i18n_langcode);
-    if ($element['#properties']['empty_option']) {
+    if (isset($element['#properties']) && !empty($element['#properties']['empty_option'])) {
       $label = theme('options_none', array('instance' => $instance, 'option' => $element['#properties']['empty_option']));
       $element['#options'] = array('_none' => $label) + $element['#options'];
-    }
-    if ($field['type'] == 'list_boolean' && !empty($element['#on_value'])) {
-      $on_value = $element['#on_value'];
-      $element['#title'] = $element['#options'][$on_value];
-
-      if ($instance['widget']['settings']['display_label']) {
-        $element['#title'] = $instance_current['label'];
+      // For some elements, change title to new translated option
+      if (!empty($element['#title']) && $field['type'] == 'list_boolean' && !empty($element['#on_value'])) {
+        $on_value = $element['#on_value'];
+        $element['#title'] = $element['#options'][$on_value];
       }
     }
   }
-  return $element;
+
+  // Check for more parameters, skip this part if missing.
+  if (!isset($context['delta']) || !isset($context['items'])) {
+    return;
+  }
+  $delta = $context['delta'];
+  $items = $context['items'];
+
+  // Translate default value if exists and the current value is the default
+  if (isset($element['value']['#default_value']) && ($translate = i18n_field_type_info($field['type'], 'translate_default')) &&
+      !empty($instance['default_value'][$delta]['value']) && !empty($items[$delta]['value']) &&
+      $instance['default_value'][$delta]['value'] === $items[$delta]['value']) {
+    $element['value']['#default_value'] = $translate($instance, $items[$delta]['value'], $i18n_langcode);
+  }
 }
 
 /**
