Генерация <button type = «submit»> с помощью API формы

12

У меня есть тематическая форма для интеграции, структура которой показана ниже. Я почти там, по большей части, за исключением отправки.

 <form action="#">
   <fieldset>
     <legend>Authentification</legend>
       <label for="email">Courriel*</label>
       <input type="text" name="email" id="email">
       <label for="password">Mot de passe*</label>
       <input type="password" name="password" id="password" class="last">
       <a href="#" title="Mot de passe oublié?" class="clearfix">Forgot password?</a>
       <button type="submit" class="clearfix"><span>Login</span></button>
   </fieldset>
 </form>

Я пробовал много разных комбинаций, оказалось, что button_type не влияет на ядро. Поэтому я использовал этот хак , надеясь, что это решит мою проблему. Увы, он изменяет только атрибут type (очевидно), но не сам элемент. Тип кнопки может содержать другие элементы, в этом случае интервал необходим для хранения фонового изображения, он должен находиться в интервале для растягивания, поскольку текст в кнопке является динамическим.

Кто-нибудь знает, как я могу генерировать следующую строку разметки, используя API формы?

<button type="submit" class="clearfix"><span>Login</span></button>
stefgosselin
источник
Для Drupal 8 кнопка отправки станет <botton type="submit">, см. Drupal.org/node/1671190
Филипп Майкл

Ответы:

12

В D7 рекомендую:

$form['custom-form'] = array(
  '#prefix' => '<button type="submit">',
  '#suffix' => '</button>',
  '#markup' => '<span>' . t('Login') . '</span>',
);

Таким образом, вы можете заменить #markup в функции alter позже, если потребуется, без необходимости перестраивать кнопку HTML.

tim.plunkett
источник
Этот метод не поддерживает автоконкурент.
Петр Лозовицкий
17

Кроме того, на случай, если кто-то столкнется с той же проблемой, что и я, - при использовании трюка #markupor #prefix/ / #suffixдля actionsгруппы формы , функция обратного вызова submit не будет вызываться вообще , если не присутствует submitэлемент type. Мой обходной путь был таким:

$form['actions']['submit'] = array
(
    '#type' => 'submit',
    '#value' => '',
    '#attributes' => array( 'style' => array( 'display: none' )), // hide the input field
    '#submit' => array( 'my_callback_for_the_form_submit' ),
    '#prefix' => '<button type="submit" class="btn btn-primary">Add <i class="fa fa-plus-square-o">',
    '#suffix' => '</i></button>',
);

Таким образом, вы можете использовать пользовательский HTML для отправки групп действий.

Оскар Гомес Альканьис
источник
Это был лучший ответ, данный ...
Пратип Гош
5

Чтобы добавить собственный тег, вы можете использовать следующие фрагменты:

// Drupal 6.
$form = array();

// Other elements.

$form['custom-form'] = array(
    '#value' => '<button type="submit" class="clearfix"><span>Login</span></button>',
);
// Drupal 7.
$form = array();

// Other elements.

$form['custom-form'] = array(
    '#markup' => '<button type="submit" class="clearfix"><span>Login</span></button>',
);
Шоаиб Наваз
источник
Это не сработало, но заставило меня попробовать «#markup» вместо #value, и это помогло . Спасибо, брат, я ценю.
Стефгосселин
1
Вы не сообщили о своей версии Drupal. # значение для Drupal6. #markup введен в Drupal 7
Shoaib Nawaz
Да друг мой плохой. Я должен был упомянуть номер версии.
stefgosselin
2

Просто для полноты я опубликую альтернативное решение, которое включает переопределение theme_button(взято из этого сообщения в блоге )

Сначала добавьте buttontypeатрибут к элементу формы:

$form['submit'] = array (
    '#type' => 'submit',
    '#buttontype' => 'button',
    '#value' => 'Search',
);

А затем переопределить кнопку темы:

/**
 * Override of theme_button().
 *
 * Render the button element as a button and the submit element as an input element.
 */
function MYTHEME_button($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'submit';

  element_set_attributes($element, array('id', 'name', 'value'));  

  $element['#attributes']['class'][] = 'form-' . $element['#button_type'];
  if (!empty($element['#attributes']['disabled'])) {
    $element['#attributes']['class'][] = 'form-button-disabled';
  }

  if (isset($element['#buttontype']) && $element['#buttontype'] == 'button') {
    $value = $element['#value'];
    unset($element['#attributes']['value']);
    return '<button' . drupal_attributes($element['#attributes']) . '>' . $value . '</button>';
  }
  else {
    return '<input' . drupal_attributes($element['#attributes']) . ' />';
  }
}

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

Это можно решить, добавив #after_buildобратный вызов в форму:

$form['#after_build'][] = 'mymodule_force_triggering_element';

А затем в функции после сборки:

function mymodule_force_triggering_element($form, &$form_state) {
  if (isset($form_state['input']['submit'])) {
    $form_state['triggering_element'] = $form['submit'];
  } elseif (isset($form_state['input']['other_button'])) {
    $form_state['triggering_element'] = $form['other_button'];
  }
  return $form;
}
Феликс Ева
источник
1

Я попытался ответить Оскару Гомесу Альканьису, но моя форма все еще не была отправлена. В качестве обходного пути я изменил его решение, чтобы ввод располагался поверх кнопки, но был прозрачным:

$form['actions']['submit'] = array (
    '#type' => 'submit',
    '#value' => '',
    '#attributes' => array( 'style' => 'position: absolute; left: 0; right: 0; top: 0; bottom: 0; border: none; opacity: 0; width: 100%;'), // put input field over the top of button and make transparent
    '#prefix' => '<button type="submit" class="btn btn-primary">Add <i class="fa fa-plus-square-o">',
    '#suffix' => '</i></button>',
);

Таким образом, фактическое input[type="submit]нажатие и запуск действия, но кнопка

Вероятно, это хорошая идея, чтобы поместить все эти CSS в таблицу стилей в реальной жизни, но просто добавьте встроенный тег стиля в качестве примера.

Феликс Ева
источник
0

Вот как я добиваюсь этого в Drupal 8. По сути, я создаю предложение новой темы, чтобы я мог переопределить кнопку с помощью пользовательского файла ветки.

Добавьте этот код в ваш файл mythemename.theme:

/**
 * Add twig suggestions for input elements.
 *
 * If a form api element has a data-twig-suggestion attribute, then allow twig
 * theme override, add to suggestions.
 *
 * @param array $suggestions
 *   Current list of twig suggestions.
 * @param array $variables
 *   Every variable of the current element.
 */
function mythemename_theme_suggestions_input_alter(&$suggestions, array $variables) {
  $element = $variables['element'];

  if (isset($element['#attributes']['data-twig-suggestion'])) {
    $suggestions[] = 'input__' . $element['#type'] . '__' . $element['#attributes']['data-twig-suggestion'];
  }
}

В своем коде, где бы вы ни создавали форму, добавьте атрибут «data-twig-Suggestion» к кнопке отправки:

$form['submit'] = [
      '#type' => 'submit',
      '#value' => t('Submit') . ' >',
      '#attributes' => [
        'data-twig-suggestion' => 'button',
      ],
    ];

Теперь, если у вас включена отладка веток и вы проверили html источник вашей кнопки на сайте, вы увидите новое предложение веток:

<!-- FILE NAME SUGGESTIONS:
   * input--submit.html.twig
   * input--submit--button.html.twig
   x input.html.twig
-->

Теперь вы можете создать файл input - submit - button.html.twig (я помещаю его в mythemename / templates / form_elements, но вы можете разместить его в другом месте, если хотите):

<button{{ attributes }} type='submit'>
    <span class="great-success">Submit</span>
</button>
user33560
источник
-3

Более правильный путь:

$form['submit'] = array(
  '#type' => 'button',
  '#value' => '<span>Login</span>',
);

Он производит правильный HTML, как это:

<button value="&lt;span&gt;Login&lt;/span&gt;" type="submit">
    <span>Login</span>
</button>

... и этот метод не тормозит автозаполнение и другие функции.

Петр Лозовицкий
источник
1
Он не возвращает <button>тег, по крайней мере, в D7. Последняя строка theme_button()в include / form.increturn '<input' . drupal_attributes($element['#attributes']) . ' />';
Даниэльс
Не могли бы вы перепроверить? Я скопировал этот код из моего рабочего пользовательского модуля.
Петр Лозовицкий
Если это работает для вас, это означает, что вы перезаписали theme_button в пользовательской теме или модуле. Даниэльс прав.
Феликс Ив
@FelixEve, правильно! Я переопределил кнопку в пользовательской функции. Есть ли другой способ сделать это без пользовательской функции?
Петр Лозовицкий
В этой теме есть хороший обзор всех доступных методов.
Феликс Ив