hook_submit bei dynamisch erzeugten Formularfeldern
am 15.09.2014 - 11:55 Uhr in
Hallo,
ich bin neu hier, und habe sogleich schon die erste Anfängerfrage.
Google konnte mir leider nicht weiterhelfen und hier im Forum habe ich auch nichts dazu gefunden. Falls ich aber was übersehen habe, tut es mir natürlich leid.
Und zwar habe ich ein Formular in meinem eigenen Modul dynamisch erstellt. D.h. Die Feldbezeichnungen werden mit Hilfe von Datenbankfeldern erstellt.
Hier mal ein Beispielcode, damit man versteht was ich meine. Ich glaube ich drücke mich bei solchen Dingen noch recht unklar aus mangels Erfahrung.
example.module:
<?php
$items['custom/menu/entry'] = array(
'title' => 'Custom menu entry',
'description' => 'Custom menu entry',
'page callback' => 'drupal_get_form',
'page arguments' => array('example_form'),
'file' => 'example_form.inc',
'access callback' => 'custom_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
?>
example_form.inc:
<?php
function example_form($form, &$form_state){
$pre_1 = '<div class="first_container">';
$suf_1 = '</div>';
$pre_2 = '<div class="second_container">';
$suf_2 = '</div>';
$form['container'] = array(
'#type' => 'container',
'#prefix' => $pre_1,
'#suffix' => $suf_1
);
$form['container']['second_container'] = array(
'#type' => 'container',
'#prefix' => $pre_2,
'#suffix' => $suf_2
);
$id_for = 1; //nur als Beispiel hier statisch, sonst dynamisch ebenfalls mit Datenbankabfrage erzeugter Wert
$query = db_select('db_tbl_example', 'e');
$query->fields('e', array('prim_Key', 'for_Key', 'col_1', 'col_2'));
$query->condition('e.for_Key', $id_for,'=');
$result = $query->execute();
foreach ($result as $row){
$id_prim = $row->prim_Key;
$col_1_value = $row->$col_1;
$col_2_value = $row->$col_2;
$pre_3 = '<div class="third_container">';
$suf_3 = '</div>';
$form['container']['second_container']['third_container_'.$id_prim] = array(
'#type' => 'container',
'#prefix' => $pre_3,
'#suffix' => $suf_3
);
$form['container']['second_container']['third_container_'.$id_prim]['col_1_value_'.$id_prim] = array(
'#type' => 'textfield',
'#title' => 'col_1_value',
'#default_value' => $col_1_value,
'#maxlength'=> 40,
'#attributes' =>array('placeholder' => t('some value'))
);
$form['container']['second_container']['third_container_'.$id_prim]['col_2_value_'.$id_prim] = array(
'#type' => 'textfield',
'#title' => 'col_2_value',
'#default_value' => $col_2_value,
'#maxlength'=> 40,
'#attributes' =>array('placeholder' => t('some value'))
);
}
$i = 1;
while ($i <= 5) {
$form['container']['sec_container_custom_'.$i] = array(
'#type' => 'container',
'#prefix' => '<div class="custom" id="id_'.$i.'">',
'#suffix' => '</div>'
);
$form['container']['sec_container_custom_'.$i]['titel_custom_'.$i] = array(
'#type' => 'textfield',
'#prefix' => '<div class="titel-custom" style="width:280px;">',
'#suffix' => '</div>',
'#maxlength'=> 100,
'#attributes' =>array('placeholder' => t('Titel'))
);
$form['container']['sec_container_custom_'.$i]['date_custom_'.$i] = array(
'#type' => 'textfield',
'#prefix' => '<div class="date-custom" style="max-width:60px">',
'#suffix' => '</div>',
'#maxlength'=> 4,
'#attributes' =>array('placeholder' => t('2014'))
);
$i++;
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'speichern'
);
return $form;
}
function example_form_submit($form, &$form_state){
$id_for = 1; //nur als Beispiel hier statisch zur Vereinfachung, sonst dynamisch ebenfalls mit Datenbankabfrage erzeugter Wert
$query = db_select('db_tbl_example', 'e');
$query->fields('e', array('prim_Key', 'for_Key', 'col_1', 'col_2'));
$query->condition('e.for_Key', $id_for,'=');
$result = $query->execute();
$rows = $result->fetchAll();
foreach ($result as $row){
$id_prim = $row->prim_Key;
$value_1 = $form_state['values']['container']['second_container']['third_container_'.$id_prim]['col_1_value_'.$id_prim];// <-- das ist Zeile 111
//Fehlermeldung: Notice: Undefined index: container in example_form_submit() (Zeile 111 von example_form.inc).
$value_2 = $form_state['values']['container']['second_container']['third_container_'.$id_prim]['col_2_value_'.$id_prim];// <-- das ist Zeile 114
//Fehlermeldung: Notice: Undefined index: container in example_form_submit() (Zeile 114 von example_form.inc).
//Das kanns also schonmal nicht sein...
if($rows_gr !== null || $rows_gr !== 0 || $rows_gr !== ""){
db_update('db_tbl_example')
->fields(array(
'col_1' => $value_1,
'col_2' => $value_2
))
->condition('prim_Key', $id_prim)
->condition('for_Key', $id_for)
->execute();
}else{
db_insert('db_tbl_example')
->fields(array(
'col_1' => $value_1,
'col_2' => $value_2,
'for_Key' => $id_for
))
->execute();
}
}
$i = 1;
while ($i <= 5) {
$val_custom_title = $form_state['values']['container']['sec_container_custom_'.$i]['titel_custom_'.$i]; //<--- Das ist Zeile 142
$val_custom_date = $form_state['values']['container']['sec_container_custom_'.$i]['date_custom_'.$i];
if($val_custom_title !== "" && $val_custom_date !== ""){
db_insert('db_tbl_example_custom_entry')
->fields(array(
'cus_title' => $val_custom_title,
'cus_date' => $val_custom_date
))
->execute();
//Fehlermeldung: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'cus_title' cannot be null:
//INSERT INTO {db_tbl_example_custom_entry} (cus_title, cus_date) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1);
//Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => ) in example_form_submit() (Zeile 142 von example_form.inc).
}
$i++;
}
drupal_set_message(('Formulardaten erhalten'), 'status');
}
?>
Wie ihr sehen könnt, handelt es sich zudem auch um ein recht verschachteltes Formular.
Die Anzeige klappt aber schon perfekt.
Nur, weiß ich jetzt nicht wie ich den hook_submit() händeln soll mit diesen dynamischen Feldbezeichnungen.
Könnt ihr mir hier weiterhelfen?
Vielen Dank schon mal im Voraus.
pyretta
EDIT: Sorry, ich habe den Beispielcode etwas zu sehr vereinfacht, so dass nur statische Daten genommen wurden. Das war eventuell missverständlich. Habe ich jetzt korrigiert. Ich hoffe jetzt wird es klarer, was ich meinte.
EDIT 2: Ich habe nun einfach versucht, das ganze so zu lösen, dass ich die ganzen DB-Abfragen in die submit Funktion übernommen habe. Aber das brachte folgenden Fehler: Notice: Undefined index: container in example_form_submit() (Zeile 77 von example_form.inc).. Passiert ist sonst nichts. Kein DB-Eintrag, kein DB Update - nix.
- Anmelden oder Registrieren um Kommentare zu schreiben
Hallo, am besten Du
am 15.09.2014 - 15:46 Uhr
Hallo,
am besten Du installierst Dir das devel Modul.
Dann gibst Du mit:
function example_form_submit($form, &$form_state){
dsm($form_state);
die Felder des Formulars aus.
So kannst Du sehen wie die Felder heissen.
In Deinem Fall kann es auch gut sein, dass Du in der Submit Funktion nochmal die
dynamischen Felder auslesen musst um die richtigen Variablen zu generieren.
MfG
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)
Sorry Hyp1, du kamst mir mit
am 15.09.2014 - 16:02 Uhr
Sorry Hyp1, du kamst mir mit deiner Antwort etwas zuvor :-D .
Ich habe gerade nochmal meinen Beitrag geändert und einen Versuch hinzugefügt, die Variablen durch die gleichen DB-Abfragen erneut zu generieren in der submit-Funktion. Aber das bringt eben die dort genannten Fehlermeldungen.
Einmal:
Notice: Undefined index: container in example_form_submit() (Zeile 111 von example_form.inc).
und einmal:
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'cus_title' cannot be null:
INSERT INTO {db_tbl_example_custom_entry} (cus_title, cus_date) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1);
Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => ) in example_form_submit() (Zeile 151 von example_form.inc).
Kannst du damit etwas anfangen? Bzw. woran liegt das und wie kann ich es beheben?
PS: "dsm($form_state);" zeigt überhaupt nichts an, obwohl ich das Modul Devel installiert und aktiviert habe. Kann das sein?
Hi, Zitat: PDOException:
am 15.09.2014 - 16:18 Uhr
Hi,
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'cus_title' cannot be null:
Das bedeutet was dort steht:
Du versuchst in das Datenbank Feld cus_title einen NULL Wert zu speichern.
Das Feld ist in der DB aber sicher auf NOT NULL gesetzt.
Notice: Undefined index: container in example_form_submit() (Zeile 111 von example_form.inc).
Die container Variable ist in der form_state nicht vorhanden.
Es ist komisch, dass Dir devel nichts anzeigt.
Du kannst satt dsm($form_state); auch alternativ var_dump($form_state); verwenden,
das ist allerdings nicht so übersichtlich.
LG
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)
Nochmal Hallo :-)Die
am 16.09.2014 - 13:50 Uhr
Nochmal Hallo :-)
Die Fehlermeldungen habe ich nun alle beheben können.
Ich habe folgendes geändert:
<?php
$form['container']['second_container']['third_container'][$id_prim] = array(
'#type' => 'container',
'#prefix' => $pre_3,
'#suffix' => $suf_3
);
$form['container']['second_container']['third_container'][$id_prim]['col_1_value'] = array(
'#type' => 'textfield',
'#title' => 'col_1_value',
'#default_value' => $col_1_value,
'#maxlength'=> 40,
'#attributes' =>array('placeholder' => t('some value'))
);
$form['container']['second_container']['third_container'][$id_prim]['col_2_value'] = array(
'#type' => 'textfield',
'#title' => 'col_2_value',
'#default_value' => $col_2_value,
'#maxlength'=> 40,
'#attributes' =>array('placeholder' => t('some value'))
);
?>
Also ich habe die "ID" oder den Zählwert in ein eigenes Feld gepackt.
Das half später in der submit Funktion diese Felder anzusprechen.
Das hat den Fehler behoben, dass den Containern kein index und damit auch keine Inhalte zugewiesen wurden.
Den Fehler, dass er auch leere Felder versucht hat in die Datenbank zu schreiben habe ich so gelöst:
<?php
while ($i <= 5) {
$val_custom_title = $form_state['values']['container']['sec_container_custom'][$i]['titel_custom']; //<--- Das ist Zeile 142
$val_custom_date = $form_state['values']['container']['sec_container_custom'][$i]['date_custom'];
if($val_custom_title !== "" && $val_custom_date !== "" && $val_custom_title !== null && $val_custom_date !== null ){
db_insert('db_tbl_example_custom_entry')
->fields(array(
'cus_title' => $val_custom_title,
'cus_date' => $val_custom_date
))
->execute();
}
$i++;
}
?>
Also ich habe zusätzlich die Feldwerte darauf geprüft ob sie "null" enthalten.
Soweit so gut :-D
Ich hoffe es hilft dem einen oder anderen Anfänger weiter.
Ganz rund läuft die Formular submit Funktion noch nicht, aber zumindest gibt es keine Fehlermeldungen mehr.
dsm und var_dump geben aber trotzdem noch keine Daten aus - also tauchen einfach nirgends auf. Also läuft da definitiv noch was gewaltig schief.
Dann fällt noch was auf:
Die Daten aus "$value_1" und "$value_2" werden nur aktualisiert. Sind sie von vornerein leer, wird kein neuer Datensatz angelegt.
Bei den Daten aus "$val_custom_title" und "$val_custom_date" ist es genau umgekehrt. Hier werden nur neue Datensätze eingefügt und das Update wird ignoriert.
Hi, also, dass weder var_dump
am 16.09.2014 - 12:56 Uhr
Hi,
also, dass weder var_dump noch dsm am Anfang der submit Funktion
etwas ausgeben, lässt mich vermuten, dass der Submit Hook evtl. gar nicht ausgeführt wird!
Probier mal am Anfang des Submit Hooks erste Zeile "drupal_set_message(__FUNCTION__);"
Das sollte Dir den Namen der submit Funkion in Drupal anzeigen wenn Sie ausgeführt wurde.
Wenn das nicht der Fall ist, wird die Funktion auch nicht aufgerufen.
MfG
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)
Hallo Hyp1,ich habe mal in
am 16.09.2014 - 13:49 Uhr
Hallo Hyp1,
ich habe mal in die erste Zeile des submit Hooks "drupal_set_message(__FUNCTION__);" eingefügt. Das wird auch ausgegeben.
Nur var_dump und dsm nicht.
Ich habe dann mal zum Test var_dump in der "example_form" Funktion ausprobiert. Dort wird es anstandslos angezeigt.
Vielleicht sollte ich noch erwähnen, dass ich Drupal 7 in einer XAMPP Umgebung laufen lasse. Vielleicht hängt es damit zusammen?
Hallo, verwendest Du ein
am 17.09.2014 - 08:04 Uhr
Hallo,
verwendest Du ein bestimmtes Theme?
Dass var_dump und dsm nicht anzeigen könnte an deinem Theme liegen.
Ich denke, das hier trifft zu:
http://drupal.stackexchange.com/questions/14835/debugging-with-var-dump-...
Für die Entwicklung Deines Moduls solltst Du besser das Drupal Standard Theme verwenden.
MfG
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)
Hallo, ich habe nun das
am 17.09.2014 - 14:09 Uhr
Hallo,
ich habe nun das Formular soweit zum Laufen bekommen - auch mit den DB-Einträgen/-Updates.
Mein Hauptfehler war, dass ich bei einigen db_query's versucht hatte das Ergebnis mittels "$result->fetchAll();" oder "$result->fetchAssoc();" in ein Array zu packen - ohne eine foreach-Schleife zu durchlaufen. Das hat offensichtlich den gesamten Programmablauf gestört. Nachdem ich das entfernt hatte, ging es auf einmal.
Das mit var_dump und dsm geht immer noch nicht. Merkwürdig zwar, und höchstwahrscheinlich ein Hinweis dass da immernoch der Wurm drin ist, aber wenn das Formular ansonsten die Ergebnisse bringt die es soll - solls mich mal nicht stören...
Das Modul das ich hier programmiere ist sowieso nur für den Eigengebrauch gedacht.
@Hyp1: Nun zu deiner Frage. Ja, ich nutze tatsächlich ein spezielles Theme mit Namen "evolve". Das habe ich für ca. 50$ bei Envato Themeforest gekauft. Ich dachte es wäre besser das Modul gleich in der Umgebung zu programmieren und zu testen in der es sein Dasein zukünftig fristen wird. Dann kann ich direkt sehen wie die Outputs aussehen würden etc. und kann mir schon gleich notieren wo ich später in der CSS nachbessern muss. Ich wusste natürlich nicht, dass Themes so etwas wie var_dump oder dsm verhindern können. Also ich kann es ja mal mit dem Standard Theme ausprobieren und vielleicht nutze ich das dann, wenn ich wieder auf Fehlersuche bin. Vielen Dank für Deine Tipps und Deine Unterstützung :-) hast mir wirklich viel geholfen und erklärt. Danke dafür.
Hi, es freut mich wenn ich
am 18.09.2014 - 00:14 Uhr
Hi,
es freut mich wenn ich helfen konnte.
Wie gesagt, dass var_dump und dsm nichts anzeigen wundert mich nun nicht mehr.
Ich könnte fast wetten es liegt an Deinem Theme (schau den Link den ich geschickt hatte).
Mein Tipp:
Wenn Du ein Modul programmierst, trenne das vom Themeing (MFC Komzept)
Du kannst auch anderen helfen wenn Du gelöst auf Deinen Thread schreibst.
MfG
Robert
https://awri.ch
Ich habe eine Schweizer Tastatur und daher kein scharfes ß ;-)