array( 'label' => t('Color Field'), 'description' => t('Field using a hexadecimal notation.'), // These settings apply to the color field field everywhere it is used. 'settings' => array( 'opacity' => FALSE, ), // These settings apply to the color field instance. 'instance_settings' => array( // Simple widget. 'default_colors' => ' #AC725E,#D06B64,#F83A22,#FA573C,#FF7537,#FFAD46 #42D692,#16A765,#7BD148,#B3DC6C,#FBE983 #92E1C0,#9FE1E7,#9FC6E7,#4986E7,#9A9CFF #B99AFF,#C2C2C2,#CABDBF,#CCA6AC,#F691B2 #CD74E6,#A47AE2', // Simple color. 'cell_width' => 10, 'cell_height' => 10, 'cell_margin' => 1, 'box_width' => 115, 'box_height' => 20, 'columns' => 16, // Spectrum. 'show_input' => FALSE, 'show_palette' => FALSE, 'palette' => '', 'show_palette_only' => TRUE, 'show_buttons' => FALSE, 'allow_empty' => FALSE, ), 'default_widget' => 'color_field_default_widget', 'default_formatter' => 'color_field_default_formatter', // Support hook_entity_property_info() from contrib "Entity API". 'property_type' => 'color_field', 'property_callbacks' => array('color_field_property_info_callback'), ), ); } /** * Additional callback to adapt the property info of link fields. * * @see entity_metadata_field_entity_property_info() */ function color_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) { $field_settings = $field['settings']; $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']]; // Define a data structure so it's possible to deal with both the color // and opacity. $property['getter callback'] = 'entity_metadata_field_verbatim_get'; $property['setter callback'] = 'entity_metadata_field_verbatim_set'; // Auto-create the field item as soon as a property is set. $property['auto creation'] = 'color_field_item_create'; $property['property info'] = color_field_item_property_info(); if (!$field_settings['opacity']) { unset($property['property info']['opacity']); } unset($property['query callback']); } /** * Callback for creating a new, empty link field item. * * @see color_field_property_info_callback() */ function color_field_item_create() { return array('rgb' => NULL, 'opacity' => NULL); } /** * Defines info for the properties of the link-field item data structure. */ function color_field_item_property_info() { $properties['rgb'] = array( 'type' => 'text', 'label' => t('The color of the color field.'), 'setter callback' => 'entity_property_verbatim_set', ); $properties['opacity'] = array( 'type' => 'float', 'label' => t('The opacity of the color field.'), 'setter callback' => 'entity_property_verbatim_set', ); return $properties; } /** * Implements hook_field_validate(). * * We want to verify that the color items only contain RGB hex values like * this: #RRGGBB. If the item validates, we do nothing. If it doesn't * validate, we add our own error notification to the $errors parameter. * * @see color_field_widget_error() */ function color_field_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { foreach ($items as $delta => $item) { // Test required color fields. if($instance['required'] && empty($item['rgb'])) { $errors[$field['field_name']][$langcode][$delta][] = array( 'error' => 'color_required', 'message' => t('The color for %field is required.', array( '%value' => trim($item['rgb']), '%field' => $instance['label'], )), 'error_element' => array('rgb' => TRUE, 'opacity' => FALSE), ); } // Test required opacity fields is opacity need to be recorded. if($field['settings']['opacity'] && $instance['required'] && empty($item['opacity'])) { $errors[$field['field_name']][$langcode][$delta][] = array( 'error' => 'color_required', 'message' => t('The opacity for %field is required.', array( '%value' => trim($item['rgb']), '%field' => $instance['label'], )), 'error_element' => array('rgb' => FALSE, 'opacity' => TRUE), ); } // Test rgb field format. $regexp = '@^#[0-9a-fA-F]{6}$@'; if (!empty($item['rgb']) && !preg_match($regexp, $item['rgb'])) { $errors[$field['field_name']][$langcode][$delta][] = array( 'error' => 'color_invalid', 'message' => t('The value %value provided for %field is not a valid color.', array( '%value' => trim($item['rgb']), '%field' => $instance['label'], )), 'error_element' => array('rgb' => TRUE, 'opacity' => FALSE), ); } // Test opacity field. $regexp = '@^[0]?(\.)(\d)*$|^[01]$@'; if (!empty($item['opacity']) && !preg_match($regexp, $item['opacity'])) { $errors[$field['field_name']][$langcode][$delta][] = array( 'error' => 'opacity_invalid', 'message' => t('The value %value provided for %field is not a valid opacity.', array( '%value' => trim($item['opacity']), '%field' => $instance['label'], )), 'error_element' => array('rgb' => FALSE, 'opacity' => TRUE), ); } } } /** * Implements hook_field_widget_error(). * * @see color_field_validate() * @see form_error() */ function color_field_field_widget_error($element, $error, $form, &$form_state) { if ($error['error_element']['rgb']) { form_error($element['rgb'], $error['message']); } if ($error['error_element']['opacity']) { form_error($element['opacity'], $error['message']); } } /** * Implements #element_validate function. * * If a palette is set for the Spectrum widget, there are no default values * available until the field has been saved. However, values are needed when a * field is marked as required, otherwise errors occur. Therefore, when rgb or * opacity are empty, and field is required, set the default values to rgb = * #000000 and opacity = 1. * * @see _color_field_field_widget_form() */ function color_field_field_widget_element_validate($element, &$form_state) { if ($form_state['build_info']['form_id'] == 'field_ui_field_edit_form') { $field = $form_state['build_info']['args'][0]; if ($field['widget']['type'] == 'color_field_spectrum_widget' && $field['required']) { $value = drupal_array_get_nested_value($form_state['values'], $element['#parents']); if (empty($value)) { $parents = $element['#parents']; $field_name = array_pop($parents); $field_value = ''; if ($field_name == 'rgb') { $field_value = '#000000'; } elseif ($field_name == 'opacity') { $field_value = 1; } drupal_array_set_nested_value($form_state['values'], $element['#parents'], $field_value); } } } } /** * Implements hook_field_is_empty(). */ function color_field_field_is_empty($item, $field) { if (!is_array($item)) { return FALSE; } if (empty($item['rgb'])) { return TRUE; } elseif ($field['settings']['opacity'] && empty($item['opacity'])) { return TRUE; } return FALSE; } /** * Implements hook_field_insert(). */ function color_field_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) { foreach ($items as $delta => $value) { if (!isset($items[$delta]['opacity'])) { $items[$delta]['opacity'] = 1; } } } /** * Implements hook_field_update(). */ function color_field_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) { foreach ($items as $delta => $value) { if (!isset($items[$delta]['opacity'])) { $items[$delta]['opacity'] = 1; } } } /** * Implements hook_element_info(). */ function color_field_element_info() { $elements = array(); $elements['color_field_plain_text'] = array( '#input' => TRUE, '#theme' => 'color_field_plain_text', '#theme_wrappers' => array('form_element'), ); $elements['color_field_default_widget'] = array( '#input' => TRUE, '#theme' => 'color_field_default_widget', '#theme_wrappers' => array('form_element'), ); $elements['color_field_simple_widget'] = array( '#input' => TRUE, '#theme' => 'color_field_simple_widget', '#theme_wrappers' => array('form_element'), ); $elements['color_field_spectrum_widget'] = array( '#input' => TRUE, '#theme' => 'color_field_spectrum_widget', '#theme_wrappers' => array('form_element'), ); return $elements; } /** * Implements hook_field_widget_info(). * * Enable the different field widgets. * * @see color_field_field_settings_form() * @see color_field_field_instance_settings_form * @see color_field_field_widget_form() */ function color_field_field_widget_info() { // If jquery-simple-color is enable so widget can be used. $jquery_simple_color_picker_enable = TRUE; $color_field_library_jquery_simple_color = drupal_get_library('color_field', 'jquery-simple-color'); foreach ($color_field_library_jquery_simple_color['js'] as $path => $js) { if (!file_exists($path)) { $jquery_simple_color_picker_enable = FALSE; } } // If jquery_dematte_color_picker_enable is enable so widget can be used. $jquery_dematte_color_picker_enable = TRUE; $color_field_library_dematte_color = drupal_get_library('color_field', 'dematte-color-picker'); foreach ($color_field_library_dematte_color['js'] as $path => $js) { if (!file_exists($path)) { $jquery_dematte_color_picker_enable = FALSE; } } // If jquery_eyecon_color_picker_enable is enable so widget can be used. $jquery_eyecon_color_picker_enable = TRUE; $color_field_library_eyecon_color = drupal_get_library('color_field', 'eyecon-color-picker'); foreach ($color_field_library_eyecon_color['js'] as $path => $js) { if (!file_exists($path)) { $jquery_eyecon_color_picker_enable = FALSE; } } // If jquery_spectrum_color_picker_enable is enable so widget can be used. $jquery_spectrum_color_picker_enable = TRUE; $color_field_library_spectrum_color = drupal_get_library('color_field', 'bgrins-spectrum'); foreach ($color_field_library_spectrum_color['js'] as $path => $js) { if (!file_exists($path)) { $jquery_spectrum_color_picker_enable = FALSE; } } foreach ($color_field_library_spectrum_color['css'] as $path => $js) { if (!file_exists($path)) { $jquery_spectrum_color_picker_enable = FALSE; } } $widgets = array(); $widgets['color_field_default_widget'] = array( 'label' => t('Pre-selected Color Boxes'), 'field types' => array('color_field_rgb'), 'weight' => 2, ); // Color_field_farbtastic_widget need more work before release. /*$widgets['color_field_farbtastic_widget'] = array( 'label' => t('Farbtastic Color-Picker'), 'field types' => array('color_field_rgb'), );*/ // Check if color_field_simple_color can become color_field_simple_widget if ($jquery_simple_color_picker_enable) { $widgets['color_field_simple_widget'] = array( 'label' => t('Simple Color-Picker'), 'field types' => array('color_field_rgb'), 'weight' => 3, ); } // Color_field_dematte_widget need more work before release. /*if ($jquery_dematte_color_picker_enable) { $widgets['color_field_dematte_widget'] = array( 'label' => t('Dematte Color-Picker'), 'field types' => array('color_field_rgb'), ); }*/ // color_field_eyecon_widget need more work before release. /*if ($jquery_eyecon_color_picker_enable) { $widgets['color_field_eyecon_widget'] = array( 'label' => t('Eyecon Color-Picker'), 'field types' => array('color_field_rgb'), ); }*/ // Dematte colorPicker. if ($jquery_spectrum_color_picker_enable) { $widgets['color_field_spectrum_widget'] = array( 'label' => t('Spectrum Color-Picker'), 'field types' => array('color_field_rgb'), 'weight' => 4, ); } // Textfield. $widgets['color_field_plain_text'] = array( 'label' => t('Plain text (RGB value as #ffffff)'), 'field types' => array('color_field_rgb'), 'weight' => 1, ); return $widgets; } /** * Implements hook_field_settings_form(). */ function color_field_field_settings_form($field, $instance, $has_data) { module_load_include('inc', 'color_field', 'color_field_admin'); return _color_field_field_settings_form($field, $instance, $has_data); } /** * Implements hook_field_instance_settings_form(). */ function color_field_field_instance_settings_form($field, $instance) { module_load_include('inc', 'color_field', 'color_field_admin'); return _color_field_field_instance_settings_form($field, $instance); } /** * Implements hook_field_widget_form(). */ function color_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { module_load_include('inc', 'color_field', 'color_field_admin'); return _color_field_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element); } /** * Implements hook_field_formatter_info(). * * @see color_field_field_formatter_view() */ function color_field_field_formatter_info() { return array( 'color_field_default_formatter' => array( 'label' => t('Plain text color'), 'field types' => array('color_field_rgb'), ), 'color_field_css_declaration' => array( 'label' => t('CSS Declaration'), 'field types' => array('color_field_rgb'), 'settings' => array( 'selector' => 'body', 'property' => 'background-color', 'important' => TRUE, 'opacity_disabled' => FALSE, ), ), 'color_field_swatch' => array( 'label' => t('Color Swatch'), 'field types' => array('color_field_rgb'), 'settings' => array( 'width' => '50', 'height' => '50', ), ), ); } /** * Implements hook_field_formatter_settings_form(). */ function color_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $element = array(); switch ($display['type']) { case 'color_field_css_declaration': $element['selector'] = array( '#title' => t('Selector'), '#type' => 'textarea', '#default_value' => $settings['selector'], '#required' => TRUE, '#description' => t('A valid CSS selector such as .links > li > a, #logo.'), ); $element['token'] = array( '#theme' => 'token_tree', '#token_types' => array($instance['entity_type']), '#dialog' => TRUE, ); $element['property'] = array( '#title' => t('Property'), '#type' => 'select', '#default_value' => $settings['property'], '#required' => TRUE, '#options' => array( 'background-color' => t('Background color'), 'color' => t('Text color'), ), ); $element['important'] = array( '#title' => t('Important'), '#type' => 'checkbox', '#default_value' => $settings['important'], '#description' => t('Whenever this declaration is more important than others.'), ); if ($field['settings']['opacity'] === 1) { $element['opacity_disabled'] = array( '#title' => t('Disable opacity'), '#type' => 'checkbox', '#default_value' => $settings['opacity_disabled'], '#description' => t('Disable the color opacity.'), ); } break; case 'color_field_swatch': $element['width'] = array( '#title' => t('Width'), '#type' => 'textfield', '#default_value' => $settings['width'], '#description' => t('Enter desired pixel width for the color swatch as a number only.'), '#required' => TRUE, "#element_validate" => array('_color_field_validate_number'), ); $element['height'] = array( '#title' => t('Height'), '#type' => 'textfield', '#default_value' => $settings['height'], '#description' => t('Enter desired pixel height for the color swatch as a number only.'), '#required' => TRUE, "#element_validate" => array('_color_field_validate_number'), ); break; } return $element; } /** * validating numerical input * * @param $element * @param $form_state * @param $form */ function _color_field_validate_number($element, &$form_state, $form) { if (!is_numeric($element['#value'])) { form_error($element, t('This needs to be a numeric value')); } } /** * Implements hook_field_formatter_settings_summary(). */ function color_field_field_formatter_settings_summary($field, $instance, $view_mode) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $summary = array(); switch ($display['type']) { case 'color_field_css_declaration': $summary[] = t('CSS selector : @css_selector', array('@css_selector' => $settings['selector'])); $summary[] = t('CSS property : @css_property', array('@css_property' => $settings['property'])); $summary[] = t('!important declaration : @important_declaration', array('@important_declaration' => (($settings['important']) ? t('Yes') : t('No')))); if ($field['settings']['opacity'] === 1) { $summary[] = t('Disable opacity : @opacity_disabled', array('@opacity_disabled' => ($settings['opacity_disabled']) ? t('Yes') : t('No'))); } break; case 'color_field_swatch': $summary[] = t('Width : @width', array('@width' => $settings['width'])); $summary[] = t('Height : @height', array('@height' => $settings['height'])); break; } return implode('
', $summary); } /** * Implements hook_field_formatter_view(). * * Three formatters are implemented. * - color_field_default_formatter just outputs markup indicating the color that * was entered and uses an inline style to set the text color to that value. * - color_field_css_declaration does the same but also changes the * background color or color of a region defined by the selector. * * @see color_field_formatter_info() */ function color_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); $field_settings = $field['settings']; $display_settings = $display['settings']; switch ($display['type']) { case 'color_field_default_formatter': foreach ($items as $delta => $item) { if ($field_settings['opacity']) { $value = color_field_hex2rgba(drupal_substr($item['rgb'], 1, 6), $item['opacity']); } else { $value = $item['rgb']; } $element[$delta]['#markup'] = $value; } break; case 'color_field_css_declaration': foreach ($items as $delta => $item) { if ($field_settings['opacity'] && $display_settings['opacity_disabled'] === 0) { $value = color_field_hex2rgba(drupal_substr($item['rgb'], 1, 6), $item['opacity']); } else { $value = $item['rgb']; } $selector = token_replace($display_settings['selector'], array($entity_type => $entity), array('clear' => TRUE)); $important = ($display_settings['important']) ? ' !important' : ''; $inline_css = $selector . '{ ' . $display_settings['property'] . ': ' . $value . $important . '; }'; drupal_add_css($inline_css, 'inline'); } break; case 'color_field_swatch': foreach ($items as $delta => $item) { if ($field_settings['opacity']) { $value = color_field_hex2rgba(drupal_substr($item['rgb'], 1, 6), $item['opacity']); } else { $value = $item['rgb']; } $width = $display_settings['width']; $height = $display_settings['height']; $element[$delta] = array( '#theme' => 'color_swatch', '#color' => $value, '#width' => $width, '#height' => $height, ); } break; } return $element; }