Вывод полей формы в одну строку bootstrap 3


116

Продолжение темы про вывод полей формы в одну строку. На этот раз мы изменим нашу функцию темизации с учетом разметки популярного фреймворка для разработки адаптивных web-проектов - Bootstrap 3.

Bootstrap включает в себя адаптивную резиновую систему разметки, которая масштабируется до 12 столбцов при изменении окна просмотра (при просмотре с различных устройств). Основная задача нашей фукции - обернуть нужные элементы формы в соответствующие контейнеры (div).

Пример двухколоночной разметки:

<div class="row">
  <div class="col-md-8">.col-md-8</div>
  <div class="col-md-4">.col-md-4</div>
</div>

row - класс, которым оборачивают всю строку. Внутри него размещают столбцы.Размеры столбцов задаются классами, типа col-md-xx (xx-число от 1 до 12). Допустимые преффиксы для колонок - col-xs-, col-sm-, col-md-, col-lg-. Собственно говоря, от преффикса зависит поведение блоков при различной ширине устройства.  Итак, с теорией немного разобрались. Теперь перейдем к практике...

Объявляем функцию темизации:  

/**
 * Реализация hook_theme()
 */
function test_fieldinline_bootstrap_theme() {
  return array(
    'inline_fields_bootstrap' => array(
      'render element' => 'element',
    ),
  );
}

И пишем саму функцию. Для гибкой настройки предусмотрим некоторые ручные настройки для темизации. Список основных настроек (передаем их вместе со свойствами контейнера):

  • '#bootstrap_prefix' - префикс для столбцов. Допустимые значения: col-xs-, col-sm-, col-md- (по-умолчанию), col-lg-
  • '#not_div' - отключает у дочерних элементов обработку ['#theme_wrappers']. Параметр остался от предыдущей версии функции 
  • '#bootstrap_size_this' - По умолчанию, мы будем самостоятельно определять ширину колонок, равномерно распределяя их по ширине контейнера. Но, для ручного управления шириной столбцов, предусмотрим возможность передачи дополнительного параметра (передаем вместе со свойствами дочерних элементов)

Ниже приведу код функции theme_inline_fields_bootstrap с комментариями

/**
 * theme функция вывода полей в один ряд используя сетку bootstrap (12 клонок)
 */
function theme_inline_fields_bootstrap($variables) {
  $form = $variables['element'];
  $fields = array();

  //Класс префикса сетки bootstrap
  $bootstrap_prefix = isset($form['#bootstrap_prefix']) ? $form['#bootstrap_prefix'] : 'col-md-';

  //определим количество элементов в контейнере
  $max = 12;
  $bootstrap_size = 1;
  $count = 0;
  foreach ($form as $key => $element) {
    if (substr($key, 0, 1) != '#') {
      $count++;
    }
  }
  //размер колонок
  $bootstrap_size = $max > $count ? floor($max / $count) : 1;
  //размер последней колонки. Может отличаться от остальных
  $bootstrap_size_last = $max - ($count - 1) * $bootstrap_size;
  $this_element = 0;
  foreach ($form as $key => $element) {
    // ищем дочерние поля
    if (substr($key, 0, 1) != '#') {
      $this_element++;
      // если при валидации в поле была допущена ошибка, функция добавит к элементу класс error
      _form_set_class($element, array());

      if (isset($form['#not_div']) && $form['#not_div']) {
        unset($element['#theme_wrappers']);
      }

      if (isset($element['#bootstrap_size_this']) && is_numeric($element['#bootstrap_size_this']) && $element['#bootstrap_size_this'] > 0 && $element['#bootstrap_size_this'] < $max) {
        $bootstrap_size_this = $element['#bootstrap_size_this'];
      }
      else {
        $bootstrap_size_this = ($this_element == $count) ? $bootstrap_size_last : $bootstrap_size;
      }

      $fields[] = '
' . drupal_render($element) . '
';     }   }   $form['#children'] = '
' . implode('', $fields) . '
';   return theme('form_element', array('element' => $form)); }
Осталось привести пример формы, на которой реализован данный подход. В качастве основы возьмем форму с предыдущего поста.
/*
 * Form
 */
function test_fieldinline_bootstrap_form($form, &$form_state, $metal = NULL) {
  $form = array();
//первый контейнер. В нем будет три колонки (3-6-3). Ширину дочерних элементов указываем вручную.
  $form['cont'] = array(
    '#type' => 'fieldset',
    '#title' => 'Укажите параметры изделия',
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#theme' => array('inline_fields_bootstrap'),
    '#not_div' => FALSE,
    '#bootstrap_prefix' => 'col-md-',
    '#title_display' => 'none',
  );

  $form['cont']['pole4'] = array(
    '#type' => 'select',
    '#default_value' => 0,
    '#options' => array('Сталь', 'Олово'),
    '#title' => 'Материал',
    '#description' => 'Смотреть по каталогу',
    '#bootstrap_size_this' => '3',
  );

//второй контейнер. В нем три дочерних элемента, ширина колонок определяется автоматически.
  $form['cont']['cont1'] = array(
    '#type' => 'markup',
    '#title' => '',
    '#description' => 'Габаритные размеры изделия',
    '#theme' => array('inline_fields_bootstrap'),
    '#not_div' => FALSE,
    '#bootstrap_prefix' => 'col-xs-',
    '#bootstrap_size_this' => '6',
  );

  $form['cont']['cont1']['pole1'] = array(
    '#type' => 'select',
    '#title' => 'Ширина',
    '#default_value' => 0,
    '#options' => array(100, 200, 300, 450),
  );

  $form['cont']['cont1']['pole2'] = array(
    '#type' => 'select',
    '#title' => 'Высота',
    '#default_value' => '0',
    '#options' => array(10, 20, 30, 40),
  );

  $form['cont']['cont1']['pole3'] = array(
    '#type' => 'textfield',
    '#title' => 'Длина',
    '#default_value' => '',
    '#maxlength' => 5,
    '#size' => 5,
  );

//третий контейнер. Два дочерних элемента. Ширина определяется автоматически.
  $form['cont']['cont2'] = array(
    '#type' => 'markup',
    '#theme' => array('inline_fields_bootstrap'),
    '#not_div' => TRUE,
    '#title' => 'Вес',
    '#description' => 'Масса изделия',
    '#bootstrap_prefix' => 'col-xs-',
    '#bootstrap_size_this' => '3',
  );

  $form['cont']['cont2']['pole_value'] = array(
    '#type' => 'textfield',
    '#default_value' => '',
    '#maxlength' => 5,
    '#size' => 5,
  );

  $form['cont']['cont2']['pole_r'] = array(
    '#type' => 'select',
    '#default_value' => 'kg',
    '#options' => array('g' => 'гр', 'kg' => 'кг'),
  );

  return $form;
}

Ну вот и все.

Готовый пример можно посмотреть на этой странице. Там представлена более сложная форма. Обратите внимание, как меняется положение элементов формы при изменении ширины окна браузера.

P.S. У элемента fieldset есть интересный параметр -'#title_display'. Допустимые значения - 'none', 'after', 'before'. Регулирует положение заголовка контейнера. У меня он дублировалося. Пришлось его отключать, указывая

  '#title_display' => 'none', 
Drupal Drupal 7 — Статьи пробраузер
Добавить комментарий
Может быть интересно

В операционной системе Windows, как и в других операционных системах, интерактивные (набираемые с клавиатуры и сразу же выполняемые) команды выполняются с помощью так называемого командного интерпретатора, иначе называемого командным процессором или оболочкой командной строки (command shell).

3
Иногда при разработке сайта появляется необходимость создавать отдельный шаблон для определенной ноды. По умолчанию такой возможности нет, зато можно это прикрутить самостоятельно. Как это сделать? Это можно узнать в данной статье.

В данной статье пойдет речь о таких командах, как: CD, COPY | XCOPY, DIR, MKDIR | RMDIR, DEL, REN, MOVE.

Полный список команд можно вывести набрав HELP в командной строке.

2

В общем, проблема старая и известная. Правда не на всех рейсурсах заметная. При использовании модуля Metatag, на форму редактирования сущностей добавляется вкладка для индивидуального изменения метатегов. И на ней используется браузер токенов.

1
Те, кто использует модуль Double field могли заметить, что в текстовой области отсутствует редактор. Бывают случаи, когда для удобства наполнения он просто необходим.
1