TRUE, '#autocomplete_path' => FALSE, '#process' => array( 'racetime_form_process', ), '#theme' => 'textfield', '#theme_wrappers' => array( 'form_element', ), '#maxlength' => 8, '#number_decimals' => 2, '#title_display' => 'before', ); return $type; } /** * Implements hook_form_process(). */ function racetime_form_process($element) { $element['#attached']['js'][] = drupal_get_path('module', 'racetime') . '/format.js'; $num_decimals = $element['#number_decimals']; $element['#attributes'] = array( "onchange" => array( 'formatTimeField(this,' . $num_decimals . ')', ), ); return $element; } /** * Implements hook_field_info(). */ function racetime_field_info() { return array( 'racetime' => array( 'label' => t('Race Time'), 'description' => t('Time in format mm:ss.00'), 'settings' => array(), 'instance_settings' => array( 'number_decimals' => 2, ), 'default_widget' => 'racetime_default_widget', 'default_formatter' => 'racetime_default_formatter', ), ); } /** * Implements hook_field_instance_settings_form(). */ function racetime_field_instance_settings_form($field, $instance) { return array( 'number_decimals' => array( '#type' => 'select', '#options' => array(1=>1,2=>2,3=>3), '#title' => t('Number of decimals'), '#default_value' => $instance['settings']['number_decimals'], '#description' => t('The number of decimal places to use. Can be 1, 2 or 3'), ), ); } /** * Implements hook_field_widget_info(). */ function racetime_field_widget_info() { return array( 'racetime_default_widget' => array( 'label' => t('Racetime Field'), 'field types' => array( 'racetime', ), ), ); } /** * Implements hook_field_is_empty(). */ function racetime_field_is_empty($item, $field) { return empty($item['time']); } /** * Implements hook_field_widget_form(). */ function racetime_field_widget_form(& $form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $value = isset($items[$delta]['time']) ? $items[$delta]['time'] : ''; $num_decimals = $instance['settings']['number_decimals']; $widget = $element; $widget['#delta'] = $delta; $widget += array( '#type' => 'textfield', '#default_value' => $value, '#size' => 8, '#maxlength' => 15, '#number_decimals' => $num_decimals, '#value_callback' => '_racetime_widget_value_callback', '#attributes' => array( "onchange" => array( 'formatTimeField(this,' . $num_decimals . ')', ), ), ); if (!isset ($widget['description']) || !strlen($widget['description'])) { $widget['#description'] = t('Enter the race time here. You can enter the time with our without colons and periods. However, the easiest method for entering times is without punctuation. When you click or tab off this field, the field will automatically format the time with the correct punctuation. For example, if you enter 11547, the field will be formatted as 1:15.47.'); } if (!isset ($widget['#process'])) { $widget['#process'] = array(); } if (!in_array('_racetime_widget_process_callback', $widget['#process'])) { $widget['#process'][] = '_racetime_widget_process_callback'; } $element['time'] = $widget; $element['#attached']['js'][] = drupal_get_path('module', 'racetime') . '/format.js'; return $element; } /** * Implements hook_field_formatter_info(). */ function racetime_field_formatter_info() { return array( 'racetime_default_formatter' => array( 'label' => t('Racetime'), 'description' => 'Format a value as a racing time: e.g. 1:15.54', 'field types' => array( 'racetime', ), 'settings' => array( 'number_decimals' => 2, ), ), ); } /** * Implements hook_field_formatter_settings_summary(). */ function racetime_field_formatter_settings_summary($field, $instance, $view_mode) { return ""; } /** * Implements hook_field_formatter_settings_form(). */ function racetime_field_formatter_settings_form($field, $instance, $view_mode, $form, & $form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $element = array(); if ($display['type'] == 'racetime_default_formatter') { $element['number_decimals'] = array( '#type' => 'select', '#title' => t('Number of decimals'), '#options' => array(1=>1,2=>2,3=>3), '#description' => t('The number of decimals to use. Can be 1, 2 or 3.'), '#default_value' => $settings['number_decimals'], '#required' => TRUE, ); } return $element; } /** * Implements hook_help(). */ function racetime_help($path, $arg) { switch ($path) { case "admin/help#racetime": $helpfile = drupal_get_path('module', 'racetime') . '/README.txt'; $text = '
' . file_get_contents($helpfile) . '
'; return $text; } } /** * Implements hook_field_formatter_view(). */ function racetime_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); if ($display['type'] == 'racetime_default_formatter') { foreach ($items as $delta => $item) { $element[$delta]['#theme'] = 'racetime'; $element[$delta]['#time'] = $item['time']; $element[$delta]['#number_decimals'] = $instance['settings']['number_decimals']; } } return $element; } /** * Implements hook_theme(). */ function racetime_theme($existing, $type, $theme, $path) { return array( 'racetime' => array( 'variables' => array( 'time' => '', 'number_decimals' => 2, ), ), ); } /** * Theme racetime. */ function theme_racetime($variables) { $html = ''; $html .= _racetime_integer_to_formatted($variables['time'], $variables['number_decimals']); $html .= ''; return $html; } /** * Function to convert a string to integer. * * Valid formats could be 1:25.25 (minutes:seconds.hundreths) or * 34.54 (seconds.hundredths). Time can also have just tenths or * thousands (i.e. 1:25.2 or 1:25.253) * * @param string $str * The time in string format (i.e. 1:25.25). * @param int $num_decimals * The number of decimals the passed time has. * * @return int * The time converted to int format (i.e. 8585) */ function _racetime_string_to_int($str, $num_decimals = 2) { // Split the string by colons, first. $parts = explode(":", $str); $num_parts = count($parts); $hours = 0; $minutes = 0; $seconds = 0; if ($num_parts == 3) { $hours = $parts[0]; $minutes = $parts[1]; $seconds = $parts[2]; } elseif ($num_parts == 2) { $minutes = $parts[0]; $seconds = $parts[1]; } else { $seconds = $parts[0]; } // Convert hours and minutes to seconds. $sec_hours = $hours * 3600; $sec_minutes = $minutes * 60; // Add all together to get the total number of seconds. $seconds = $sec_hours + $sec_minutes + $seconds; // Now convert the seconds to an integer value // here we multiple seconds by 10 to the power of number of decimals. // if the user wants one decimal, we'd be expecting a value like // 1:54.3, in which case we'd have a seconds value of 114.3. 10^1 is 10, // and we'd be left with an integer of 1143. For the default of two, // we would expect a value of 1:54.34, which would give us 114.34 * 10^2 or // 114.34 * 100 = 11434. $seconds_int = $seconds * pow(10, $num_decimals); return $seconds_int; } /** * Function to convert an integer value to a time. * * @param int $seconds * The time in int format (i.e. 8525 for 1:25.25). * @param int $num_decimals * The number of decimals the returned time will have. * * @return string * The time in string format */ function _racetime_integer_to_formatted($seconds, $num_decimals = 2) { if ($num_decimals === '') { $num_decimals = 2; } // First convert the integer value to seconds. $sec = $seconds / pow(10, $num_decimals); if ($sec < 60) { return number_format($sec, $num_decimals); } else { $hours_str = ''; // Get number of minutes. $minutes = floor($sec / 60); $seconds_str = $sec - ($minutes * 60); // If seconds is less then 10, then add a leading 0. if ($seconds_str < 10) { $seconds_str = 0 . number_format($seconds_str, $num_decimals); } else { $seconds_str = number_format($seconds_str, $num_decimals); } // If the number of minutes is greater than 60, then convert. // minutes to hours and minutes. if ($minutes > 60) { $hours = floor($minutes / 60); $minutes_str = $minutes - ($hours * 60); if ($minutes_str < 10) { $minutes_str = 0 . $minutes_str; } $hours_str = $hours . ':'; } else { $minutes_str = $minutes; } $time_string = $hours_str . $minutes_str . ":" . $seconds_str; return $time_string; } } /** * Widget helper to save input values as seconds. */ function _racetime_widget_value_callback($element, $input = FALSE) { if ($input) { return _racetime_string_to_int($input, $element['#number_decimals']); } } /** * Widget helper to present seconds as readable formatted string. */ function _racetime_widget_process_callback($element, $form_state) { if (!isset ($element['#value'])) { $element['#value'] = ''; } $element['#value'] = _racetime_integer_to_formatted($element['#value'], $element['#number_decimals']); return $element; }