Riesco facilmente a creare form con WebForm dall'interfaccia inclusa ma mi piacerebbe imparare a creare form con WebForm anche attraverso dei moduli personalizzati.
So come si creano i moduli in genere ma come faccio a creare un modulo in cui definisco i campi per poi usarli attraverso WebForm?
Creare moduli WebForm
Sab, 05/06/2010 - 21:11
#1
Creare moduli WebForm
Mi sembra un sacco di lavoro. Se il problema e trasferire un webform da un sito ad un altro, o clonare un webform per creare un altro, leggi questo thread http://drupal.org/node/127902, in particolare http://drupal.org/node/127902#comment-527261 e http://drupal.org/node/127902#comment-1390552
Più imparo, più dubito.
No il mio problema non è questo.
Usando la versione 2 usavo la possibilità di inserire codice php per integrare funzionalità.
Nella versione 3 non c'è più questa possibilità.
C'è un modulo che la reintroduce ma con l'avviso dei pericoli che comporta.
D'altra parte il modulo webform validation non mi funziona più con la versione 3.
Per cui anche per entrare più a fondo nel funzionamento di Drupal e Webform avrei pensato di sperimentare la possibilità di creare direttamente dei moduli programmandoli.
Essenzialmente avere la possibilità di introdurre codice PHP nella versione 2 era sbagliata. Con la versione 3 siamo costretti ad usare il mecchanismo 'normale' di Drupal - modificando il form con hook_form_alter - come per un qualunque form del sistema.
La logica va così:
Se devi aggiungere codice di controllo (validation o submit) devi scrivere codice. Se devi scrivere codice puoi scrivere un tuo modulo. Poi si evita di mettere codice nel db.
Bon chance.
Più imparo, più dubito.
Si ma appunto il problema è come scriverlo il modulo.
Si fa come con i moduli normali con una cartella tutta i file ".module" e ".info" e poi si usano gli hook di WebForm?
Non si trova un esempio sul web?
Incidentalemente come accennavo nella 3 non mi funziona più webform_validation. Ho letto che c'è anche un "issue" aperto in proposito. Ho provato a cancellare la cache ma non c'è verso. C'è qualcos'altro che posso provare per ripristinarlo?
Non è così difficile...
Anche su questo sito (quasi) in italiano: http://www.drupalitalia.org/node/9349
Per hook e webform prova http://drupal.org/node/207251#comment-682179
Più imparo, più dubito.
Questo lo conosco ed è la procedura per la creazione standard di moduli.
Quello che ho spiegato non crea un webform...
Devi creare il webform tramite Web UI, oppura clonando o importando.
Quello che ho spiegato (o meglio linkato) spiega come aggiungere ulteriori validazioni, o azioni dopo il submit. Può anche essere usato per massaggiare il form stesso - ma questo è unaltro paio di maniche. Qui una mia odissea modificando il form node edit: http://www.drupalitalia.org/node/9089
Più imparo, più dubito.
Ok creo normalmente un webform.
Ma poi non riesco a capire dove devo scrivere tutte le cose spiegate nel link per aggiungere le validazioni.
Massaggi!?!
Ciao scusate sono nuovo e anche io ho un sacco di dubbi...
come si relazionano CCK, webforms e la creazione di nuovi moduli?
cioè: se io voglio crearmi una mia form dove l'utente inserisca i dati posso usare webform (FATTO). ma poi i dati dove vengono salvati? io vorrei crearmi una mia tabella nel DB e mettere i dati lì. invece di default ho trovato i miei dati "tutti sparsi" in tabelle del tipo webforms_qlcosa.
allora ho provato a creare un mio modulo per la generazione della form, ma seguendo il codice di node_example.module preso qui:
node_example
Di seguito il codice prodotto dopo aver letto le Form API :
<?php
/**
* Implementation of hook_node_info(). This function replaces hook_node_name()
* and hook_node_types() from 4.6. Drupal 5 expands this hook significantly.
*
* This is a required node hook. This function describes the nodes provided by
* this module.
*
* The required attributes are:
* - "name" provides a human readable name for the node,
* - "module" tells Drupal how the module's functions map to hooks (i.e. if the
* module is node_example_foo then node_example_foo_insert will be called
* when inserting the node).
* - "description" provides a brief description of the node type, which is
* shown when a user accesses the "Create content" page for that node type.
*
* The other optional, attributes:
* - "has_title" boolean that indicates whether or not this node type has a
* title field.
* - "title_label": the label for the title field of this content type.
* - "has_body": boolean that indicates whether or not this node type has a
* body field.
* - "body_label": the label for the body field of this content type.
* - "min_word_count": the minimum number of words for the body field to be
* considered valid for this content type.
*/
function form_anagrafica_node_info() {
return array(
'form_anagrafica' => array(
'name' => t('Form Anagrafica'),
'module' => 'form_anagrafica',
'description' => t("Form per inserire anagrafica atleti"),
'has_title' => true,
'title_label' => t('Dati Anagrafici'),
'has_body' => false,
'body_label' => t('Qui ci scriverò dopo'),
)
);
}
/**
* Display help and module information
* @param path which path of the site we're displaying help
* @param arg array that holds the current path as would be returned from arg() function
* @return help text for the path
*/
function form_anagrafica_help($path, $arg) {
$output = ''; //declare your output variable
switch ($path) {
case "admin/help#form_anagrafica":
$output = '<p>'. t("Mostra la form per l\'anagrafica") .'</p>';
break;
}
return $output;
}
/**
* Implementation of hook_perm().
*
* Since we are limiting the ability to create new nodes to certain users,
* we need to define what those permissions are here. We also define a permission
* to allow users to edit the nodes they created.
*
* @return array An array of valid permissions for the form_anagrafica module
*/
function form_anagrafica_perm() {
return array(
'create nuova form',
'delete la propria form',
'delete ogni form',
'edit la propria form',
'edit ogni form',
);
}
/**
* Implementation of hook_access().
*
* Node modules may implement node_access() to determine the operations
* users may perform on nodes. This example uses a very common access pattern.
*/
function form_anagrafica_access($op, $node, $account) {
if ($op == 'create') {
return user_access('create nuova form', $account);
}
if ($op == 'update') {
if (user_access('edit ogni form', $account) || (user_access('edit own example content', $account) && ($account->uid == $node->uid))) {
return TRUE;
}
}
if ($op == 'delete') {
if (user_access('delete any example content', $account) || (user_access('delete own example content', $account) && ($account->uid == $node->uid))) {
return TRUE;
}
}
}
/**
*
* Implementazione di hook_form_alter() usato per modificare la form base
*
*/
/*function form_anagrafica_form_alter(&$form, $form_state, $form_id) {
if($form_id == 'form_anagrafica_node_form') {
$form['menu']['#access'] = false;
$form['attachments']['#access'] = false;
$form['options']['#access'] = false;
$form['author']['#access'] = false;
$form['comment_settings']['#access'] = false;
$form['revision_information']['#access'] = false;
$form['path']['#access'] = false;
}
}*/
/**
* Implementation of hook_form().
*
* Now it's time to describe the form for collecting the information
* specific to this node type. This hook requires us to return an array with
* a sub array containing information for each element in the form.
*/
function form_anagrafica_form(&$form_state) {
$form['#attributes'] = array('enctype' => "multipart/form-data");
$form['main'] = array(
'#type' => 'fieldset',
'#title' => check_plain($type->title_label),
'#collapsible' => TRUE,
'#collapsed' => false,
'#tree' => false,
);
// Now we define the form elements specific to our node type.
//COGNOME
$form['main']['cognome'] = array(
'#type' => 'textfield',
'#title' => t('Cognome'),
'#size' => 50,
'#maxlength' => 64,
'#required' => TRUE,
'#default_value' => isset($node->cognome) ? $node->cognome : '',
'#description' => t('Cognome atleta')
);
//NOME
$form['main']['nome'] = array(
'#type' => 'textfield',
'#title' => t('Nome'),
'#size' => 50,
'#maxlength' => 64,
'#required' => TRUE,
'#default_value' => isset($node->nome) ? $node->nome : '',
'#description' => t('Nome atleta')
);
//SESSO
$options = array('','M'=>'M','F'=>'F');
$form['main']['sesso'] = array(
'#type' => 'select',
'#required' => false,
'#title' => t('Sesso'),
'#default_value' => isset($node->sesso) ? $node->sesso : '',
'#options' => $options,
'#description' => t('Scegliere sesso')
);
$options = null;
//CATEGORIA
$sql = "SELECT id, categoria FROM CATEGORIE";
$result = db_query($sql);
$options = array('');
while ($row = db_fetch_array($result)) {
$options[$row['id']] = $row['categoria'];
}
$form['main']['categoria'] = array(
'#type' => 'select',
'#title' => t('Categoria'),
'#required' => TRUE,
'#default_value' => isset($node->categoria) ? $node->categoria : '',
'#options' => $options,
'#description' => t('Specificare la categoria di appartenenza')
);
$options = null;
//ALTEZZA
$form['main']['altezza'] = array(
'#type' => 'textfield',
'#title' => t('Altezza'),
'#required' => false,
'#size' => 5,
'#maxlength' => 3,
'#default_value' => isset($node->altezza) ? $node->altezza : '',
'#description' => t('Specificare altezza in cm (es. "172")')
);
//PESO
$form['main']['peso'] = array(
'#type' => 'textfield',
'#title' => t('Peso'),
'#required' => false,
'#size' => 5,
'#maxlength' => 3,
'#default_value' => isset($node->peso) ? $node->peso : '',
'#description' => t('Specificare altezza in Kg')
);
//DATA DI NASCITA
$form['main']['data_nascita'] = array(
'#type' => 'date',
'#title' => t('Data di nascita'),
'#required' => false,
'#default_value' => isset($node->data_nascita) ? $node->data_nascita: '',
'#description' => t('Inserire data di nascita'),
'day' => format_date(time(), 'custom', 'j'),
'month' => format_date(time(), 'custom', 'n',0),
'year' => format_date(time(), 'custom', 'Y')
);
//questo va scomposto per l'indirizzo perché così si possono inviare le lettere in automatico!
//LUOGO DI NASCITA
$form['main']['luogo_nascita'] = array(
'#type' => 'textfield',
'#title' => t('Luogo di nascita'),
'#required' => false,
'#size' => 50,
'#maxlength' => 60,
'#default_value' => isset($node->luogo_nascita) ? $node->luogo_nascita : '',
'#description' => t('Inserire la città di nascita (es. "Alfonsine (RA))"')
);
//NAZIONALITA'
$form['main']['nazionalita'] = array(
'#type' => 'textfield',
'#title' => t('Nazionalità'),
'#required' => false,
'#size' => 20,
'#maxlength' => 15,
'#default_value' => isset($node->nazionalita) ? $node->nazionalita : '',
'#description' => t('Inserire la nazionalità (es. "ITALIANA")')
);
//CODICE FISCALE
$form['main']['cf'] = array(
'#type' => 'textfield',
'#title' => t('Codice Fiscale'),
'#required' => false,
'#size' => 20,
'#maxlength' => 16,
'#default_value' => isset($node->cf) ? $node->cf : '',
'#description' => t('Inserire il codice fiscale')
);
//TIPO ISCRIZIONE
$options = array('','Provvisoria'=>'Provvisoria','Definitiva'=>'Definitiva');
$form['main']['tipo_iscrizione'] = array(
'#type' => 'select',
'#required' => false,
'#title' => t('Tipo di iscrizione'),
'#default_value' => isset($node->tipo_iscrizione) ? $node->tipo_iscrizione : '',
'#options' => $options,
'#description' => t('Specificare il tipo di iscrizione')
);
$options = null;
//FOTO
$form['main']['foto'] = array(
'#type' => 'file',
'#title' => t('Foto'),
'#size' => 80,
'#default_value' => isset($node->altezza) ? $node->altezza : '',
'#description' => t('Seleziona la foto per l\'upload')
);
//NOTE
$form['main']['note'] = array(
'#type' => 'textarea',
'#required' => false,
'#title' => t('Note aggiuntive'),
'#default_value' => isset($node->note) ? $node->note : '',
'#cols' => 60,
'#rows' => 5,
'#description' => t('Campo per eventuali informazioni addizionali'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
//FINE
return $form;
}
/**
* Implementation of hook_validate().
*
*
* Errors should be signaled with form_set_error().
*/
function form_anagrafica_validate($node, &$form) {
//drupal_set_message( "questo e' il validate <pre>" . print_r($node, true)."</pre>");
//ALTEZZA
//controllo che l'altezza sia un numero e >0
if (($node->altezza != '') && (!is_numeric($node->altezza) || $node->altezza <=0)){
form_set_error('altezza', t('Errore ALTEZZA deve essere numerico e maggiore di zero.'));
}
//PESO
//controllo che peso sia un numero e >0
if (($node->peso != '') && (!is_numeric($node->peso) || $node->peso <=0)){
form_set_error('peso', t('Errore PESO deve essere numerico e maggiore di zero.'));
}
//DATA DI NASCITA
//controllo che sia antecedente ad oggi //TODO
//CONTROLLO SUL CODICE FISCALE
if ($node->cf != '' && strlen($node->cf) != 16)
form_set_error('cf', t('Errore CODICE FISCALE deve essere lungo 16 caratteri.'));
//CONTROLLO FOTO
//$nome_campo = 'foto';
//mi ha dato errori nell'array $_FILES?
//if ($_FILES['files']['error'][$nome_campo] == '0'){
// esiste il file temp?
// if (!file_exists($_FILES['files']['tmp_name'][$nome_campo]))
// form_set_error($nome_campo, t('Sembra che non esiste...'));
// è del formato corretto, dimensione corretta, ...
// if($_FILES['files']['tmp_name'][$nome_campo])
//}
//else
// form_set_error($nome_campo, t('C\'è stato un problemino con la foto'));
//
//$valids = array("funz"=>"");
//file_save_upload('foto',$valids'images/',FILE_EXISTS_RENAME);
//_stampa($_FILES);
}
/**
* Implementation of hook_insert().
*
* As a new node is being inserted into the database, we need to do our own
* database inserts.
*/
function form_anagrafica_form_insert($node) {
//drupal_set_message("insert: <pre>" . print_r($node, TRUE) . "</pre>");
//$dob = $node->data_nascita['year'].'-'.$node->data_nascita['month'].'-'.$node->data_nascita['day'];
//db_query("INSERT INTO {ATLETI}
// (COGNOME, NOME, SESSO, CATEGORIA_ID, ALTEZZA, PESO, DATA_NASCITA,LUOGO_NASCITA,
// NAZIONALITA, CF, TIPO_ISCRIZIONE, FOTO, NOTE) VALUES
// ('%s', '%s', '%s', %d, %d, %d, '%s')",
// $node->cognome, $node->nome, $node->sesso, $node->categoria, $node->altezza,
// $node->peso, $dob, $node->luogo_nascita, $node->nazionalita, $node->cf,
// $node->tipo_iscrizione, $node->foto, $node->note);
_stampa(t('La form è stata salvata.'));
}
/**
* Implementation of hook_update().
*
* As an existing node is being updated in the database, we need to do our own
* database updates.
*/
function form_anagrafica_update($node) {
drupal_set_message("update");
// if this is a new node or we're adding a new revision,
// if ($node->revision) {
// form_anagrafica_insert($node);
// }
// else {
// db_query("UPDATE {node_example} SET color = '%s', quantity = %d WHERE Lid = %d", $node->color, $node->quantity, $node->Lid);
// }
//drupal_set_message(t('Your form has been updated.'));
}
function form_anagrafica_form_submit($form_id, &$form_state) {
drupal_set_message('Form submitted: successo');
// unset ($form_state['storage']);
}
/**
* Implementation of hook_block().
* @param string $op one of "list", "view", "save" and "configure"
* @param integer $delta code to identify the block
* @param array $edit only for "save" operation
*/
function form_anagrafica_block($op='list') {
}
function form_anagrafica_admin() {
//$form = array();
// $form['form_anagrafica_val'] = array(
// '#type' => 'textfield',
// '#title' => t('Maximum number of links'),
// '#default_value' => variable_get('form_anagrafica_val', 3),
// '#size' => 2,
// '#maxlength' => 2,
// '#description' => t("The maximum number of links to display in the block."),
// '#required' => TRUE,
// );
//
// return system_settings_form($form);
}
function form_anagrafica_menu() {
$items = array();
$items['admin/settings/form_anagrafica'] = array(
'title' => 'Form anagrafica modulo settaggi',
'description' => 'Descrizione di pagina menu',
'page callback' => 'drupal_get_form',
'page arguments' => array('form_anagrafica_admin'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['form_anagrafica'] = array(
'title' => 'Form Anagrafica',
'page callback' => 'form_anagrafica_form',
'access arguments' => array('access form_anagrafica'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
/**
* Implementation of hook_nodeapi().
*
* When a node revision is deleted, we need to remove the corresponding record
* from our table. The only way to handle revision deletion is by implementing
* hook_nodeapi().
*/
function form_anagrafica_nodeapi(&$node, $op, $teaser, $page) {
// echo "$op ";
//switch ($op) {
// case 'delete_revision':
// Notice that we're matching a single revision based on the node's Lid.
// db_query('DELETE FROM {node_example} WHERE Lid = %d', $node->Lid);
// break;
// }
}
/**
* Implementation of hook_delete().
*
* When a node is deleted, we need to remove all related records from our table.
*/
function form_anagrafica_delete($node) {
// Notice that we're matching all revision, by using the node's Sid.
// db_query('DELETE FROM {node_example} WHERE Sid = %d', $node->Sid);
}
/**
* Implementation of hook_load().
*
* Now that we've defined how to manage the node data in the database, we
* need to tell Drupal how to get the node back out. This hook is called
* every time a node is loaded, and allows us to do some loading of our own.
*/
function form_anagrafica_load($node) {
//$additions = db_fetch_object(db_query('SELECT color, quantity FROM {node_example} WHERE Lid = %d', $node->Lid));
//return $additions;
}
/**
* Implementation of hook_view().
*
* This is a typical implementation that simply runs the node text through
* the output filters.
*/
//function form_anagrafica_view($node, $teaser = FALSE, $page = FALSE) {
// _stampa( "questa e la view <pre>" . print_r($node, TRUE) . "</pre>");
//$node = node_prepare($node, $teaser);
//$node->content['myfield'] = array(
// '#value' => theme('form_anagrafica_order_info', $node),
// '#weight' => 1,
//);
// return $node;
//}
/**
* Implementation of hook_theme().
*
* This lets us tell Drupal about our theme functions and their arguments.
*/
function form_anagrafica_theme() {
return array(
'form_anagrafica_order_info' => array(
'arguments' => array('node'),
),
);
}
/**
* A custom theme function.
*
* By using this function to format our node-specific information, themes
* can override this presentation if they wish. We also wrap the default
* presentation in a CSS class that is prefixed by the module name. This
* way, style sheets can modify the output without requiring theme code.
*/
function theme_form_anagrafica_order_info($node) {
$output = '<div class="form_anagrafica_order_info">';
$output .= t('The order is for quantity color items.');
$output .= '</div>';
return $output;
}
//function form_anagrafica_admin_validate($form, &$form_state) {
//}
function _stampa($var){
if (!is_array($var)){
drupal_set_message("Var : ".$var. " <br />");
return true;
}
else {
drupal_set_message("Var array: <pre>". print_r($var,true)."</pre>");
return true;
}
return false;
}
Il problema? se clicco su SUBMIT non succede nulla, così come se clicco su Save o Preview. E non riesco neanche a capire perché ci sono quei due pulsanti?!?
seguendo un altro esempio trovato in rete creo altre forms ma save e preview non compaiono. e perché l'indirizzo mi viene assegnato come /node/add/ invece che come form_anagrafica?
grazie in anticipo per le risposte!!
Giacomo