diff --git a/office_hours.elements.inc b/office_hours.elements.inc
index b859ab9..4c71651 100644
--- a/office_hours.elements.inc
+++ b/office_hours.elements.inc
@@ -14,13 +14,8 @@
  * note that $element['#value'] is already set.
  */
 function _office_hours_slot_process($element, &$form_state, $form) {
-  $day = $element['#weight'];
-  $day = (int)($day / 2); // Keys are 0+1 for sunday, 2+3 for monday, etc. Each day may have normal hours + extra hours.
-
-  $days = date_week_days_untranslated();
-
-  if (!($element['#weight'] & 1)) { //first cell
-    $element['#prefix'] = '<div class="office-hours-slot"><div class="dayname">' . t($days[$day]) . '</div>';
+  if ($element['#daydelta'] == 0) { //first cell
+    $element['#prefix'] = '<div class="office-hours-slot"><div class="dayname">' . $element['#dayname'] . '</div>';
   }
   elseif ($element['#addhrs']) {  // second cell, we're supposed to show the 'add hours link'
     $link = l(t('Add more hours'), '', array('attributes' => array('class' => 'oh-add-more-link'))) . '<div class="office-hours-slot" style = "display:none;">' . '<div class="dayname">' . t('and') . '</div>';
@@ -31,9 +26,14 @@ function _office_hours_slot_process($element, &$form_state, $form) {
     $element['#value']['starthours'] = '';
   }
   $element['#suffix'] = '</div>';
+
   $element['day'] = array(
     '#type' => 'value',
-    '#value' => $element['#weight'],
+    '#value' => $element['#day'],
+  );
+  $element['daydelta'] = array(
+    '#type' => 'value',
+    '#value' => $element['#daydelta'],
   );
 
   $settings = array(
@@ -42,7 +42,6 @@ function _office_hours_slot_process($element, &$form_state, $form) {
     '#hours' => $element['#hours'],
     '#minutes' => $element['#minutes'],
   );
-
   $element['starthours'] = array(
     '#type' => 'office_hours_select',
     '#prefix' => ' ' . t('from'),
@@ -58,6 +57,31 @@ function _office_hours_slot_process($element, &$form_state, $form) {
 }
 
 /**
+ * Implements validate callback for office_hours_slot.
+ *
+ * which defines the 'office_hours' (day) and 'office_hours_select' (hour) elements.
+ *
+ * You can find the value in $element['#value'], but better in $form_state['values'],
+ * which is set in _office_hours_select_validate().
+ */
+function _office_hours_slot_validate($element, &$form_state) {
+  $item = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
+
+  $error_text = '';
+  if (!empty($item['starthours']) xor !empty($item['endhours']) ) {
+    $error_text = t('Both Opening hours and Closing hours must be set.');
+  }
+  elseif ( ($element['#valhrs']) && ($item['starthours'] > $item['endhours']) ) {
+    $error_text = t('Closing hours are earlier than opening hours.');
+  }
+
+  if ($error_text) {
+    $error_text  = $element['#dayname'] . ': ' . $error_text;
+    form_error($element, check_plain($error_text));
+  }
+}
+
+/**
  * Value callback for office_hours_select element.
  */
 function _office_hours_select_value_callback($element, $input = FALSE, &$form_state) {
@@ -134,30 +158,3 @@ function _office_hours_select_validate($element, &$form_state) {
     form_error($element, t('Minutes should be between 0 and 59.'));
   }
 }
-
-/**
- * Implements a callback for _office_hours_elements()
- * which defines the 'office_hours' (day) and 'office_hours_select' (hour) elements.
- *
- * You can find the value in $element['#value'], but better in $form_state['values'],
- * which is set in _office_hours_select_validate().
- */
-function _office_hours_slot_validate($element, &$form_state) {
-  $delta = $element['#delta'];
-  $item = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
-
-  $error_text = '';
-  if (!empty($item['starthours']) xor !empty($item['endhours']) ) {
-    $error_text = t('Both Opening hours and Closing hours must be set.');
-  }
-  elseif ( ($element['#valhrs']) && ($item['starthours'] > $item['endhours']) ) {
-    $error_text = t('Closing hours are earlier than opening hours.');
-  }
-
-  if ($error_text) {
-    $weekdays = date_week_days(TRUE);
-    $error_text  = $weekdays[$delta / 2] . ': ' . $error_text;
-
-    form_error($element, check_plain($error_text));
-  }
-}
diff --git a/office_hours.module b/office_hours.module
index d3b90f6..f7c82c3 100644
--- a/office_hours.module
+++ b/office_hours.module
@@ -18,31 +18,22 @@ function office_hours_theme($existing, $type, $theme, $path) {
   $themes = array(
     'office_hours_formatter_default' => $base + array('render element' => 'element'),
     'office_hours_time_range' => $base + array('render element' => 'element'),
+    'office_hours_week' => $base + array('render element' => 'element'),
     'office_hours_slot' => $base + array('render element' => 'element'),
-    'field_multiple_value_form' => $base + array('render element' => 'element'),
     'office_hours_select' => $base + array('render element' => 'element'),
   );
   return $themes;
 }
 
-function office_hours_theme_registry_alter(&$theme_registry) {
-  $theme_registry['field_multiple_value_form']['function'] = 'office_hours_field_multiple_value_form';
-}
-
 /**
  * Implements hook_form_FORM_ID_alter().
  */
-function office_hours_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
+function office_hours_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
   if ($form['#field']['type'] == 'office_hours') {
-    $description = t('14 hours slots is the current default. See below for limiting it.');
-    $description .= '<br/><strong>' . t('Warning! Changing this setting after data has been created could result in the loss of data!') . '</strong>';
-    $form['field']['cardinality'] = array(
-      '#type' => 'select',
-      '#title' => t('Number of values'),
-      '#options' => drupal_map_assoc(array(14)),
-      '#default_value' => 14,
-      '#description' => $description,
-    );
+   $form['field']['cardinality']['#options'] = drupal_map_assoc(array(14));
+   $form['field']['cardinality']['#value'] = 14;
+   $form['field']['cardinality']['#disabled'] = TRUE;
+   $form['field']['cardinality']['#description'] = t('This field requires 14 values: 2 possible slots for each day of week.');
   }
 }
 
@@ -118,6 +109,23 @@ function office_hours_property_info_callback(&$info, $entity_type, $field, $inst
 }
 
 /**
+ * Implements hook_field_presave().
+ *
+ * Convert day key to a backend value:
+ *  - sunday as first day of week.
+ *  - 14 days based value.
+ */
+function office_hours_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
+  $first_day = variable_get('date_first_day', 0);
+  foreach ($items as $delta => $item) {
+    // 1. Convert day to sunday based.
+    $day = ($item['day'] + $first_day) % 7;
+    // 2. Convert to 14 days base.
+    $items[$delta]['day'] = ($day * 2) + $item['daydelta'];
+  }
+}
+
+/**
  * Implements hook_field_settings_form().
  *
  * Handle the parameters for a field.
@@ -568,7 +576,7 @@ function office_hours_field_widget_info() {
       'label' => t('Office Hours'),
       'field types' => array('office_hours'),
       'behaviors' => array(
-        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
         'default value' => FIELD_BEHAVIOR_DEFAULT,
       ),
     ),
@@ -579,13 +587,7 @@ function office_hours_field_widget_info() {
  * Implements hook_field_widget_form().
  */
 function office_hours_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  if ($delta == 0) {
-    // This function is called 14 times. We only need to include files once, not 14 times.
-    // @TODO: perhaps it is even better to include it in office_hours_field_multiple_value_form(), which is only called once per page.
-    drupal_add_js(drupal_get_path('module', 'office_hours') . "/office_hours.js", 'file');
-  }
-
-  $items = _office_hours_arrange_items($items);
+  drupal_add_js(drupal_get_path('module', 'office_hours') . "/office_hours.js", 'file');
 
   // Use Date API to obtain valid minutes.
   $minutes = date_minutes('i', FALSE, $field['settings']['granularity']);
@@ -598,26 +600,50 @@ function office_hours_field_widget_form(&$form, &$form_state, $field, $instance,
     $end = $field['settings']['limitend'];
   }
   else {
-    $end = ($field['settings']['hoursformat'] == 1) ? 12 : 24;
+    $end =($field['settings']['hoursformat'] == 1) ? 12 : 24;
   }
   $hours = array('' => '');
-  for ($i=$start;$i<=$end;$i++) {
+  for ($i = $start; $i < $end; $i++) {
     $hours[$i] = $i < 10 && ($field['settings']['hoursformat'] == 0) ? "0$i" : $i;
   }
 
+  // Prepare generic element.
   $element += array(
     '#type' => 'office_hours_slot',
-    '#default_value' => isset($items[$delta]['starthours']) ? $items[$delta] : NULL,
     '#hours' => drupal_map_assoc($hours),
     '#minutes' => drupal_map_assoc($minutes),
+    '#hoursformat' => $field['settings']['hoursformat'],
+    '#addhrs' => $field['settings']['addhrs'],
+    '#valhrs' => $field['settings']['valhrs'],
   );
 
-  $field_settings = array('hoursformat', 'addhrs', 'valhrs');
-  foreach ($field_settings as $key) {
-    $element['#' . $key] = $field['settings'][$key];
+  // Build elements.
+  $days = date_week_days_ordered(date_week_days(TRUE));
+
+  //  @todo convert the formatter to work with this representation for $items and move this call to hook_field_load().
+  $items = office_hours_arrange_field_items($items);
+  $elements = array();
+  for ($day = 0; $day < 7; $day++) {
+    for ($daydelta = 0; $daydelta < 2; $daydelta ++) {
+      $element['#default_value'] = isset($items[$day][$daydelta]['starthours']) ? $items[$day][$daydelta] : NULL;
+      $element['#day'] = $day;
+      $element['#daydelta'] = $daydelta;
+      $element['#dayname'] = $days[$day];
+      $elements[] = $element;
+    }
   }
 
-  return $element;
+  // Build multi element widget.
+  $parents = $form['#parents'];
+  $field_elements = array(
+    '#theme' => 'office_hours_week',
+    '#field_name' => $field['field_name'],
+    '#title' => check_plain($instance['label']),
+    '#required' => $instance['required'],
+    '#description' => field_filter_xss($instance['description']),
+  ) + $elements;
+
+  return $field_elements;
 }
 
 /**
@@ -630,6 +656,28 @@ function office_hours_field_widget_error($element, $error, $form, &$form_state)
 }
 
 /**
+ * Arrange items indexed by day and daydelta.
+ *
+ * @param $items array of field values with 'day' key based on 14 possible
+ *    values, 2 for each day (0,1 = Sunday; 2,3 = Monday; 4,5 = Tuesday ...)
+ *
+ * @return two level array. First level are day numbers, ordered in accordance
+ *   with first day of week. Second level contains field values arranged by
+ *   daydelta.
+ */
+function office_hours_arrange_field_items($items) {
+  $values = array_fill_keys(array(0, 1, 2, 3, 4, 5, 6), array());
+  foreach ($items as $item) {
+    $day = (int)($item['day'] / 2);
+    $daydelta = $item['day'] % 2;
+    $values[$day][$daydelta] = $item;
+  }
+
+  return date_week_days_ordered($values);
+}
+
+
+/**
  * Implements FAPI hook_element_info().
  */
 function office_hours_element_info() {
@@ -672,29 +720,6 @@ function _office_hours_show_ampm($hours) {
   return $hours;
 }
 
-function _office_hours_arrange_items($items) {
-  $days = array();
-  foreach ($items as $item) {
-    $days[$item['day']] = $item;
-  }
-  return $days;
-}
-
-function _office_hours_arrange_day($items) {
-  $first = variable_get('date_first_day', 0);
-  while ($first > 0) :
-    $shifted = array_shift($items);
-    $items[] = $shifted;
-    if (isset($items[13])) {
-      $shifted = array_shift($items);
-      $items[] = $shifted;
-    }
-    $first--;
-  endwhile;
-
-  return $items;
-}
-
 /**
  * Helper function for conversion of clock format.
  */
@@ -738,33 +763,6 @@ function _office_hours_mil_to_tf($time = '') {
   return $hour . ':' . $min;
 }
 
-function _office_hours_set_weight($items) {
-  $sorted = array();
-  foreach (range(0, 13) as $value) {
-    $sorted[$value] = NULL;
-  }
-  foreach ($items as $key => $item) {
-    if (!is_null($item['day'])) {
-      $sortkey= (int)$item['day'];
-      $sortkey = $sortkey * 2;
-      if (!empty($sorted[$sortkey]) && is_array($sorted[$sortkey])) {
-        $sorted[$sortkey+1] = $item;
-      }
-      else {
-        $sorted[$sortkey] = $item;
-      }
-    }
-  }
-  //now fill the empty spaces with null values
-  foreach (range(0, 13) as $value) {
-    if (empty($sorted[$value]) || !is_array($sorted[$value])) {
-      $day = ($value == 0) ? 0 : (($value & 1) ? ( $value - 1) / 2 : $value / 2 );
-      $sorted[$value] = array('starthours' => 0000, 'endhours' => 0000, 'day' => (int)$day);
-    }
-  }
-  return $sorted;
-}
-
 function _office_hours_field_formatter_defaults($settings = array()) {
 
   // Assure all values are set. Append with missing values.
diff --git a/office_hours.theme.inc b/office_hours.theme.inc
index 101d7ea..241f5f6 100644
--- a/office_hours.theme.inc
+++ b/office_hours.theme.inc
@@ -123,83 +123,32 @@ function theme_office_hours_select($vars) {
 }
 
 /**
- * copied from content module's theme_content_multiple_values- we're taking out the draggable feature.
- *
- * Theme the hour table form
- *
+ * Theme function for office_hours widget.
  */
-function office_hours_field_multiple_value_form($variables) {
-  // Use Field's theme function for non-office hours fields.
-  if (empty($variables['element'][0]['#type']) || $variables['element'][0]['#type'] != 'office_hours_slot') {
-    return theme_field_multiple_value_form($variables);
-  }
-
-  // The following is a copy from standard theme_field_multiple_value_form()
-  // http://api.drupal.org/api/drupal/modules%21field%21field.form.inc/function/theme_field_multiple_value_form/7
-  // Modifications for the Office Hours form are commented out.
-  // We've removed the columns 'order' and 'drag&drop', and do not add the drap&drop JS.
-
+function theme_office_hours_week($variables) {
   $element = $variables['element'];
   $output = '';
-  if ($element['#cardinality'] > 1 || $element['#cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
-    $table_id = drupal_html_id($element['#field_name'] . '_values');
-    $order_class = $element['#field_name'] . '-delta-order';
-    $required = !empty($element['#required']) ? theme('form_required_marker', $variables) : '';
-
-    $header = array(
-      array(
-        'data' => '<label>' . t('!title: !required', array('!title' => $element['#title'], '!required' => $required)) . "</label>",
-        'colspan' => 2,
-        'class' => array('field-label'),
-      ),
-//      t('Order'),
-    );
-    $rows = array();
-
-    // Sort items according to '_weight' (needed when the form comes back after
-    // preview or failed validation)
-    $items = array();
-    foreach (element_children($element) as $key) {
-      if ($key === 'add_more') {
-        $add_more_button = &$element[$key];
-      }
-      else {
-        $items[] = &$element[$key];
-      }
-    }
-    usort($items, '_field_sort_items_value_helper');
-
-    $items = _office_hours_arrange_day($items); //this calls the function that arranges the first day of the week.
-
-    // Add the items as table rows.
-    foreach ($items as $key => $item) {
-      $item['_weight']['#attributes']['class'] = array($order_class);
-      $delta_element = drupal_render($item['_weight']);
-      $cells = array(
-//        array('data' => '', 'class' => array('field-multiple-drag')),
-        drupal_render($item),
-//        array('data' => $delta_element, 'class' => array('delta-order')),
-      );
-      $rows[] = array(
-        'data' => $cells,
-//        'class' => array('draggable'),
-      );
-    }
-
-    $output = '<div class="form-item">';
-    $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => $table_id, 'class' => array('field-multiple-table'))));
-    $output .= $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : '';
-    $output .= '<div class="clearfix">' . drupal_render($add_more_button) . '</div>';
-    $output .= '</div>';
+  $table_id = drupal_html_id($element['#field_name'] . '_values');
+  $required = !empty($element['#required']) ? theme('form_required_marker', $variables) : '';
 
-//    drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
-  }
-  else {
-    foreach (element_children($element) as $key) {
-      $output .= drupal_render($element[$key]);
-    }
+  $header = array(
+    array(
+      'data' => '<label>' . t('!title: !required', array('!title' => $element['#title'], '!required' => $required)) . "</label>",
+      'class' => array('field-label'),
+    ),
+  );
+  $rows = array();
+  foreach (element_children($element) as $key) {
+    $rows[] = array(
+      drupal_render($element[$key])
+    );
   }
 
+  $output = '<div class="form-item">';
+  $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => $table_id, 'class' => array('field-multiple-table'))));
+  $output .= $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : '';
+  $output .= '</div>';
+
   return $output;
 }
 
