function tablefield_field_widget_form in TableField 7.2
Same name and namespace in other branches
- 7.3 tablefield.module \tablefield_field_widget_form()
- 7 tablefield.module \tablefield_field_widget_form()
Implements hook_widget_form().
File
- ./
tablefield.module, line 786 - Provides a set of fields that can be used to store tabular data with a node.
Code
function tablefield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$form['#after_build'][] = 'tablefield_after_build';
$settings = isset($instance['display']['default']['settings']) ? $instance['display']['default']['settings'] : FALSE;
$element['#type'] = 'tablefield';
$form['#attributes']['enctype'] = 'multipart/form-data';
/* Tablefield is sometimes embedded within another form by other modules, such
* as Field Collection. Because of that, we cannot rely on field_name and
* $delta to provide a unique ID for this element. Instead we use a
* concatenation of the field parents along with the current field name,
* language, delta and tablefield key.
*/
$tablefield_parents = isset($element['#field_parents']) ? $element['#field_parents'] : array();
array_push($tablefield_parents, $element['#field_name'], $element['#language'], $element['#delta'], 'tablefield');
$id = drupal_clean_css_identifier(implode('-', $tablefield_parents));
// IDs to use for various buttons/wrapper for this element. When processing
// an AJAX request, these IDs are used to build the field stack so we know
// where the value we're adjusting is in the FormAPI array.
$ajax_wrapper_id = "{$id}-wrapper";
$rebuild_id = "{$id}-rebuild";
$import_id = "{$id}-import";
$pasted_id = "{$id}-pasted";
// Default table size.
$default_size['count_cols'] = isset($instance['default_value'][0]['tablefield']['rebuild']['count_cols']) ? $instance['default_value'][0]['tablefield']['rebuild']['count_cols'] : 5;
$default_size['count_rows'] = isset($instance['default_value'][0]['tablefield']['rebuild']['count_rows']) ? $instance['default_value'][0]['tablefield']['rebuild']['count_rows'] : 5;
// Default table cell values.
$default_value = NULL;
// If there's a triggering element get the values from form state.
if (isset($form_state['triggering_element'])) {
if ($form_state['triggering_element']['#name'] == $rebuild_id) {
// Rebuilding table rows/cols.
$default_value = drupal_array_get_nested_value($form_state['tablefield_rebuild'], $tablefield_parents);
drupal_set_message(t('Table structure rebuilt.'), 'status', FALSE);
}
elseif ($form_state['triggering_element']['#name'] == $import_id) {
// Importing CSV data.
tablefield_import_csv($form, $form_state, $langcode, $import_id, $tablefield_parents);
$default_value = drupal_array_get_nested_value($form_state['input'], $tablefield_parents);
}
elseif ($form_state['triggering_element']['#name'] == $pasted_id) {
// Importing pasted data.
tablefield_import_pasted($form, $form_state, $langcode, $pasted_id, $tablefield_parents);
$default_value = drupal_array_get_nested_value($form_state['input'], $tablefield_parents);
if (empty($default_value['rebuild'])) {
$default_value['rebuild'] = $default_size;
}
}
else {
// The triggering element is neither a rebuild nor an import
// e.g. a file upload.
$default_value = drupal_array_get_nested_value($form_state['input'], $tablefield_parents);
}
}
// If no values by now, get tablefield item value stored in database, if any.
if (!$default_value) {
// This could be set e.g. when using paragraphs module.
if (isset($items[$delta]['tablefield'])) {
$default_value = $items[$delta]['tablefield'];
}
elseif (isset($items[$delta]['value'])) {
$default_value = unserialize($items[$delta]['value']);
}
elseif ($delta === 0 && isset($instance['default_value'][0]['tablefield'])) {
$default_value = $instance['default_value'][0]['tablefield'];
}
}
if (empty($default_value['rebuild'])) {
$default_value['rebuild'] = $default_size;
}
else {
$default_size = $default_value['rebuild'];
}
$count_rows = $default_size['count_rows'];
$count_cols = $default_size['count_cols'];
// Now we can build the widget.
if (!empty($instance['description'])) {
$help_text = $instance['description'];
}
else {
if ($settings) {
$display_settings = l(t('default display settings'), 'admin/structure/types/manage/' . $element['#bundle'] . '/display', array(
'attributes' => array(
'title' => t('Manage display settings'),
),
));
if ($settings['hide_header'] == TRUE) {
$help_text = t('This table will not have a header according to the !display_settings.', array(
'!display_settings' => $display_settings,
));
}
else {
$help_text = t('The first row will appear as the table header. Leave the first row blank if you do not need a header.');
}
}
}
$element['tablefield'] = array(
'#title' => $element['#title'],
'#description' => filter_xss_admin($help_text),
'#attributes' => array(
'id' => $id,
'class' => array(
'form-tablefield',
),
),
'#type' => 'fieldset',
'#tree' => TRUE,
'#collapsible' => FALSE,
'#prefix' => '<div id="' . $ajax_wrapper_id . '">',
'#suffix' => '</div>',
);
if ($settings) {
if ($settings['hide_header']) {
$element['tablefield']['#attributes']['class'][] = 'table-no-headers';
}
}
// Give the fieldset the appropriate class if it is required.
if ($element['#required']) {
$element['tablefield']['#title'] .= ' <span class="form-required" title="';
$element['tablefield']['#title'] .= t('This field is required');
$element['tablefield']['#title'] .= '">*</span>';
}
$arg0 = arg(0);
if ($arg0 == 'admin') {
$element['tablefield']['#description'] = t('This form defines the table field defaults, but the number of rows/columns and content can be overridden.');
if ($settings) {
if (!$settings['hide_header']) {
$element['tablefield']['#description'] .= ' ' . t('The first row will appear as the table header. Leave the first row blank if you do not need a header.');
}
}
}
// Render the form table.
$element['tablefield']['tabledata']['a_break'] = array(
'#markup' => '<table id="tablefield-editor">',
);
$default_value = isset($default_value['tabledata']) ? $default_value['tabledata'] : $default_value;
// Loop over all the rows.
for ($i = 0; $i < $count_rows; $i++) {
$zebra = $i % 2 == 0 ? 'even' : 'odd';
$element['tablefield']['tabledata']['b_break' . $i] = array(
'#markup' => '<tr class="draggable tablefield-row-' . $i . ' ' . $zebra . '"><td class="tablefield-row-count">' . ($i + 1) . '</td>',
);
// Loop over all the columns.
for ($ii = 0; $ii < $count_cols; $ii++) {
$instance_default = isset($instance['default_value'][0]['tablefield']['tabledata']["row_{$i}"]["col_{$ii}"]) ? $instance['default_value'][0]['tablefield']['tabledata']["row_{$i}"]["col_{$ii}"] : array();
if (!empty($instance_default) && !empty($field['settings']['lock_values']) && $arg0 != 'admin') {
// The value still needs to be send on every load in order for the
// table to be saved correctly.
$element['tablefield']['tabledata']['row_' . $i]['col_' . $ii] = array(
'#type' => 'value',
'#value' => $instance_default,
);
// Display the default value, since it's not editable.
$element['tablefield']['tabledata']['row_' . $i]['col_' . $ii . '_display'] = array(
'#type' => 'item',
'#title' => $instance_default,
'#prefix' => '<td>',
'#suffix' => '</td>',
);
}
else {
$cell_default = isset($default_value['row_' . $i]['col_' . $ii]) ? $default_value['row_' . $i]['col_' . $ii] : '';
$element['tablefield']['tabledata']['row_' . $i]['col_' . $ii] = array(
'#type' => 'textfield',
'#maxlength' => 2048,
'#size' => 0,
'#attributes' => array(
'id' => $id . '-cell-' . $i . '-' . $ii,
'class' => array(
'tablefield-row-' . $i,
'tablefield-col-' . $ii,
),
'style' => 'min-width: 100%',
),
'#default_value' => $cell_default,
'#prefix' => '<td>',
'#suffix' => '</td>',
);
}
}
// Add an extra column for the weight.
$row_weight_default = isset($default_value[$i]['weight']) ? $default_value[$i]['weight'] : $i + 1;
$element['tablefield']['tabledata']['row_' . $i]['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $row_weight_default,
'#delta' => $count_rows,
'#attributes' => array(
'class' => array(
'tablefield-weight',
),
),
'#prefix' => '<td class="tabledrag-hide">',
'#suffix' => '</td>',
);
$element['tablefield']['c_break' . $i] = array(
'#markup' => '</tr>',
);
}
$element['tablefield']['t_break' . $i] = array(
'#markup' => '</table>',
);
// Provide caption field to describe the data contained in the table.
$element['tablefield']['caption'] = array(
'#type' => 'textfield',
'#title' => t('Table description'),
'#default_value' => '',
'#description' => t('This brief caption will be associated with the table and will help Assitive Technology, like screen readers, better describe the content within.'),
);
if (isset($items[$delta]['value'])) {
$raw = unserialize($items[$delta]['value']);
if (isset($raw['caption'])) {
$element['tablefield']['caption']['#default_value'] = check_plain($raw['caption']);
}
}
// If the user doesn't have rebuild perms, we pass along the data as a value.
// Otherwise we provide form elements to specify the size and ajax rebuild.
if (isset($field['settings']['restrict_rebuild']) && $field['settings']['restrict_rebuild'] && !user_access('rebuild tablefield')) {
$element['tablefield']['rebuild'] = array(
'#type' => 'value',
'#tree' => TRUE,
'count_cols' => array(
'#type' => 'value',
'#value' => $count_cols,
),
'count_rows' => array(
'#type' => 'value',
'#value' => $count_rows,
),
'rebuild' => array(
'#type' => 'value',
'#value' => t('Rebuild Table'),
),
);
}
else {
$element['tablefield']['rebuild'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#title' => t('Change number of rows/columns.'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$element['tablefield']['rebuild']['count_cols'] = array(
'#title' => t('How many Columns'),
'#type' => 'textfield',
'#size' => 5,
'#prefix' => '<div class="clearfix">',
'#suffix' => '</div>',
'#value' => $count_cols,
);
$element['tablefield']['rebuild']['count_rows'] = array(
'#title' => t('How many Rows'),
'#type' => 'textfield',
'#size' => 5,
'#prefix' => '<div class="clearfix">',
'#suffix' => '</div>',
'#value' => $count_rows,
);
$element['tablefield']['rebuild']['rebuild'] = array(
'#type' => 'button',
'#validate' => array(),
'#limit_validation_errors' => array(),
'#executes_submit_callback' => TRUE,
'#submit' => array(
'tablefield_rebuild_form',
),
'#value' => t('Rebuild Table'),
'#name' => $rebuild_id,
'#attributes' => array(
'class' => array(
'tablefield-rebuild',
),
),
'#ajax' => array(
'callback' => 'tablefield_rebuild_form_ajax',
'wrapper' => $ajax_wrapper_id,
'effect' => 'fade',
),
);
}
// Allow the user to import a csv file.
$element['tablefield']['import'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#title' => t('Upload CSV file'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$element['tablefield']['import']['file'] = array(
'#name' => 'files[' . $import_id . ']',
'#title' => t('File upload'),
'#type' => 'file',
);
$element['tablefield']['import']['import'] = array(
'#type' => 'button',
'#validate' => array(),
'#limit_validation_errors' => array(),
'#executes_submit_callback' => TRUE,
'#submit' => array(
'tablefield_rebuild_form',
),
'#value' => t('Upload CSV'),
'#name' => $import_id,
'#attributes' => array(
'class' => array(
'tablefield-rebuild',
),
),
'#ajax' => array(
'callback' => 'tablefield_rebuild_form_ajax',
'wrapper' => $ajax_wrapper_id,
'effect' => 'fade',
),
);
// Allow user to paste data (e.g. from Excel).
$element['tablefield']['paste'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#title' => t('Copy & Paste'),
'#attributes' => array(
'class' => array(
'tablefield-extra tablefield-paste',
),
),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$delimiters = array(
'TAB' => t('TAB'),
',' => t('Comma ,'),
';' => t('Semicolon ;'),
'|' => t('Pipe |'),
'+' => t('Plus +'),
':' => t('Colon :'),
);
$element['tablefield']['paste']['paste_delimiter'] = array(
'#type' => 'select',
'#tree' => TRUE,
'#title' => t('Column separator'),
'#name' => 'delimiter[' . $pasted_id . ']',
'#options' => $delimiters,
'#description' => t('Data copied from Excel will use TAB.'),
);
$element['tablefield']['paste']['data'] = array(
'#type' => 'textarea',
'#tree' => TRUE,
'#name' => 'data[' . $pasted_id . ']',
'#title' => t('Paste table data here:'),
);
$element['tablefield']['paste']['paste_import'] = array(
'#type' => 'button',
'#validate' => array(),
'#limit_validation_errors' => array(),
'#executes_submit_callback' => TRUE,
'#submit' => array(
'tablefield_rebuild_form',
),
'#value' => t('Import & Rebuild'),
'#name' => $pasted_id,
'#ajax' => array(
'callback' => 'tablefield_rebuild_form_ajax',
'wrapper' => $ajax_wrapper_id,
'effect' => 'fade',
),
);
// Allow the user to select input filters.
if (!empty($field['settings']['cell_processing'])) {
$element['#base_type'] = $element['#type'];
$element['#type'] = 'text_format';
$element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL;
if (module_exists('wysiwyg')) {
$element['#wysiwyg'] = FALSE;
}
}
return $element;
}