Come creare 3 select dinamiche relazionate nazioni-regioni-province con l'attributo ahah per Drupal 6

Con molta fatica ho ricercato il codice per la popolazione di 3 select in Drupal 6, con PHP, Javascript, AJAX, girato tra forum, inviato richieste e post, poi grazie alla documentazione trovata sono riuscita a sviluppare penso in modo ottimale le funzioni necessarie. Il modulo è testato e funzionamte ma non completo in quanto manca il codice SQL per le tabelle del db e completare le funzioni validate e submit del form, ecco perchè non allego file. Inoltre è sviluppato per l'Italia, ma si può implemenare per le altre nazioni, basta creare gli array delle relative regioni.... MA L'IMPORTANTE CHE POPOLA LE SELECT! Questo era l'obiettivo.

<?php
/**
* Display help and module information
*/
function informationphp_help($path, $arg) {
  $output = '';
  switch ($path) {
    case "admin/help#informationphp":
      $output = '<p>'.  t("Allows you to show phpinfo inside the site") .'</p>';
      break;
  }
  return $output;
}
/**
* Valid permissions for this module
* @return array An array of valid permissions for the informationphp module
*/
function informationphp_perm() {
  //an administrator can define which roles have those permissions on the Administer » User management » Permissions page.
  return array('access informationphp');
}
function informationphp_menu() {
  $items = array();
  $items['admin/settings/informationphp'] = array(
    'title' => t('PHP info'),
    'description' => t('Allows you to show phpinfo inside the site'),
    'page callback' => 'informationphp_admin',
    'access arguments' => array('access informationphp'),
    'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/settings/informationphp/renderfields'] = array(
    'title' => t('JSON1'),
    'description' => t('Get data1 for haha'),
    'page callback' => 'informationphp_renderfields',
    'access arguments' => array('access informationphp'),
    'type' => MENU_CALLBACK,
   );
   $items['admin/settings/informationphp/renderfields_sub'] = array(
    'title' => t('JSON2'),
    'description' => t('Get data2 for haha'),
    'page callback' => 'informationphp_renderfields_sub',
    'access arguments' => array('access informationphp'),
    'type' => MENU_CALLBACK,
   );
  return $items;
}
function informationphp_admin() {
  //il modulo inizialmente è stato realizzato per visualizzare le phpinfo e nient'altro
  //print phpinfo();
  //exit;
  return drupal_get_form('informationphp_simple_form');
}
function informationphp_simple_form($form_state) {
  //in alternativa potete prendere le nazioni da un array: $optionsnation = array('Italia' => 'Italia', 'Francia' => 'Francia');
  $sql = "SELECT nid, nazione, continente, active, weight FROM {ab_nazioni} WHERE active='1' ORDER BY weight";
    $result = db_query($sql);
    $optionsnation = array();
    while ($row = db_fetch_array($result)) {
        $optionsnation[$row['nazione']] = $row['nazione'];
    }
  $form['res_nazionalita'] = array(
      '#type' => 'select',
      '#title' => t("Nazione"),
      '#required' => TRUE,
      '#options' =>  $optionsnation,
      '#attributes' => array('style' => 'width:152px;'),
      '#ahah' => array(
        'event' => 'change',
        'path' => 'admin/settings/informationphp/renderfields',
        'wrapper' => 'hahatestselect2',
        'method' => 'replace',
      ),
    );
  $form['res_regione'] = array(
      '#type' => 'select',
      '#title' => t("Cantone/Regione"),
      '#required' => TRUE,
      '#attributes' => array('style' => 'width:152px;'),
      '#options' => array(0 => 'Seleziona'),
      '#prefix' => '<div id="hahatestselect2">',
      '#suffix' => '</div>',
      '#ahah' => array(
        'event' => 'change',
        'path' => 'admin/settings/informationphp/renderfields_sub',
        'wrapper' => 'hahatestselect3',
        'method' => 'replace',
      ),
  );
  $form['res_provincia'] = array(
      '#type' => 'hidden',
      '#title' => t("Distretto/Provinciaa"),
      '#required' => TRUE,
      '#disabled' => TRUE,
      '#attributes' => array('style' => 'width:152px;'),
      '#options' => array(),
      '#prefix' => '<div id="hahatestselect3">',
      '#suffix' => '</div>',
  );
  $form['submit'] = array('#type' => 'submit', '#value' => t('Invia'), );
  return $form;
}
function informationphp_simple_form_validate($form, &$form_state) {
  $res_nazionalita = $form_state['values']['res_nazionalita'];
  $res_regione = $form_state['values']['res_regione'];
  $res_provincia = $form_state['values']['res_provincia'];
  //iserire qui il codice per la validazione se occorre
}
function informationphp_simple_form_submit($form, &$form_state) {
  global $user, $language, $account;
  $res_nazionalita = $form_state['values']['res_nazionalita'];
  $res_regione = $form_state['values']['res_regione'];
  $res_provincia = $form_state['values']['res_provincia'];
  drupal_set_message(t("res_nazionalita %res_nazionalita e' modificato", array('%res_nazionalita' => $res_nazionalita)));
  drupal_set_message(t("res_regione %res_regione e' modificato", array('%res_regione' => $res_regione)));
  drupal_set_message(t("res_provincia %res_provincia e' modificato", array('%res_provincia' => $res_provincia)));
  //mettere qui il codice per inserire nel database o quello che occorre
}
function informationphp_renderfields() {
  $form_build_id = $_POST['form_build_id'];
  $form_state = array('submitted' => FALSE);
  $form = form_get_cache($form_build_id, $form_state);
  $res_nazionalita = $_POST['res_nazionalita'];
  $options = array();
  $optionsSub = array();
  if ($res_nazionalita=='Italia') {
   $options = array('Lombardia' => 'Lombardia', 'Piemonte' => 'Piemonte', 'ValledAosta' => 'ValledAosta', 'TrentinoAltoAdige' => 'TrentinoAltoAdige', 'Veneto' => 'Veneto', 'FriuliVeneziaGiulia' => 'FriuliVeneziaGiulia', 'Liguria' => 'Liguria', 'EmiliaRomagna' => 'EmiliaRomagna', 'Toscana' => 'Toscana', 'Umbria' => 'Umbria', 'Marche' => 'Marche', 'Lazio' => 'Lazio', 'Abruzzo' => 'Abruzzo', 'Molise' => 'Molise', 'Campania' => 'Campania', 'Puglia' => 'Puglia', 'Basilicata' => 'Basilicata', 'Calabria' => 'Calabria', 'Sicilia' => 'Sicilia', 'Sardegna' => 'Sardegna');
   $optionsSub = array('Varese' => 'Varese', 'Como' => 'Como', 'Sondrio' => 'Sondrio', 'Milano' => 'Milano', 'Bergamo' => 'Bergamo', 'Brescia' => 'Brescia', 'Pavia' => 'Pavia', 'Cremona' => 'Cremona', 'Mantova' => 'Mantova', 'Lecco' => 'Lecco', 'Lodi' => 'Lodi', 'MonzaBrianza' => 'MonzaBrianza');
      $form['res_regione'] = array(
          '#type' => 'select',
          '#title' => t("Cantone/Regione *"),
          '#options' => $options,
          '#attributes' => array('style' => 'width:152px;'),
          '#ahah' => array(
            'event' => 'change',
            'path' => 'admin/settings/informationphp/renderfields_sub',
            'wrapper' => 'hahatestselect3',
            'method' => 'replace',
          ),
      );
      $form['res_provincia'] = array(
          '#type' => 'select',
          '#title' => t("Distretto/Provincia *"),
          '#options' => $optionsSub,
          '#attributes' => array('style' => 'width:152px;'),
          '#prefix' => '<div id="hahatestselect3">',
          '#suffix' => '</div>',
      );
  } else {
      $form['res_regione'] = array(
        '#type' => 'textfield',
        '#title' => t('Cantone/Regione'),
        '#maxlength' => 80,
        '#size' => 18,
        '#required' => TRUE,
        '#description' => '',
      );
      $form['res_provincia'] = array(
        '#type' => 'textfield',
        '#title' => t('Distretto/Provincia'),
        '#maxlength' => 80,
        '#size' => 18,
        '#required' => TRUE,
        '#description' => '',
      );
  }
  form_set_cache($form_build_id, $form, $form_state);
  $form = form_builder($_POST['form_id'], $form, $form_state);
  $output .= drupal_render($form[res_regione]);
  $output .= drupal_render($form[res_provincia]);
  drupal_json(array('status' => TRUE, 'data' => $_POST['tipo'].$output));
  exit;
}
function informationphp_renderfields_sub() {
  $form_build_id = $_POST['form_build_id'];
  $form_state = array('submitted' => FALSE);
  $form = form_get_cache($form_build_id, $form_state);
  $res_regione = $_POST['res_regione'];
  $options = array();
  switch($res_regione) {
      case "ValledAosta":
      $options = array('ValledAosta' => 'ValledAosta');
      break;
      case "Piemonte":
      $options = array('Torino' => 'Torino', 'Vercelli' => 'Vercelli', 'Novara' => 'Novara', 'Cuneo' => 'Cuneo', 'Asti' => 'Asti', 'Alessandria' => 'Alessandria', 'Biella' => 'Biella', 'VerbanoCusioOssola' => 'VerbanoCusioOssola');
      break;
      case "Lombardia":
      $options = array('Varese' => 'Varese', 'Como' => 'Como', 'Sondrio' => 'Sondrio', 'Milano' => 'Milano', 'Bergamo' => 'Bergamo', 'Brescia' => 'Brescia', 'Pavia' => 'Pavia', 'Cremona' => 'Cremona', 'Mantova' => 'Mantova', 'Lecco' => 'Lecco', 'Lodi' => 'Lodi', 'MonzaBrianza' => 'MonzaBrianza');
      break;
      case "TrentinoAltoAdige":
      $options = array('Bolzano' => 'Bolzano', 'Trento' => 'Trento');
      break;
      case "Veneto":
      $options = array('Verona' => 'Verona', 'Vicenza' => 'Vicenza', 'Belluno' => 'Belluno', 'Treviso' => 'Treviso', 'Venezia' => 'Venezia', 'Padova' => 'Padova', 'Rovigo' => 'Rovigo');
      break;
      case "FriuliVeneziaGiulia":
      $options = array('Udine' => 'Udine', 'Gorizia' => 'Gorizia', 'Trieste' => 'Trieste', 'Pordenone' => 'Pordenone');
      break;
      case "Liguria":
      $options = array('Imperia' => 'Imperia', 'Savona' => 'Savona', 'Genova' => 'Genova', 'LaSpezia' => 'LaSpezia');
      break;
      case "EmiliaRomagna":
      $options = array('Piacenza' => 'Piacenza', 'Parma' => 'Parma', 'ReggioEmilia' => 'ReggioEmilia', 'Modena' => 'Modena', 'Bologna' => 'Bologna', 'Ferrara' => 'Ferrara', 'Ravenna' => 'Ravenna', 'ForliCesena' => 'ForliCesena', 'Rimini' => 'Rimini');
      break;
      case "Toscana":
      $options = array('MassaCarrara' => 'MassaCarrara', 'Lucca' => 'Lucca', 'Pistoia' => 'Pistoia', 'Firenze' => 'Firenze', 'Livorno' => 'Livorno', 'Pisa' => 'Pisa', 'Arezzo' => 'Arezzo', 'Siena' => 'Siena', 'Grosseto' => 'Grosseto', 'Prato' => 'Prato');
      break;
      case "Umbria":
      $options = array('Perugia' => 'Perugia', 'Terni' => 'Terni');
      break;
      case "Marche":
      $options = array('PesaroUrbino' => 'PesaroUrbino', 'Ancona' => 'Ancona', 'Macerata' => 'Macerata', 'AscoliPiceno' => 'AscoliPiceno', 'Fermo' => 'Fermo');
      break;
      case "Lazio":
      $options = array('Viterbo' => 'Viterbo', 'Rieti' => 'Rieti', 'Roma' => 'Roma', 'Latina' => 'Latina', 'Frosinone' => 'Frosinone');
      break;
      case "Abruzzo":
      $options = array('LAquila' => 'LAquila', 'Teramo' => 'Teramo', 'Pescara' => 'Pescara', 'Chieti' => 'Chieti');
      break;
      case "Molise":
      $options = array('Campobasso' => 'Campobasso', 'Isernia' => 'Isernia');
      break;
      case "Campania":
      $options = array('Caserta' => 'Caserta', 'Benevento' => 'Benevento', 'Napoli' => 'Napoli', 'Avellino' => 'Avellino', 'Salerno' => 'Salerno');
      break;
      case "Puglia":
      $options = array('Foggia' => 'Foggia', 'Bari' => 'Bari', 'Taranto' => 'Taranto', 'Brindisi' => 'Brindisi', 'Lecce' => 'Lecce', 'BarlettaAndriaTrani' => 'BarlettaAndriaTrani');
      break;
      case "Basilicata":
      $options = array('Potenza' => 'Potenza', 'Matera' => 'Matera');
      break;
      case "Calabria":
      $options = array('Cosenza' => 'Cosenza', 'Catanzaro' => 'Catanzaro', 'ReggioCalabria' => 'ReggioCalabria', 'Crotone' => 'Crotone', 'ViboValentia' => 'ViboValentia');
      break;
      case "Sicilia":
      $options = array('Trapani' => 'Trapani', 'Palermo' => 'Palermo', 'Messina' => 'Messina', 'Agrigento' => 'Agrigento', 'Caltanissetta' => 'Caltanissetta', 'Enna' => 'Enna', 'Catania' => 'Catania', 'Ragusa' => 'Ragusa', 'Siracusa' => 'Siracusa');
      break;
      case "Sardegna":
      $options = array('Sassari' => 'Sassari', 'Nuoro' => 'Nuoro', 'Cagliari' => 'Cagliari', 'Oristano' => 'Oristano', 'OlbiaTempio' => 'OlbiaTempio', 'Ogliastra' => 'Ogliastra', 'MedioCampidano' => 'MedioCampidano', 'CarboniaIglesias' => 'CarboniaIglesias');
      break;
    default:
         $options = array();
    break;
  }
  if (count($options)) {
    $form['res_provincia'] = array(
      '#type' => 'select',
      '#title' => t("Distretto/Provincia *"),
      '#attributes' => array('style' => 'width:152px;'),
      '#options' => $options,
    );
  } else {
    $form['res_provincia'] = array(
      '#type' => 'textfield',
      '#title' => t('Distretto/Provincia'),
      '#maxlength' => 80,
      '#size' => 18,
      '#required' => TRUE,
      '#description' => '',
    );
  }
  form_set_cache($form_build_id, $form, $form_state);
  $form = form_builder($_POST['form_id'], $form, $form_state);
  $output .= drupal_render($form[res_provincia]);
  drupal_json(array('status' => TRUE, 'data' => $_POST['tipo'].$output));
  exit;
}

Un ringraziamento particolare a [email protected] che ha pubblicato un interessante pdf su "Variare un form con AHAH (Asynchronous HTML and HTTP)", con la sua guida è stato possibile sviluppare il codice sopra. Scrivetemi per qualsiasi commento.

Alla prossima da Danzisiweb

Argomenti:

Ho riprodotto perfettamente quanto riportato dal codice di sopra ma un problemino con il validate. Se attivo un qualsiasi check di validazione (e faccio in modo di non superarlo...), DOPO il submit il codice ahah non viene invocato, ovvero le select non si aggiornano! Proprio non ne esco fuori!