3

I'm doing something that works fine but I get the feeling there is a better way.

I have managed to extend the field settings in the field's manage page to add two new checkboxes. The checkboxes in this case, allow the input form field to be rendered with a Bootstap Add-ON for things like £ signs via my themes template.php

Adding the checkboxes using hook_field_widget_form_alter seems ok (although checking for args is a bit rubbish).

It's the 'wangle' I have to do in hook_widget_validate to get the settings to be incorporated in to the other field settings and saved to the database that is a bit nasty.

There must be a nicer way to do it than that so the question is ..

What is the standard (or better than this) way to extend a field's settings without creating a new widget ?

For reference, here is my code, firstly the added checkboxes :

<?php
/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_form_alter(&$element, &$form_state, $context) {
  if (arg(5) == 'fields' || arg(4) == 'fields') {
    if (isset($element['value'])) {
      $name = $context['field']['field_name'];
      // PREPEND.
      $val = 0;
      if (isset($form_state['field'][$name][LANGUAGE_NONE]['instance']['settings']['pre_on'])) {
        $val = $form_state['field'][$name][LANGUAGE_NONE]['instance']['settings']['pre_on'];
      }
      $element['#element_validate'][] = 'village_widget_validate';
      $element['pre_on']              = array(
        '#title'         => t('Render Prefix as Prepend'),
        '#type'          => 'checkbox',
        '#default_value' => $val,
      );
      // APPEND.
      $val = 0;
      if (isset($form_state['field'][$name][LANGUAGE_NONE]['instance']['settings']['app_on'])) {
        $val = $form_state['field'][$name][LANGUAGE_NONE]['instance']['settings']['app_on'];
      }
      $element['#element_validate'][] = 'village_widget_validate';
      $element['app_on']              = array(
        '#title'         => t('Render Suffix as Append'),
        '#type'          => 'checkbox',
        '#default_value' => $val,
      );
    }
  }
}
?>

The silly 'wangle' in the form validation to get the custom added fields to save as proper field instance settings that can be reteived.

<?
/**
 * Form validation handler for village_field_widget_form_alter().
 */
function mymodule_widget_validate($element, &$form_state) {
  if (isset($element['pre_on']['#value'])) {
    $form_state['values']['instance']['settings']['pre_on'] = $element['pre_on']['#value'];
  }
  if (isset($element['app_on']['#value'])) {
    $form_state['values']['instance']['settings']['app_on'] = $element['app_on']['#value'];
  }
}
?>

And for completeness here is the counterpart in my template.php that checks for the settings and adds some markup.

<?php
/**
 * Implements hook_form_element().
 */
function mytheme_form_element(&$variables) {
  // Default suffix.
  $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . $element['#field_suffix'] . '</span>' : '';
  // Check for field settings.
  if(isset($element['#field_name'])){
      if (isset($element['#bundle'])) {
      $field_instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
      if(isset($field_instance['settings']['app_on'])){
        // Our Bootstrapped suffix.
        $addoncls .= 'input-prepend '; 
        $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix add-on">' . $element['#field_suffix'] . '</span>' : '';
      }
    }
  }
  // Complied element.
  $output .= '<div class="'.$addoncls.'">' . $prefix . $element['#children'] . $suffix . "</div>";
  return $output;
}
?>

The only bit of interest is the recalling via.

$field_instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
$field_instance['settings']['app_on'];
3
  • I know the struggle to extend field options from experience and I would say you are right on target. However, due to the nature of somewhat regular updates to the main field module, I was creating my own field modules in most cases. For example, I wrote a custom link field module which has additional fields for prefix and suffix. I provided a patch on d.o for the link module, but it never got accepted or incorporated. So I am using my custom module when needed.
    – Paul
    Commented Nov 26, 2014 at 10:34
  • Thanks Paul. As you can imagine, I don't really want to create a whole module and widget just to add a checkbox, but thanks for the heads up about FieldAPI changes as they may make my 'wangley' bit redundant. Commented Nov 26, 2014 at 11:54
  • Neither did I write a complete module. I just took the existing Link module and made my changes (including module name change to avoid updates). But you are right, I also never meant to do that as it means additional maintenance effort.
    – Paul
    Commented Nov 26, 2014 at 12:19

1 Answer 1

0

You can add extra field instance settings as part of you custom module using hook_form_FORM_ID_alter, e.g.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function FOO_form_field_ui_field_edit_form_alter(&$form, $form_state, $form_id) {
  $field = $form['#field'];

  // @todo: Consider adding extra condition.

  // Inject setting form element to an instance settings form.
  $form['instance']['settings']['pre_on'] = array(
    '#type' => 'checkbox',
    '#title' => t('Render Prefix as Prepend'),
    '#description' => t('Some description'),
    '#default_value' => isset($form['#instance']['settings']['pre_on']) ? $form['#instance']['settings']['pre_on'] : NULL,
  );
}

If you don't want to create new module for a single checkbox, consider adding this hook into your template.php file as part of your theme.

1
  • 1
    this wont guarantee the data is saved and is retrieved by the field Commented Jul 8, 2017 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.