Message d'avertissement

The subscription service is currently unavailable. Please try again later.

[Résolu] Rafraichir une liste apres soumission d'un formulaire

Information importante

En raison d'un grand nombre d'inscriptions de spammers sur notre site, polluant sans relache notre forum, nous suspendons la création de compte via le formulaire de "sign up".

Il est néanmoins toujours possible de devenir adhérent•e en faisant la demande sur cette page, rubrique "Inscription" : https://www.drupal.fr/contact


De plus, le forum est désormais "interdit en écriture". Il n'est plus autorisé d'y écrire un sujet/billet/commentaire.

Pour contacter la communauté, merci de rejoindre le slack "drupalfrance".

Si vous voulez contacter le bureau de l'association, utilisez le formulaire disponible ici, ou envoyez-nous un DM sur twitter.

Bonjour,

Dans mon module, j'ai créé 1 formulaire dans un bloc, et une liste dans un autre bloc qui s'affiche en-dessous. Le formulaire permet de créer/modifier des événements, qui doivent s'afficher dans la liste.
Au chargement de ma page, j'ai bien le formulaire (vide) et la liste en-dessous. Quand je soumets le formulaire, mon événement est bien créé, mais la liste n'est pas rafraichie, il faut que je recharge la page pour avoir la liste correcte. De plus, les champs de mon formulaire ne sont pas réinitialisés après la soumission.
Comment faire ?
Voici une partie de mon code :

function evenements_block_info(){
  $blocks['bloc_criteres'] = array(
    'info' => 'bloc des criteres',   
  );
  $blocks['bloc_resultats'] = array(
    'info' => 'bloc des resultats',   
  ); 
  $blocks['form']['cache'] = DRUPAL_NO_CACHE;
  return $blocks; 
}

function evenements_block_view($delta){
  switch ($delta){
    case 'bloc_criteres' :  return bloc_criteres();
                      break;
    case 'bloc_resultats' :  return bloc_resultats();
                      break;
    default:
        return array('subject'=>'','content'=>'');                     
  }
}

function bloc_criteres(){
  $block = array(
      'subject' => '',
      'content' => drupal_get_form('criteres_form'),
  );
  return $block;
}

function bloc_resultats(){
  $block = array(
      'subject' => '',
      'content' => theme(
        'bloc_resultats',
        array('evenements' => get_liste_evenements(),)
      ),
  );
  return $block;
}

function criteres_form($form, &$form_state) {

[....constitution du formulaire....]

    $form['submit'] = array(
      '#type' => 'submit',
      '#prefix' => '<div class="item-form">',
      '#suffix' => '',
      '#value' => $label_button,
      '#executes_submit_callback' => TRUE,
      '#id' => 'evenement_submit',
      '#ajax' => array(
          'callback' => 'submit_criteres_form',
          'wrapper' => 'bloc_resultats',
          'method' => 'replace',
          'effect' => 'fade',
           ),
      ); 
}

function submit_criteres_form($form, &$form_state){
   
  $form_state['rebuild'] = FALSE;

   [...traitement des infos...]

  $liste_evenements = get_liste_evenements();
  //ma liste est bien à jour, elle contient bien l'événement créé
  return theme('bloc_resultats', array('evenements' => $liste_evenements));
}

Merci pour votre aide !

Forum : 
Version de Drupal : 

En fait tu as deux zones à mettre à jour, le formulaire et ta liste d'événements.

Ta fonction callback devrait donc retourner des commandes ajax sous forme d'un tableau.

$command = array ( )
$command[] = ajax_command_replace( '#id-de-la-zone-formulaire', $html_du_formulaire);
$command[] = ajax_command_replace( '#id-de-la-zone-liste', $html_de_la_liste);

return array( (
'#type' => 'ajax',
'#commands' => $command
);

il existe d'autres functions ajax que ajax_commad_replace à voir en fonction de tes besoins

Super, ma liste est bien mise à jour, mille fois merci !!
Par contre, comment réinitialiser le formulaire, afin que les données saisies ne s'affichent plus dans les champs ? Si à la place de ton $html_du_formulaire, je mets drupal_get_form('mon_form'), ça ne fonctionne pas....

normal drupal_get_form() retourne un tableau il faut passé le resultat par drupal_render().

$array_du_formulaire = drupal_get_form('mon_form');

$html_du_formulaire = '<div id="id-de-mon-formalaire">' . drupal_render( $array_du_formulaire) . '</div>';

Si besoin, pense à remettre la div qui entoure ton formulaire comme dans mon exemple.

Malheureusement, on dirait que drupal_get_form('criteres_form') ne fonctionne pas ici, alors que c'est cette fonction que j'utilise à la création du block (dans le hook_bloc_view) : dès que je mets l'appel à drupal_get_form, même ma liste n'est plus rafraichie, alors que ça fonctionnait avant...je n'y comprends rien ! (pas d'erreur dans la console de firebug...).

Drupal n'a peut être pas chargé le fichier qui contient la fonction criteres_form().

Si tes fonctions ne sont pas dans le même fichier, il faut utiliser module_load_include() (ou un include_once mais ce n'est pas une bonne pratique) et cela bien sûr avant l'appel de drupal_get_form()

Mon code :

function evenements_block_info(){
  $blocks['bloc_criteres'] = array(
    'info' => 'bloc des criteres de recherche', 
    'cache' => DRUPAL_NO_CACHE, 
  );
  $blocks['bloc_resultats'] = array(
    'info' => 'bloc des resultats de recherche',
    'cache' => DRUPAL_NO_CACHE,   
  ); 
  return $blocks; 
}

function evenements_block_view($delta){
  switch ($delta){
    case 'bloc_criteres' :  return bloc_criteres();
                      break;
    case 'bloc_resultats' :  return bloc_resultats();
                      break;
    default:
        return array('subject'=>'','content'=>'');                     
  }
}

function bloc_criteres(){
  $block = array(
      'subject' => '',
      'content' => drupal_get_form('criteres_form'),
  );
  return $block;
}

function bloc_resultats(){
  $block = array(
      'subject' => '',
      'content' => theme(
        'bloc_resultats',
        array('evenements' => get_liste_evenements(),)
      ),
  );
  return $block;
}

function criteres_form($form, &$form_state) {
   [...constitution de mon formulaire...]

   $form['submit'] = array(
      '#type' => 'submit',
      '#prefix' => '<div class="item-form">',
      '#suffix' => '',
      '#value' => $label_button,
      '#executes_submit_callback' => TRUE,
      '#id' => 'critere_submit',
      '#ajax' => array(
          'callback' => 'submit_criteres_form',
          'wrapper' => 'bloc_resultats',
          'method' => 'replace',
          'effect' => 'fade',
           ),
      ); 
 
}

function submit_criteres_form($form, &$form_state){
   
  $form_state['rebuild'] = FALSE;
[...traitement des infos...]

   $liste_evenements = get_liste_evenements();  
  $html_liste = theme('bloc_resultats', array('evenements' => $liste_evenements)); 
  $command = array ();
  //dès que je mets cette ligne, non seulement mon formulaire n'est pas rafraichi, mais en plus ma liste d'événements
  //n'est pas rafraichie non plus
  //si je mets cette ligne en commentaire, alors mon formulaire n'est pas rafraichi, mais ma liste d'événements est rafraichie
  $array_du_formulaire = drupal_get_form('criteres_form');
  $html_du_formulaire = '<div id="block-evenements-bloc-criteres">' . drupal_render($form) . '</div>';

  $command[] = ajax_command_replace( '#block-evenements-bloc-criteres', $html_du_formulaire);
  $command[] = ajax_command_replace( '#block-evenements-bloc-resultats', $html_liste);
 
  return array(
  '#type' => 'ajax',
  '#commands' => $command,
  );

$array_du_formulaire = drupal_get_form('criteres_form');
  $html_du_formulaire = '<div id="block-evenements-bloc-criteres">' . drupal_render($array_du_formulaire) . '</div>';

Dans drupal_render, il faut mettre $array_du_formulaire.

L'autre chose à faire, c'est de renommer submit_criteres_form(...) par criteres_form_callback(...)

Les fonctions qui se termine par _form dans Drupal ne sont faite que pour la création des formulaires.

Pas sûr que ça règle ton problème, mais au moins se sera plus propre.

J'avoue que je suis en manque d'idée.

T'es < div > dans prefix suffix sont t'elles toutes fermés ?

      '#prefix' => '<div class="item-form">',
      '#suffix' => '',

Une chose en tout cas important à faire, c'est de mettre des "poids" à tous les composants de ton formulaires pour assurer l'ordre d'affichage, via les clefs '#weight' :
'#weight' => 1, // puis 2 3 4 5 6 ... tu peux aussi mettre des nombres négatifs,

Je viens de voir dans mon rapport de logs que juste après l'appel à drupal_get_form (qui ne fonctionne pas), j'ai ça :
Notice : Undefined index: form_build_id dans ajax_get_form() (ligne 320 dans /home/domains/glucozdev.fr/cmk/web/includes/ajax.inc).
puis
Données du formulaire POST invalides.

On dirait donc que le $form_id ('criteres_form') n'est plus reconnu...? Quand au 2ème message, je ne comprends pas pourquoi il apparaît là....

Je n'ai rien trouvé sur une fonction s'appelant form_build_id()....? Je veux bien recréer un formulaire, puis lui donner le même 'build_id', mais quelle méthode me retourne le formulaire sous forme de tableau afin que je l'affiche correctement (comme le fait drupal_get_form) ? A moins que j'aie raté quelque chose...?

Padon c'est drupal_build_form(), (manque l'autocomplétation d'Aptana dans les formulaires de ce site ;)).

Je n'en suis pas sur, car je n'en ai jamais eu besoin, mais ça devrait donner quelques chose de ce genre :

$_fS = $form_state;
$_fS['rebuild'] = TRUE; /* ou si ça ne fonctionne pas : $_fS['input'] = array(); */
$form = drupal_build_form('criteres_form', $_fS);
$html = drupal_render($form);

Au final, les corrections sont les suivantes :

function criteres_form($form, &$form_state) {
[...constitution du formulaire...]

$form['submit'] = array(
      '#type' => 'submit',
      '#prefix' => '<div class="item-form">',
      '#suffix' => '',
      '#value' => $label_button,
      '#executes_submit_callback' => TRUE,
      '#id' => 'alerte_submit',
      '#ajax' => array(
          'callback' => 'criteres_form_callback',
          'effect' => 'fade',
           ),
      ); 

}

function criteres_form_callback($form, &$form_state){ 
[...traitement des données...]

$liste_evenements = get_liste_evenements();  
  $html_liste = theme('bloc_resultats', array('evenements' => $liste_evenements));
 
  $command = array ();
  $command[] = ajax_command_replace( '#block-evenements-bloc-resultats', $html_liste);
 
  $_fS = $form_state;
   $_fS['input'] = array();
  $_fS['values'] = array();
  $form = drupal_build_form('criteres_form', $_fS);
  $criteres = array(
    '#theme' => 'bloc_criteres',
    '#criteres' => $form,
  );
  $html = drupal_render($criteres);
  
  $html_du_formulaire = '<div id="block-evenements-bloc-criteres" class="block block-evenements contextual-links-region odd">' .$html . '</div>';

  $command[] = ajax_command_replace( '#block-evenements-bloc-criteres', $html_du_formulaire);
 
    
  return array(
  '#type' => 'ajax',
  '#commands' => $command,
  );
}