пятница, 7 июля, 2017 - 22:33

Довольна часто мне приходится писать динамическое описание к очередному полю.

Например выбрав пользователя из списка нужно написать о нём в подписи. Одним словом нужная фича.

Сам я перепробовал кучу способов и пришёл к выводу, что удобнее всего использовать widget alter (код выходит короче и проще).

Собственно начнём с поля file которое у нас уже является ajax полем (без ajax динамики не будет).
При загрузки файла в поле меняем описание поля на "#номер имя (размер)".

HOOK, MODULE - название вашего модуля.
FORM_ID - форма где находится widget поле.
FIELD_NAME - имя поля.

/**
 * Implements hook_field_widget_form_alter().
 */
function HOOK_field_widget_form_alter(&$element, &$form_state, $context) {
  $values = &$form_state['values'];

  $form_id = $form_state['build_info']['form_id'];
  $field_name = $context['field']['field_name'];
  $data = &$element;
  if (isset($element[0])) {
    $data = $element[0];
  }

  switch ("{$form_id}:{$field_name}") {
    case 'FORM_ID:FIELD_NAME':
      $data['#process'][] = '_MODULE_form_field_file_process';
      break;
  }
}

function _MODULE_form_field_file_process($element, &$form_state, $form) {
  if ($fid = $element['#value']['fid']) {
    $file = file_load($fid);
    $element['#description'] = "#{$file->fid} {$file->filename} ({$file->filesize})";
  }

  return $element;
}

Если у нас поле не ajax, но мы хотим что бы описание было динамическое - сделаем его ajax (по другому никак).
Суть такая при вводе новых данных в поле мы заменяем его на обновлённое поле с подписью.

Для замены поля нам необходимо обернуть поле в <div id="wrapper-field-user"></div>, делаем через "#prefix" и "#suffix".

$element['#prefix'] = '<div id="wrapper-field-user">';
$element['#suffix'] .= '</div>';

Зарегистрировать ajax callback срабатывающий при изменении содержимого поля.

$element['#ajax'] = array(
  'event' => 'change',
  'callback' => '_MODULE_replace_field_user',
);

Осталось написать сам ajax callback.

$form_id - id формы.
$selector_form - css selector формы.
$selector - обёртка нашей формы.

/**
 * Ajax callback change field_ref_contractor
 */
function _MODULE_replace_field_user($form, &$form_state) {
  $commands = array();

  $form_id = preg_replace('/_+/', '-', $form['form_id']['#value']);
  $selector_form = '[id^="' . $form_id . '"]';

  // replace
  $selector = $selector_form . ' #wrapper-field-user';
  $commands[] = ajax_command_replace($selector, render($form['FIELD_NAME']));

  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}

На выходе код будет таким.

/**
 * Implements hook_field_widget_form_alter().
 */
function HOOK_field_widget_form_alter(&$element, &$form_state, $context) {
  $values = &$form_state['values'];

  $form_id = $form_state['build_info']['form_id'];
  $field_name = $context['field']['field_name'];
  $data = &$element;
  if (isset($element[0])) {
    $data = $element[0];
  }

  switch ("{$form_id}:{$field_name}") {
    case 'FORM_ID:FIELD_NAME':
      $data['#process'][] = '_MODULE_form_field_user_process';
      break;
  }
}

function _MODULE_form_field_user_process($element, &$form_state, $form) {
  $element['#ajax'] = array(
    'event' => 'change',
    'callback' => '_MODULE_replace_field_user',
  );
  $element['#prefix'] = '<div id="wrapper-field-user">';
  $element['#suffix'] .= '</div>';
  $element['#description'] = rand(0, 20);

  return $element;
}

/**
 * Ajax callback change field_ref_contractor
 */
function _MODULE_replace_field_user($form, &$form_state) {
  $commands = array();

  $form_id = preg_replace('/_+/', '-', $form['form_id']['#value']);
  $selector_form = '[id^="' . $form_id . '"]';

  // replace
  $selector = $selector_form . ' #wrapper-field-user';
  $commands[] = ajax_command_replace($selector, render($form['FIELD_NAME']));

  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}

Все приготовления сделаны, сбрасываем кэш и готово.

Добавить комментарий

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.