Problem with Custom CCk field value save
| Project: | CCK Currency |
| Version: | 6.x-1.0 |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | active |
Jump to:
Below is my module code. I have made simple mobile cck custom field to store mobilephone. But value is not getting saved/viewed/edited!!! I can see the text box while node add/edit. but value is not saved to db.. only one character is saved... Say i entered 98989.. it only saves 9 in db.. In edit time its not displayed even!!
Thx in adv.
<?php
// $Id: currency_cck.module,v 1.2.2.1 2008/10/21 15:21:29 melsawy Exp $
/**
* @file
* Defines a field type for currency.
*/
/**
* Implementation of hook_theme().
*/
function mobile_theme() {
return array(
'mobilephone_select' => array(
'arguments' => array('element' => NULL),
),
'mobile_formatter_default' => array(
'arguments' => array('element'),
)
);
}
/**
* Implementation of hook_field_info().
*
* Here we indicate that the content module will use its default
* handling for the view of this field.
*
* Callbacks can be omitted if default handing is used.
* They're included here just so this module can be used
* as an example for custom modules that might do things
* differently.
*/
function mobile_field_info() {
return array(
'mobilephone' => array(
'label' => 'Mobile Phone',
'description' => t('Store a mobile phone value.'),
'callbacks' => array(
'tables' => CONTENT_CALLBACK_DEFAULT,
'arguments' => CONTENT_CALLBACK_DEFAULT,
),
),
);
}
/**
* Implementation of hook_field_settings().
*/
function mobile_field_settings($op, $field) {
switch ($op) {
case 'form':
$form = array();
return $form;
case 'save':
return array();
case 'database columns':
return array(
'colmobilephone' => array(
'type' => 'text',
'not null' => TRUE,
'default' => ''
)
);
}
}
/**
* Implementation of hook_field().
*/
function mobile_field($op, &$node, $field, &$items, $teaser, $page) {
switch ($op) {
case 'validate':
//die(var_dump($items));
foreach ($items as $delta => $item) {
$error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
//die(var_dump($item));
if ($item) {
if (trim($item) == '') {
form_set_error($error_element, "Enter valid value for mobile");
}
}
}
return $items;
}
}
/**
* Implementation of hook_content_is_empty().
*/
function mobile_content_is_empty($item, $field) {
if (empty($item['colmobilephone'])) {
return TRUE;
}
return FALSE;
}
/**
* Implementation of hook_field_formatter_info().
*/
function mobile_field_formatter_info() {
return array(
'default' => array(
'label' => 'Flat Display',
'field types' => array('mobilephone'),
'multiple values' => CONTENT_HANDLE_CORE,
)
);
}
/**
* Theme function for 'default' currency_cck field formatter.
*/
function theme_mobile_formatter_default($element) {
if (!empty($element['#item']['colmobilephone'])) {
$currency_desc = $element['#item']['colmobilephone'];
if ($currency_desc !== FALSE) {
$output = $currency_desc;
}
}
return $output;
}
/**
* Implementation of hook_widget_info().
*
* Here we indicate that the content module will handle
* the default value and multiple values for these widgets.
*
* Callbacks can be omitted if default handing is used.
* They're included here just so this module can be used
* as an example for custom modules that might do things
* differently.
*/
function mobile_widget_info() {
return array(
'mobilephone_select' => array(
'label' => t('Text Field'),
'field types' => array('mobilephone'),
'multiple values' => CONTENT_HANDLE_MODULE,
'callbacks' => array(
'default value' => CONTENT_CALLBACK_DEFAULT,
),
),
);
}
/**
* Implementation of FAPI hook_elements().
*
* Any FAPI callbacks needed for individual widgets can be declared here,
* and the element will be passed to those callbacks for processing.
*
* Drupal will automatically theme the element using a theme with
* the same name as the hook_elements key.
*
* Autocomplete_path is not used by text_widget but other widgets can use it
* (see nodereference and userreference).
*/
function mobile_elements() {
return array(
'mobilephone_select' => array(
'#input' => TRUE,
'#columns' => array('colmobilephone'), '#delta' => 0,
'#process' => array('mobilephone_select_process'),
)
);
}
/**
* Implementation of hook_widget().
*
* Attach a single form element to the form. It will be built out and
* validated in the callback(s) listed in hook_elements. We build it
* out in the callbacks rather than here in hook_widget so it can be
* plugged into any module that can provide it with valid
* $field information.
*
* Content module will set the weight, field name and delta values
* for each form element. This is a change from earlier CCK versions
* where the widget managed its own multiple values.
*
* If there are multiple values for this field, the content module will
* call this function as many times as needed.
*
* @param $form
* the entire form array, $form['#node'] holds node information
* @param $form_state
* the form_state, $form_state['values'][$field['field_name']]
* holds the field's form values.
* @param $field
* the field array
* @param $items
* array of default values for this field
* @param $delta
* the order of this item in the array of subelements (0, 1, 2, etc)
*
* @return
* the form item for a single element for this field
*/
function mobile_widget(&$form, &$form_state, $field, $items, $delta = 0) {
switch ($field['widget']['type']) {
case 'mobilephone_select':
$element = array(
'#type' => 'mobilephone_select',
'#default_value' => $items,
);
break;
}
return $element;
}
/**
* Process an individual element.
*
* Build the form element. When creating a form using FAPI #process,
* note that $element['#value'] is already set.
*
* The $fields array is in $form['#field_info'][$element['#field_name']].
*/
function mobilephone_select_process($element, $edit, $form_state, $form) {
// The currency_cck_select widget doesn't need to create its own
// element, it can wrap around the optionwidgets_select element.
// This will create a new, nested instance of the field.
// Add a validation step where the value can be unwrapped.
$field_key = $element['#columns'][0];
$element[$field_key] = array(
'#type' => 'textfield',
'#default_value' => isset($element['#value']) ? $element['#value'] : '',
// The following values were set by the content module and need
// to be passed down to the nested element.
'#title' => $element['#title'],
'#required' => $element['#required'],
'#description' => $element['#description'],
'#field_name' => $element['#field_name'],
'#type_name' => $element['#type_name'],
'#delta' => $element['#delta'],
'#columns' => $element['#columns'],
);
if (empty($element[$field_key]['#element_validate'])) {
$element[$field_key]['#element_validate'] = array();
}
//array_unshift($element[$field_key]['#element_validate'], 'currency_cck_optionwidgets_validate');
//die(var_dump($element['#value']));
return $element;
}
/**
* FAPI theme for an individual elements.
*
* The textfield or select is already rendered by the
* textfield or select themes and the html output
* lives in $element['#children']. Override this theme to
* make custom changes to the output.
*
* $element['#field_name'] contains the field name
* $element['#delta] is the position of this element in the group
*/
function theme_mobilephone_select($element) {
return $element['#children'];
}

#1
Hi,
I had the same issue on my custom CCK field.
Took some time to figure out the prolem was in hook_widget where I assigned the result array to $element where it should have been assigned to $element['value'].
So in your case, you'll have to replace '$element = array(' in function mobile_widget with '$element['mobilephone_select'] = array('
So what happened?
There was one array level too less in the data. This made the final [0] in the code select the first character in the resulting string which was allready your data.
Gertjan