Generowanie <typ przycisku = „prześlij”> za pomocą API formularza

12

Mam silnie tematyczną formę do zintegrowania, której strukturę pokazano poniżej. Jestem prawie tam, z wyjątkiem przesłania.

 <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>

Próbowałem wielu różnych kombinacji, okazuje się, że button_type nie ma wpływu na rdzeń. Więc użyłem tego hacka , mając nadzieję, że rozwiąże to mój problem. Niestety, zmienia tylko atrybut „typ” (oczywiście), a nie sam element. Typ przycisku może zawierać inne elementy, w tym przypadku rozpiętość jest potrzebna do przechowywania obrazu tła, musi być w rozpiętości, aby rozciągać się, ponieważ tekst na przycisku jest dynamiczny.

Czy ktoś ma jakiś pomysł, jak wygenerować następujący wiersz znaczników za pomocą interfejsu API formularza?

<button type="submit" class="clearfix"><span>Login</span></button>
stefgosselin
źródło
W przypadku Drupala 8 przycisk przesyłania stanie się <botton type="submit">, patrz drupal.org/node/1671190
Philipp Michael

Odpowiedzi:

12

W D7 poleciłby:

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

W ten sposób możesz później zastąpić #markup funkcją alter, jeśli to konieczne, bez konieczności przebudowywania przycisku HTML.

tim.plunkett
źródło
Ta metoda nie obsługuje automatycznego konkurowania.
Peter Lozovitskiy
17

Jako dodatek, na wypadek, gdyby ktoś napotkał takie same problemy, jak ja - kiedy używam #markuplub #prefix/ #suffixtrick na grupie formularza actions, funkcja wywołania zwrotnego przesyłania nie będzie w ogóle wywoływana , chyba że submitelement typu jest obecny. Moje obejście było takie:

$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>',
);

W ten sposób możesz używać niestandardowego kodu HTML do przesyłania grup akcji.

Óscar Gómez Alcañiz
źródło
To była najlepsza udzielona odpowiedź ...
Pratip Ghosh
5

Aby dodać niestandardowy tag, możesz użyć następujących fragmentów:

// 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>',
);
Shoaib Nawaz
źródło
To naprawdę nie działało, ale zmusiło mnie do spróbowania „#markup” zamiast #value i to załatwiło sprawę . Dzięki bracie, doceniam.
stefgosselin
1
Nie poinformowałeś o swojej wersji Drupal. #value jest dla Drupal6. #markup wprowadzono w Drupal 7
Shoaib Nawaz
Tak przyjacielu, mój zły. Powinienem był podać numer wersji.
stefgosselin
2

Dla kompletności opublikuję alternatywne rozwiązanie, które wymaga zastąpienia theme_button(wzięte z tego postu na blogu )

Najpierw dodaj buttontypeatrybut do elementu formularza:

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

A następnie zastąp przycisk motywu:

/**
 * 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']) . ' />';
  }
}

Powoduje to problemy, jeśli w formularzu jest więcej niż jeden przycisk, ponieważ Drupal nie jest w stanie wykryć, który przycisk został kliknięty.

Można temu zaradzić, dodając #after_buildwywołanie zwrotne do formularza:

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

A potem w funkcji po kompilacji:

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;
}
Felix Eve
źródło
1

Próbowałem odpowiedzi Óscara Gómeza Alcañiza, ale mój formularz wciąż nie był przesyłany. Aby obejść ten problem, zmieniłem jego rozwiązanie, aby dane wejściowe znajdowały się nad przyciskiem, ale były przezroczyste:

$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>',
);

W ten sposób rzeczywisty input[type="submit]zostaje kliknięty i wyzwala akcję, ale przycisk

Prawdopodobnie dobrym pomysłem jest umieszczenie całego CSS w arkuszu stylów w prawdziwym życiu, ale po prostu wstaw tutaj tag stylowy jako przykład.

Felix Eve
źródło
0

Oto jak to osiągnąć w Drupal 8. Zasadniczo tworzę nową sugestię motywu, dzięki czemu mogę zastąpić przycisk niestandardowym plikiem gałązki.

Dodaj ten kod do pliku 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'];
  }
}

W kodzie, gdziekolwiek utworzysz formularz, dodaj atrybut „data-twig-sugestion” do przycisku przesyłania:

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

Teraz, jeśli masz włączoną funkcję debugowania gałązek i sprawdzisz źródło HTML przycisku na stronie, zobaczysz nową propozycję gałązki:

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

Teraz możesz utworzyć plik wejściowy - prześlij - button.html.twig (umieszczam go w mythemename / templates / form_elements, ale możesz go umieścić gdzie indziej):

<button{{ attributes }} type='submit'>
    <span class="great-success">Submit</span>
</button>
użytkownik33560
źródło
-3

Bardziej poprawnym sposobem jest:

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

Tworzy poprawny kod HTML w następujący sposób:

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

... a ta metoda nie hamuje autouzupełniania i innych funkcji.

Piotr Łozowicki
źródło
1
Nie zwraca <button>tagu, przynajmniej w D7. Ostatni wiersz theme_button()w includes / form.inc jestreturn '<input' . drupal_attributes($element['#attributes']) . ' />';
Daniels
Czy mógłbyś ponownie sprawdzić? Skopiowałem ten kod z mojego działającego modułu niestandardowego.
Peter Lozovitskiy
Jeśli to działa, oznacza to, że przesłoniłeś przycisk motywu w niestandardowym motywie lub module. Daniels ma rację.
Felix Eve
@ FelixEve, zgadza się! Przesłoniłem przycisk w funkcji niestandardowej. Czy istnieje jakaś inna metoda, aby to zrobić bez funkcji niestandardowej?
Peter Lozovitskiy
Ten wątek ma dobry przegląd wszystkich dostępnych metod.
Felix Eve