Gerando <tipo de botão = "enviar"> com a API do formulário

12

Eu tenho uma forma fortemente temática para integrar, cuja estrutura é mostrada abaixo. Estou quase lá, na maioria, exceto pelo envio.

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

Eu tentei muitas combinações diferentes, verifica-se que button_type não tem efeito no núcleo. Então, eu usei esse hack , esperando que isso resolvesse o meu problema. Infelizmente, apenas altera o atributo 'type' (obviamente), e não o próprio elemento. O tipo de botão pode conter outros elementos; nesse caso, a extensão é necessária para conter uma imagem de plano de fundo; ela deve ser expandida, pois o texto no botão é dinâmico.

Alguém tem uma idéia de como posso gerar a seguinte linha de marcação usando a API do formulário?

<button type="submit" class="clearfix"><span>Login</span></button>
stefgosselin
fonte
Para o Drupal 8, o botão enviar se tornará <botton type="submit">, consulte drupal.org/node/1671190
Philipp Michael

Respostas:

12

Em D7 recomendaria:

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

Dessa forma, você pode substituir o #markup em uma função de alteração posteriormente, se necessário, sem precisar reconstruir o botão HTML.

tim.plunkett
fonte
Este método não suporta o preenchimento automático.
Peter Lozovitskiy
17

Além disso, caso alguém tenha o mesmo problema que eu - ao usar o truque #markupou #prefix/ #suffixno actionsgrupo de um formulário , a função de retorno de chamada de envio não será chamada , a menos que um submitelemento de tipo esteja presente. Minha solução alternativa foi assim:

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

Dessa forma, você pode usar o HTML personalizado para enviar grupos de ações.

Óscar Gómez Alcañiz
fonte
Esta foi a melhor resposta dada ...
Pratip Ghosh
5

Para adicionar uma tag personalizada, você pode usar os seguintes trechos:

// 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
fonte
Isso realmente não funcionou, mas me levou a tentar '#markup' em vez de #value, e isso fez o truque. Obrigado mano, eu aprecio.
21411 stefgosselin
1
Você não informou sobre sua versão do Drupal. #value é para o Drupal6. #markup introduzido no Drupal 7
Shoaib Nawaz
Sim amigo, meu mal. Eu deveria ter mencionado o número da versão.
2131111
2

Para completar, postarei uma solução alternativa que envolve a substituição theme_button(retirada desta postagem do blog )

Primeiro adicione um buttontypeatributo ao elemento do formulário:

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

E, em seguida, substitua o botão do tema:

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

Isso cria problemas, no entanto, se houver mais de um botão no formulário, pois o Drupal não consegue detectar em qual botão foi clicado.

Isso pode ser solucionado adicionando um #after_buildretorno de chamada ao formulário:

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

E então na função 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;
}
Felix Eve
fonte
1

Tentei a resposta de Óscar Gómez Alcañiz, mas meu formulário ainda não estava sendo enviado. Como solução alternativa, alterei sua solução para que a entrada ficasse por cima do botão, mas fosse 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>',
);

Dessa forma, o real input[type="submit]está sendo clicado e acionando a ação, mas o botão

Provavelmente, é uma boa idéia colocar todo esse CSS em uma folha de estilo na vida real, mas apenas colocar a tag de estilo embutido aqui como exemplo.

Felix Eve
fonte
0

Aqui está como consegui isso no Drupal 8. Basicamente, crio uma nova sugestão de tema para que eu possa substituir o botão por um arquivo de galho personalizado.

Adicione este código ao seu arquivo 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'];
  }
}

No seu código, sempre que você criar seu formulário, adicione um atributo 'data-twig-sugestão' ao botão de envio:

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

Agora, se você tiver ativado a depuração de galho e verificar a fonte html do seu botão no site, verá uma nova sugestão de galho:

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

Agora você pode criar um arquivo input - submit - button.html.twig (eu o coloco em mythemename / templates / form_elements, mas você pode colocá-lo em outro lugar, se quiser):

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

A maneira mais correta é:

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

Produz HTML válido como este:

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

... e esse método não freia o preenchimento automático e outros recursos.

Peter Lozovitskiy
fonte
1
Ele não retorna uma <button>tag, pelo menos em D7. A última linha theme_button()no inclui / form.inc éreturn '<input' . drupal_attributes($element['#attributes']) . ' />';
Daniels
Poderia, por favor, verificar novamente? Copiei esse código do meu módulo personalizado em funcionamento.
Peter Lozovitskiy
Se funcionar para você, significa que você substituiu theme_button em um tema ou módulo personalizado. daniels está certo.
Felix Eve
@FelixEve, correto! Substituí o botão na função personalizada. Existe algum outro método para fazer isso sem a função personalizada?
Peter Lozovitskiy
Este tópico possui uma boa visão geral de todos os métodos disponíveis.
Felix Eve