Génération de <button type = "submit"> avec l'API de formulaire


12

J'ai une forme fortement thématique à intégrer, dont la structure est illustrée ci-dessous. Je suis à peu près là pour la plupart à l'exception de la soumission.

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

J'ai essayé de nombreuses combinaisons différentes, il s'avère que button_type n'a aucun effet sur le noyau. J'ai donc utilisé ce hack , en espérant qu'il résoudrait mon problème. Hélas, cela ne change que l'attribut 'type' (évidemment), et non l'élément lui-même. Le type de bouton peut contenir d'autres éléments, dans ce cas, l'étendue est nécessaire pour contenir une image d'arrière-plan, elle doit être dans une étendue pour s'étirer car le texte du bouton est dynamique.

Quelqu'un a-t-il une idée de la façon dont je peux générer la ligne de balisage suivante à l'aide de l'API de formulaire?

<button type="submit" class="clearfix"><span>Login</span></button>

Pour Drupal 8, le bouton de soumission deviendra <botton type="submit">, voir drupal.org/node/1671190
Philipp Michael

Réponses:


12

En D7, je recommanderais:

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

De cette façon, vous pouvez remplacer le #markup dans une fonction alter plus tard si nécessaire, sans avoir à reconstruire le bouton HTML.


Cette méthode ne prend pas en charge la compétition automatique.
Peter Lozovitskiy

17

En outre, juste au cas où quelqu'un rencontrerait le même problème que moi - lors de l'utilisation de #markupou #prefix/ #suffixtrick sur le actionsgroupe d' un formulaire , la fonction de rappel de soumission ne sera pas appelée du tout , sauf si un submitélément type est présent. Ma solution de contournement était la suivante:

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

De cette façon, vous pouvez utiliser du code HTML personnalisé pour soumettre des groupes d'actions.


C'était la meilleure réponse donnée ...
Pratip Ghosh

5

Pour ajouter une balise personnalisée, vous pouvez utiliser les extraits de code suivants:

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

Cela n'a pas vraiment fonctionné, mais cela m'a permis d'essayer «#markup» au lieu de #value, et cela a fait l'affaire. Merci frère, j'apprécie.
stefgosselin

1
Vous n'avez pas informé de votre version Drupal. #value est pour Drupal6. #markup introduit dans Drupal 7
Shoaib Nawaz

Oui mon ami, ma mauvaise. J'aurais dû mentionner le numéro de version.
stefgosselin

2

Juste pour être complet, je posterai une solution alternative qui implique la priorité theme_button(tirée de ce billet de blog )

Ajoutez d'abord un buttontypeattribut à l'élément de formulaire:

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

Et puis remplacer le bouton du thème:

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

Cela crée cependant des problèmes s'il y a plus d'un bouton dans le formulaire car Drupal n'est pas en mesure de détecter le bouton sur lequel vous avez cliqué.

Cela peut être résolu en ajoutant un #after_buildrappel au formulaire:

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

Et puis dans la fonction after build:

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

J'ai essayé la réponse d'Óscar Gómez Alcañiz mais mon formulaire n'était toujours pas soumis. Pour contourner ce problème, j'ai modifié sa solution afin que l'entrée se trouve au-dessus du bouton mais soit transparente:

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

De cette façon, le réel input[type="submit]est cliqué et déclenche l'action, mais le bouton

Probablement une bonne idée de mettre tout ce CSS dans une feuille de style dans la vie réelle, mais juste de mettre la balise de style en ligne ici à titre d'exemple.


0

Voici comment j'y parviens dans Drupal 8. Fondamentalement, je crée une nouvelle suggestion de thème afin que je puisse remplacer le bouton par un fichier de brindille personnalisé.

Ajoutez ce code dans votre fichier 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'];
  }
}

Dans votre code, où que vous créiez votre formulaire, ajoutez un attribut 'data-twig-suggestion' à votre bouton d'envoi:

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

Maintenant, si vous avez activé le débogage de brindilles et que vous vérifiez la source html de votre bouton sur le site, vous verrez une nouvelle suggestion de brindilles:

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

Vous pouvez maintenant créer un fichier input - submit - button.html.twig (je le place dans mythemename / templates / form_elements mais vous pouvez le placer ailleurs si vous le souhaitez):

<button{{ attributes }} type='submit'>
    <span class="great-success">Submit</span>
</button>

-3

Une manière plus correcte est:

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

Il produit du HTML valide comme ceci:

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

... et cette méthode ne freine pas la saisie semi-automatique et d'autres fonctionnalités.


1
Il ne renvoie pas de <button>balise, du moins en D7. La dernière ligne de theme_button()in includes / form.inc estreturn '<input' . drupal_attributes($element['#attributes']) . ' />';
daniels

Pourriez-vous s'il vous plaît revérifier? J'ai copié ce code à partir de mon module personnalisé de travail.
Peter Lozovitskiy

Si cela fonctionne pour vous, cela signifie que vous avez remplacé theme_button dans un thème ou un module personnalisé. Daniels a raison.
Felix Eve

@FelixEve, correct! J'ai remplacé le bouton dans la fonction personnalisée. Existe-t-il une autre méthode pour le faire sans fonction personnalisée?
Peter Lozovitskiy

Ce fil a un bon aperçu de toutes les méthodes disponibles.
Felix Eve
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.