AHAH Problem beim Erstellen eines Formulars
am 10.10.2009 - 13:15 Uhr in
Vielleicht kann mir ja jemand helfen.
Ich habe in meinem Modul einen Button, jedesmal wenn er geklickt wird, soll ein neuer Eintrag generiert werden. Natürlich, sollen die Werte, die in den Zellen stehen jedesmal gespeichert werden, wenn auf den Button geklickt wird.
Ich habe mich dabei sehr nah am Poll-Modul orientiert, die das über formstate[value] machen. Leider habe ich wohl noch nen kleinen Denkfehler in meinem Code. Ich kann zwar ein weiteres Feld erstellen, aber ein drittes, viertes usw. klappt nicht. Ich vermute das Problem liegt an einer Abfrage, aber da ich nicht genau verstehe was da passiert, bräuchte ich nen kleinen Stubs.
// Die Formmethode
function dublist_form(&$node, $form_state) {
$type = node_get_types('type', $node);
// diese Abfrage soll garantieren, dass alle Einträge angezeigt werden, initial natürlich 1
if (isset($form_state['entry_count'])) {
$entry_count = $form_state['entry_count'];
}
else {
$entry_count = 1;
}
// damit niemand im Code vom Poll-Modul suchen muss, mal die Stelle im Poll Modul, Hier gibt es initial 2 Optionen, hat jeder sicher schon gesehen
if (isset($form_state['choice_count'])) {
$choice_count = $form_state['choice_count'];
}
else {
$choice_count = max(2, empty($node->choice) ? 2 : count($node->choice));
}
// Existing files: title (Title) and body (body)
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -7,
);
}
// The wrapper for the input
$form['list_wrapper'] = array(
'#tree' => FALSE,
'#weight' => -4,
'#prefix' => '<div class="clear-block" id="list-wrapper"><table>',
'#suffix' => '</table></div>',
);
// Container for the input
$form['list_wrapper']['list_entry'] = array(
'#prefix' => '<div class="clear-block" id="list-entry"><tr>',
'#suffix' => '</tr></div>',
'#theme' => 'dublist_edit',
);
// Add elements to table
for ($delta = 0; $delta < $entry_count; $delta++) {
$role = isset($node->list_entry[$delta]['dlrole']) ? $node->list_entry[$delta]['dlrole'] : '';
$note = isset($node->list_entry[$delta]['dlnote']) ? $node->list_entry[$delta]['dlnote'] : '';
$form['list_wrapper']['list_entry'][$delta] = _dublist_form($delta, $role, $note);
}
// The button to add more roles.
$form['list_wrapper']['add_role'] = array(
'#type' => 'submit',
'#value' => t('More roles'),
'#description' => t("If the amount of roles above isn't enough, click here to add more roles."),
'#prefix' => '<div class="clear-block" id="table-action">',
'#suffix' => '</div>',
'#weight' => 1,
'#submit' => array('dublist_more_entries_submit'), // If no javascript action
);
return $form;
}
Jetzt die Methode, die beim Klicken des Buttons aufgerufen wird.
function dublist_more_entries_submit($form, &$form_state) {
// Set the form to rebuild and run submit handlers.
node_form_submit_build_node($form, $form_state);
// Make the changes we want to the form state.
if ($form_state['values']['add_role']) {
$n = $_GET['q'] == 'dublist/js' ? 1 : 2; // In dieser Zeile vermute ich den Fehler, zumal ich leider nicht wirklich weiß, //wie hier an das n gekommen wird. Vielleicht kann mir das jemand erklären und Abhilfe schaffen. Steht anstatt der 2 ne 5 bekomme ich 5 //weitere Einträge
$form_state['entry_count'] = count($form_state['values']['counter']) + $n;
}
}
//Alternativ die Methode im Pollmodul
function poll_more_choices_submit($form, &$form_state) {
// Set the form to rebuild and run submit handlers.
node_form_submit_build_node($form, $form_state);
// Make the changes we want to the form state.
if ($form_state['values']['poll_more']) {
$n = $_GET['q'] == 'poll/js' ? 1 : 5;
$form_state['choice_count'] = count($form_state['values']['choice']) + $n;
}
}
Meine Submitfunkton
function dublist_node_form_submit(&$form, &$form_state) {
// Renumber fields
$form_state['values']['list_entry'] = array_values($form_state['values']['list_entry']);
}
//Poll-Modul:
function poll_node_form_submit(&$form, &$form_state) {
// Renumber fields
$form_state['values']['choice'] = array_values($form_state['values']['choice']);
$form_state['values']['teaser'] = poll_teaser((object)$form_state['values']);
}
Falls jemand noch mehr Input benötigt und ich wichtige Details vergessen habe, bitte melden. Das ist wohl das letzte Problem, was ich nicht alleine oder mit nem Kumpel lösen kann, der mir in DB und php-Fragen unterstützen kann. Wenn dies funtkioniert, ist ne monatelange Odysee endlich vorbei.
- Anmelden oder Registrieren um Kommentare zu schreiben
Thema AHAH Formulare
am 10.10.2009 - 14:29 Uhr
Damit Du grunsaetzlich verstehst was Du mit dem nachgenutzten Code des Pollmodules veranstaltest bzw. damit Du weisst was da grundsaetzlich ablaeuft empfehle ich Dir Dich mit dem Theme
AHAH Formulare
zu beschaeftigen. Das Thema AHAH Forms ist auf drupal.org gut dokumentiert.
Ich denke Du weisst nicht was ein AHA CAllback ist und wie eine entsprechende AHA Callbackfunktion
Bei der Realisierung Deines Code empfehle ich Dir 2 Etappen:
1. Die AHA Funktionalitaet fehlerfrei abarbeiten.
2. Das Generieren der Node mit den durch den Buttonklick gesendeten Daten.
=======================================================================================
Da Deine Fragestelung etwas missverstandlich ist entsteht die Frage ob Du ueberhaupt AHAH Form Funktionen brauchst.
------------------------
Quiptime Group
Da geht noch was.
Der 2. Punkt trifft zu. Das
am 10.10.2009 - 14:59 Uhr
Der 2. Punkt trifft zu. Das soll ähnlich ablaufen wie bei den Umfragen. Ein Klick, Daten in den Feldern speichern, neue Zeile hinzufügen usw.
Dann schaue ich mir mal AHAH-Forms an, da ich die wohl benötige.
Danke für den Tipp, ich wusste nämlich nicht, wofür das im Code gut ist und habe es erstmal weggelassen.
Wenn Du nicht voellig Match in der Birne werden willst ...
am 10.10.2009 - 16:00 Uhr
Den Code des Pollmodules als Ausgangspunkt fuer Deine Problemlosung zu nehmen ist nicht die beste Variante. Gerade das Pollmodul hat fuer einen "Aussenstehenden" zunaechst etwas verwirrenden Code der durch Funktionsverschachtelungen schwer zu verstehen ist.
Wenn Du nicht voellig Match in der Birne werden willst ist es eine gute Idee den Pollmodulcode erst Mal bei Seite zu legen. Ich denke nach Deinem Studium der AHA Form Doku benoetigst Du diesen Code nicht mehr. Du kannst dann effizienter eigenen Code produzieren. Glaub mir.
Dein "AHA Code" muss am Ende 2 Dinge tun.
das zusaetzliche/neue Feld an das Formular senden
die mit dem Buttonklick gesendeten Daten verarbeiten
Eventuell hilft Die dieser Code etwas weiter:
<?php
/**
* Implementation of hook_menu().
*/
function my_module_menu() {
$items['foo/bar/my_aha'] = array( // <<<<<<<<< Guckst Du
'page callback' => '_my_module_blabla_ahah',
'type' => MENU_CALLBACK,
'access arguments' => array('was du willst als berechtigung'), // muss aber existieren
);
}
// Snipped zum Formularaufbau
$form['dein_button']['#ahah'] = array(
'path' => 'foo/bar/my_aha', // <<<<<<<<< Guckst Du
'event' => 'change',
'wrapper' => 'my-field-wrapper',
);
// Wenn Du beginnst mit AHAH Daten an das Formular zurueckzusenden und Du bekommst Fehler-Popups
// dann sehe Dir mit Firebug -> Netzwerk an was passiert.
/**
* AHA callback function.
*/
function _my_module_blabla_ahah() {
// Build the new form.
$form_build_id = $_POST['form_build_id'];
$form_state = array();
$form_state = array('storage' => NULL, 'submitted' => FALSE, 'values' => $_POST);
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
// Entnimm $form_state die gesendeten Daten.
// Rufe eine extra Funktion auf, uebergib ihr entweder die entnommenen Daten oder $form_state,
// und fuehre die Speicherung der Daten durch.
// Optional
drupal_set_message(t('Was immer Du dem User nach dem Klich auf den extra Button mitteilen willst'), 'status');
// Hole Dir in einer separaten Funktion den Code fuer das zusaetzliche/neue Formularfeld
$extra_field = module_invoke('my_module', 'get_extra_field');
// oder
// $extra_field = my_module_get_extra_field();
// Delete wrapper element.
// Das Wrapper-Element wird im AHAH menu festgelegt und sollte ein extra div sein das um das eigentliche neue Formularfeld
// gelegt wird. Das div selbst wird beim Aufbau des Formulares mit
// $form['my_field']['#prefix'] = '<div id="my-field-wrapper">'; und
// $form['my_field']['#prefix'] = '</div>';
// definiert.
// An dieser Stelle treffen sich sozusagen des Formular und der von AHAH zurueckgesendete Code.
unset($extra_field['my_field']['#prefix'], $extra_field['my_field']['#suffix']);
// Set the the data for extra field.
$form['my_field'] = $extra_field;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
'#redirect' => FALSE,
);
// Rebuild the form.
// Hier enspricht my_foobar_form der ID Deines Formulares!
$form = form_builder('my_foobar_form', $extra_field, $form_state);
// Wenn obige optionale Message gesetzt wurde dann diesen code
$output = theme('status_messages') . drupal_render($form);
// Wenn nicht dann nur
// $output = drupal_render($form);
print drupal_to_js(array('status' => TRUE, 'data' => $output));
exit();
}
?>
------------------------
Quiptime Group
Da geht noch was.
Danke für deine Hilfe. Ich
am 10.10.2009 - 17:42 Uhr
Danke für deine Hilfe.
Ich habe das soweit implementiert. Aber ich habe ein Problem mit dem Pfad.
Wenn ich my_module/ahah angebe, dann bekomme ich nen Meldung, dass die Seite nicht vorhanden ist. Habe mir das mal angeschaut, was du mir zu AHAH gesagt hast, aber welchen Pfad ich jetzt genau angeben muss, habe ich noch nicht komplett verstanden. Oder muss ich das noch in meinen Modulordner kopieren?
Mal mein Code, vielleicht habe ich ja irgendwo nen Fehler gemacht.
function dublist_menu() {
$items = array();
$items['dublist'] = array(
'title' => 'Dublist',
'page callback' => 'drupal_get_form',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);
$items['dublist/ahah'] = array(
'page callback' => '_dublist_ahah',
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
}
$form['list_wrapper']['add_role'] = array(
'#type' => 'submit',
'#value' => t('More roles'),
'#description' => t("If the amount of roles above isn't enough, click here to add more roles."),
'#prefix' => '<div class="clear-block" id="table-action">',
'#suffix' => '</div>',
'#weight' => 1,
'#submit' => array('dublist_more_entries_submit'), // If no javascript action
'#ahah' => array(
'path' => 'dublist/ahah',
'wrapper' => 'dublist-entries',
'method' => 'replace',
'effect' => 'fade',
),
);
Der Pfad ist der neuralgische Punkt.
am 10.10.2009 - 17:44 Uhr
Der Pfad ist der neuralgische Punkt. Nach meiner Erfahrung kann man nicht irgendeinen beliebigen bilden.
Geeigneten Pfad bilden.
Es kommt darauf an wo Dein Formular "angesiedelt" ist - um einen sach- oder themenbezogenen Pfad zu bilden. Ist es beispielsweise im Bereich user dann kennt Drupal den Pfadbestandteil user und man koennte user/my_was_auch_immer_ahah verwenden.
Ist es im Bereich node angesiedelt koennte man als Pfad node/my_was_auch_immer_ahah verwenden. Denn mit node kann Drupal etwas anfangen.
Eine Idee ist, Du siehst Dir die URL an wenn Du das Formular im Browser vor Dir hast.
Im Beispiel "im Bereich User angesiedelt" koennte man auch im Pfad die User ID abbilden. Also user/%/my_was_auch_immer_ahah. Dadurch kann man % als arg(1) der Callbackfunktion uebergeben und kann im Callbackcode bezug auf den User nehmen.
------------------------
Quiptime Group
Da geht noch was.
Ist ein Inhaltstyp. Denke
am 10.10.2009 - 17:46 Uhr
Ist ein Inhaltstyp. Denke mal, dass wird dann node sein. Node steht auch hinter der url. Also so url/node/XY
Im Post über deinem habe ich mal meinen aktuellen Code angeben. Könnte ja auch nen Fehler sein.
Dann probiere ich mal node/dublist/ahah
Ich muss mich an einer
am 10.10.2009 - 17:52 Uhr
Ich muss mich an einer Stelle korrigieren. Und zwar dabei das Du ja ein weiteres Formfeld mit jedem Buttonklick hinzufuegen willst. Deswegen nicht das Wrapper div um das Feld herum sondern unter das Feld welches im aufgerufenen Formular bereits existiert und unter jedes zusaetzliche Formfeld das mit AHAH gesendet wird.
Aus diesem Grund entfaellt in meinem vorhin gepostetetn Code auch das unset() des Wrapper div's.
Moment ich schreibe noch etwas zu Deinem letzten Code.
------------------------
Quiptime Group
Da geht noch was.
Macht das mit dem Pfad
am 10.10.2009 - 17:53 Uhr
Macht das mit dem Pfad eigentlich nen Unterschied, ob das Module in root/module oder in root/sites/all/modules liegt?
Zu Deinem
am 10.10.2009 - 18:16 Uhr
Zu Deinem Code.
<?php
function dublist_menu() {
$items = array();
$items['dublist'] = array(
'title' => 'Dublist',
'page callback' => 'drupal_get_form',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);
$items['dublist/ahah'] = array(
'page callback' => '_dublist_ahah',
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items; // Hast Du das?
}
?>
access arguments = 'access content' ist nicht so guenstig. Wenn Dein AHAH functioniert aendere das auf eine Berechtigung im Zusammenhang mit Nodes editieren. Zum Entwickeln ist es aber ok weil es eine sehr allgemeine Berechtigung ist.
<?php
$form['list_wrapper']['add_role'] = array(
'#type' => 'submit',
'#value' => t('More roles'),
'#description' => t("If the amount of roles above isn't enough, click here to add more roles."),
'#prefix' => '<div class="clear-block" id="table-action">',
'#suffix' => '</div>',
'#weight' => 1,
'#submit' => array('dublist_more_entries_submit'), // If no javascript action
'#ahah' => array(
'path' => 'dublist/ahah',
'wrapper' => 'dublist-entries',
'method' => 'replace',
'effect' => 'fade',
),
);
?>
Das ist aber Code aus einer anderen Funktion, richtig?
<?php
'#prefix' => '<div class="clear-block" id="table-action">',
'#suffix' => '</div>',
?>
ist hier wohl eher nicht der richtige Platz. Das bedeutet die zusaetzlichen Felder werden von AHA unter/am Submit Button eingefuegt.
Besser ist das Formelement des Feldes, das jeweils als weiteres zusaetzliches Feld verwendet wird, fuer das Platzieren des Wrapper div zu nutzen.
Im Zusammenhang mit meinem vorigen Post und meiner Korrektur waere auch nur ein Suffix notwendig um unter dem in Frage kommenden Feld bei jedem Buttonklick ein weiteres Feld hinzuzufuegen.
<?php
$form['das_bewuste_feld']['#suffix'] = '<div id="dublist-entries"></div>'; // entsprich dem Wrapper in #ahah
?>
Genau diesen Suffix muss jedes weitere von AHA gesendete Feld haben.
Wie lautet der Code Deiner AHAH Callbackfunktion? Kannst Du ihn der Vollstaendigkeit halber noch posten?
------------------------
Quiptime Group
Da geht noch was.
pewiha schrieb Macht das
am 10.10.2009 - 18:15 Uhr
Macht das mit dem Pfad eigentlich nen Unterschied, ob das Module in root/module oder in root/sites/all/modules liegt?
Nein.
------------------------
Quiptime Group
Da geht noch was.
Hattest recht. Die Rückgabe
am 10.10.2009 - 18:33 Uhr
Hattest recht. Die Rückgabe fehlte bei der Menüfunktion. Die Form für den Button war aus einer anderen Methode, hätte ich vielleicht dazuschreiben sollen.
Jetzt bekomme ich keinen Fehler mehr durch das AHAH, wenn ich auf den Button klicke. Zumindest bleibt schon mal der Text in den Feldern erhalten.
Eigentlich kann jetzt nur noch im AHAH Callback oder in der 2. Methode, die ich poste sein.
function _dublist_ahah() {
include_once drupal_get_path('module', 'node') . '/node.pages.inc';
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
// We will run some of the submit handlers so we need to disable redirecting.
$form['#redirect'] = FALSE;
// We need to process the form, prepare for that by setting a few internals
// variables.
$form['#post'] = $_POST;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
// Build, validate and if possible, submit the form.
drupal_process_form($form_id, $form, $form_state);
// This call recreates the form relying solely on the form_state that the
// drupal_process_form set up.
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
// Render the new output.
$entry_form = $form['list_wrapper']['list_entry'];
unset($entry_form['#prefix'], $entry_form['#suffix']); // Prevent duplicate wrappers.
$output = theme('status_messages') . drupal_render($entry_form);
drupal_json(array('status' => TRUE, 'data' => $output));
}
function dublist_more_entries_submit($form, &$form_state) {
// Set the form to rebuild and run submit handlers.
node_form_submit_build_node($form, $form_state);
// Make the changes we want to the form state.
if ($form_state['values']['add_role']) {
$n = $_GET['q'] == 'dublist/ahah' ? 1 : 2;
$form_state['entry_count'] = count($form_state['values']['counter']) + $n;
}
}
Bevor ich auf den Code
am 10.10.2009 - 19:04 Uhr
Bevor ich auf den Code Deines AHAH Callback eingehe noch etwas Grundsaetzliches.
Wenn es einen finalen Submit gibt dann musst Du doch nicht beim Klick auf den zusaetzlichen Button die gesendeten Daten im ablaufenden AHAH Callback speichern. Die Daten der zusaetzlich eingefuegten Felder koennen doch mit dem finalen Submit gespeichert werden. Oder sehe ich das nicht richtig?
Wenn ich es richtig sehe dann hat Dein zusaetzlicher Button die Funktionalitaet "Add more" - bezogen auf ein bestimmtes Feld. Und deswegen beschraenkt sich die AHA Funktionalitaet auf das Senden eines leeren Feldes.
Kannst Du meine Sicht betstaetigen?
------------------------
Quiptime Group
Da geht noch was.
Das Speichern kann mit dem
am 10.10.2009 - 19:12 Uhr
Das Speichern kann mit dem finalen Submit passieren, da hast du Recht.
Mit dem Button "Add more" wird dann eine neue Zeile mit leeren Eingabefeldern erzeugt. Später sollen dann noch zwei Felder hinzukommen, in denen Einträge aus einer Datenbank geladen werden, so dass man dann über eine Select Liste sich den entsprechenden Eintrag raussuchen kann.
Das mit dem Speichern soll also nicht über diesen Button erfolgen. Hoffe eigentlich nicht, dass ich das auch noch über meinen Button lösen muss.
Ok, wobei das Speichern von
am 10.10.2009 - 19:28 Uhr
Ok, wobei das Speichern von Daten bei Klick auf den zusaetzlichen Button absolut kein Problem darstellt.
Da Du Deine Daten, egal aus wievielen Feldern des Formulares, mit dem finalen Submit speicherst vereinfacht dies die AHAH Callback Funktion etwas. Auch in diesem Zusammenhang korrigiert sich mein Post mit dem Beispielcode eines AHAH Callbacks.
Da Du von weiteren Feldern sprichst folgender Hinweis fuer Dein Formular-Layout. Mit AHA kann man nur EINEN Bereich an EIN Wrapperelement zuruecksenden. Das bedeutet Du kannst mit AHAH Forms innerhalb eines einzelnen Callbacks nicht 2 verschiedene Felder an 2 verschiedene Positionen im Formular zuruecksenden. In solch einem Fall muss man das gesamte Formural mit AHA neu aufbauen (das Wrapperelement ist das Formular selbst) - oder die 2 Felder stehen hintereinander und man kann sie dadurch an ein einzelnes Wrapper(element) div senden.
Moment, geht gleich weiter.
------------------------
Quiptime Group
Da geht noch was.
Ich hatte das wie beim
am 10.10.2009 - 19:36 Uhr
Ich hatte das wie beim Poll-Modul vor. Da werden ja auch jedes 2 Mal zwei neue Felder hinzugefügt.
Wenn das mit dem Speichern kein Problem ist, kann ich das gerne einbauen, als Sicherheitsfunktion, damit sich nachher niemand ärgert, wenn durch nen dummen Fehler etwas mehrmals eingetragen werden muss. ^^
Bevor ich auf die AHA
am 10.10.2009 - 19:53 Uhr
Bevor ich auf die AHA Callback funktion eingehe folgendes Wichtiges im Zusammenhang mit dem Einfuegen zusaetzlicher Felder und und der Submit Funktion des finalen Submit.
Dein vorhandenes Feld muss mit dem Hinzufuegen weiterer Felder als Array behandelt werden. Wen dem nicht so ist wird in der $form Variable der Wert des Feldes bei jedem Klick fuer ein weiteres Feld mit dem Inhalt des weiteren Feldes ueberschrieben. Das weitere Feld ist leer - alles klar?
Diesen Umstand musst Du in jedem Fall in Deiner Formularlogik beachten. Zum Einen beim Aufruf des Formulares und zum Anderen beim Speichern des Formulares.
Der "Array-Prozess" des Feldes wird in der AHAH Callbackfunktion realisiert.
Wenn nun der finale Submit (
dublist_more_entries_submit($form, &$form_state)
) ausgefuehrt wird ist in $form_state Dein Feld ein Array und Du kannst die Daten innerhalb einer Schleife aufnehmen und dem Speicher- bzw. Vearbeitungsvorgang zufuehren.Dies wird auch vom Pollmodul realisiert. Poll fuehrt sogar einen extra Counterfeld
$form_state['values']['counter']
. Darauf kannst Du unter Umstaenden in Deinem Code verzichten.------------------------
Quiptime Group
Da geht noch was.
pewiha schrieb Ich hatte
am 10.10.2009 - 19:57 Uhr
Ich hatte das wie beim Poll-Modul vor. Da werden ja auch jedes 2 Mal zwei neue Felder hinzugefügt.
Zwei oder mehr Felder am Stueck sind kein Problem wenn sie an einem einzelnen Wrapper-Element von AHAH eingefuegt werden. Ich wollte lediglich auf das Thema "getrennter" Felder hinweisen.
------------------------
Quiptime Group
Da geht noch was.
Danke für deine zahlreichen
am 10.10.2009 - 20:48 Uhr
Danke für deine zahlreichen Tipps.
Hast du noch Feedback zu meiner AHAH-Methode? Oder hattest du das schon abgegeben? :)
Nein, habe mich zu Deinem
am 10.10.2009 - 21:02 Uhr
Nein, habe mich zu Deinem AHA Callback noch nicht geaeussert. Dazu habe ich auf Grund meiner zusaetzlichen Infos Feedback hinsichtlich dessen erhofft was Du fuer ein Formular aufbaust und welche Daten damit final gespeichert werden. Das ist mir nicht so ganz klar. Mit diesem Wissen koennte ich ziemlich konkret auf den AHA Callbackcode eingehen.
------------------------
Quiptime Group
Da geht noch was.
Also ich plane am Ende eine
am 10.10.2009 - 21:24 Uhr
Also ich plane am Ende eine Sprecherliste zu erstellen. Bisher habe ich nur 2 Felder, wenn ich das mit den beiden Feldern hinbekommen habe, baue ich die anderen Felder ein.
Wenn auf meinen Button geklickt wird, soll dann eine neue Zeile generiert werden, in der weitere Einträge vorgenommen werden können. Wenn man sich einen Film oder eine Serie anguckt, dann spielen da je eine Menge Personen mit und nicht nur ein oder zwei. Von daher soll man soviele Sprecher hinzufügen können, wie man braucht. Für jeden neuen Sprecher wird dann einmal auf den Button geklickt. Gespeichert werden sollen natürlich alle Einträge, die in dieser Zeile gemacht werden sollen. Wie du vielleicht gemerkt hast, habe ich mich deshalb auch am Poll-Modul orientiert. Weil es da halt ne horizontale Ansicht der einzelnen Punkte gibt und es im Prinzip auch das macht, was ich am Ende benötige.
Momentan habe ich im Formular ein Feld für die Rollenbezeichnung und Bemerkungen. Hinzu kommen soll noch ein Feld für den deutschen Sprecher und den Sprecher, der Originalfassung. Die Sprecher wollte ich aus einer Datenbank auslesen und über eine Select-Liste anzeigen lassen.
In diesem Thread habe ich im letzten Beitrag ein Bild eingefügt. Damit du dir vorstellen kannst, was da am Ende rauskommen soll. http://www.drupalcenter.de/node/17959
Ich hoffe, es ist jetzt klarer geworden, was mein Ziel ist.
Aha,es geht bei dem AHAH
am 11.10.2009 - 03:00 Uhr
Aha,es geht bei dem AHAH Callback also nicht um ein einzelnes Feld sondern um eine Gruppe von Feldern.
Das diese in einer Zeile stehen ist eine Frage von CSS.
Empfehlenswert ist, fuer diese Gruppe von Feldern eine separate (Hilfs)Funktion zu erstellen. Auch wenn das eigentliche Formular aus mehr Feldern besteht, der finale Submitbutton ist mindestens eines dieser Mehrfelder, wuerde ich das eigentliche Formular innerhalb einer Funktion bilden und zum Fuellen der Formvariable aus dieser Funktion herau die Funktion aufrufen welche die Feldgruppe bildet die Du auch mit jedem AHA Callback brauchst.
Somit wird Deine (Hilfs)Funktion zweifach genutzt. Einmal zur Bildung des initialen Formulares und ein Andermal von dem AHA Callback damit Du je Klick die Grupe der weiteren Felder (Add more) bilden kannst.
Hier der Code fuer die Darstellung der AHAH Zusammenhaenge. Er ist nicht vollstaendig im Sinne des Gesamtvorganges.
<?php
/**
* Implementation of hook_menu().
*/
function dublist_menu() {
$items = array();
// Other menu items.
// ......
$items['node/dublist_ahah'] = array(
'page callback' => '_dublist_ahah',
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
/**
* Implementation of hook_form().
*/
function dublist_form(&$node, $form_state) {
$form = array;
form['studio'] array(
'#type' => 'select',
'#title' => 'Studio',
'#options' => array(
'1' => 'Studio Foo',
'2' => 'Studio Bar',
);
//'#default_value' => , // muss belegt werden fuer den Editmodus
form['native_version'] array(
'#type' => 'select',
'#title' => 'Native version',
'#options' => array(
'1' => 'German',
'2' => 'Japanese',
);
//'#default_value' => , // muss belegt werden fuer den Editmodus
);
$form['add_more'] = array(
'#type' => 'submit',
'#value' => 'Add more',
'#ahah' => array(
'path' => 'node/dublist_ahah',
'wrapper' => 'dublist-entries-wrapper',
),
);
$form['my_fields'] = module_invoke('dublist', 'extra_fields')
$form[submit] = array(
'#type' => 'submit',
'#value' => 'Save',
);
return $form;
}
/**
* Helper function. Called from dublist_form() and _dublist_ahah().
*/
function dublist_extra_fields() {
$form = array();
$form['my_fields'] => array(
'#type' => 'fieldset',
'#collapsible' => FALSE',
'#tree' => TRUE,
'#suffix' => '<div id="dublist-entries-wrapper"></div>',
);
$form['my_fields']['role'] array(
'#type' => 'text',
'#title' => 'Rolle',
//'#default_value' => , // muss belegt werden fuer den Editmodus
);
$form['my_fields']['german_speaker'] array(
'#type' => 'select',
'#title' => 'German speaker',
'#options' => array(
'1' => 'ein Sprecher',
'2' => 'anderer Sprecher',
);
//'#default_value' => , // muss belegt werden fuer den Editmodus
form['my_fields']['native_speaker'] array(
'#type' => 'select',
'#title' => 'Native speaker',
'#options' => array(
'1' => 'ein Sprecher',
'2' => 'anderer Sprecher',
);
//'#default_value' => , // muss belegt werden fuer den Editmodus
);
$form['my_fields']['role'] array(
'#type' => 'text',
'#title' => 'Rolle',
//'#default_value' => , // muss belegt werden fuer den Editmodus
);
form['my_fields']['role_function'] array(
'#type' => 'select',
'#title' => 'Native speaker',
'#options' => array(
'1' => 'eine Funktion',
'2' => 'andere Funktion',
);
//'#default_value' => , // muss belegt werden fuer den Editmodus
);
$form['my_fields']['delete'] array(
'#type' => 'checkbox',
'#title' => 'Delete role',
'#default_value' => 0,
);
return $form;
}
/**
* AHA callback function.
*/
function _dublist_ahah() {
// Build the new form.
$form_build_id = $_POST['form_build_id'];
$form_state = array();
$form_state = array('storage' => NULL, 'submitted' => FALSE, 'values' => $_POST);
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
// Get the data for add more fields.
$add_fields = module_invoke('dublist', 'extra_fields');
// Set the the data for add more fieldset.
$form['my_fields'][] = $add_fields;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
'#redirect' => FALSE,
);
// Rebuild the form.
$form = form_builder('dublist_form', $add_fields, $form_state);
$output = drupal_render($form);
print drupal_to_js(array('status' => TRUE, 'data' => $output));
exit();
}
/**
* Validation function for the dublist editing form.
*/
function dublist_form_validate($form, &$form_state) {
}
/**
* Submit function for the dublist editing form.
*/
function dublist_form_submit($form, &$form_state) {
}
?>
------------------------
Quiptime Group
Da geht noch was.
Vielen Dank. Habe mein Modul
am 11.10.2009 - 11:52 Uhr
Vielen Dank. Habe mein Modul mal dementsprechend umgestellt, nachdem ich nachvollzogen hatte, was in deinem Code vorgeht.
Irgendetwas scheine ich aber falsch gemacht zu haben, denn ich sehe am Anfang überhaupt keine Felder für Rolle und Bemerkungen. Anscheinend müsste ich noch die Themefunktion umbasteln. Oder sehe ich das falsch?
Ich hätte das im Vorfeld ja gerne mit CSS gemacht, aber überall, wo ich nachgelesen hatte, fand ich keinen Anknüpfpunkt um das auf das Editierfenster anzuwenden.
Hier hat sich ein Fehler eingeschlichen
am 11.10.2009 - 12:04 Uhr
Hier hat sich ein Fehler eingeschlichen:
<?php
$form['my_fields'] = module_invoke('dublist', 'extra_fields')
?>
Besser so:
<?php
$form = module_invoke('dublist', 'extra_fields');
?>
Denn 'my_fields' wird ja bereits in der Hilfsfunktion dublist_extra_fields() gebildet.
Eventuell loest das bereits das Problem.
Was die Frage nach der Themefunktion betrifft kann ich Dir schlecht raten da ich den gesamten Code Deines Modules nicht kenne.
------------------------
Quiptime Group
Da geht noch was.
Also irgendwas scheint mit
am 11.10.2009 - 12:36 Uhr
Also irgendwas scheint mit dem AHAH immer noch nicht zu klappen. Wenn ich auf den Button klicke, dann werden keine neuen Felder erzeugt. Ich kopiere am besten mal meinen Modulcode. Die Titelzeile wird irgendwie auch nicht mehr angezeigt...
<?php
/* $Id$ */
/**
* @file
* Dublist Module
*/
/**
* implementation of hook_help().
*/
function dublist_help($path, $arg) {
if ($path == 'admin/help#dublist') {
$txt = 'A dublist is a list, which belongs '
.'to a film or a series. In this kind of list'
.'the speakers of series roles are contained '
;
$replace = array();
return '<p>'. t($txt, $replace) .'</p>';
}
}
/**
* Implements hook_node_info().
*/
function dublist_node_info() {
return array(
'dublist' => array(
'name' => t('Dublist'),
'module' => 'dublist',
'description' => t('A dublist of a film or series.'),
'has_title' => TRUE,
'title_label' => t('Title'),
'has_body' => TRUE,
//'body_label' => t('Body'),
)
);
}
/**
* Implementation of hook_menu().
*/
function dublist_menu() {
$items = array();
/*$items['dublist'] = array(
'title' => 'Dublist',
'page callback' => 'drupal_get_form',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);*/
$items['dublist/ahah'] = array(
'page callback' => '_dublist_ahah',
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
/**
* Implementation of hook_form().
*/
function dublist_form(&$node, $form_state) {
// Existing files: title (Title) and body (body)
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -4,
);
}
$form = module_invoke('dublist', 'entries');
// The button to add more roles.
$form['add_role'] = array(
'#type' => 'submit',
'#value' => t('More roles'),
'#description' => t("If the amount of roles above isn't enough, click here to add more roles."),
'#weight' => -1,
'#ahah' => array(
'path' => 'dublist/ahah',
'wrapper' => 'dublist-entries',
'method' => 'replace',
'effect' => 'fade',
),
);
return $form;
}
/**
* Menu callback for AHAH additions.
*/
function _dublist_ahah() {
$form_state = array('storage' => NULL, 'submitted' => FALSE, 'values' => $_POST);
$form_build_id = $_POST['form_build_id'];
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
// Get the data for add more fields.
$add_fields = module_invoke('dublist', 'entries');
// Set the the data for add more fieldset.
$form['dublist_wrapper'][] = $add_fields;
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
'#redirect' => FALSE,
);
// Rebuild the form.
$form = form_builder('dublist_form', $add_fields, $form_state);
$output = drupal_render($form);
drupal_json(array('status' => TRUE, 'data' => $output));
}
/**
* Help function
*/
function dublist_entries(){
$form = array();
// The wrapper for the input
$form['dublist_wrapper'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#weight' => -2,
'#suffix' => '<div id="dublist-entries-wrapper"></div>',
);
$form['dublist_wrapper']['role'] = array(
'#type' => 'textfield',
'#size' => 30,
'#maxlengh' => 100,
'#title' => t('Role'),
'#description' => t('A role.'),
'#default_value' => isset($node->role) ? $node->role : '',
);
$form['dublist_wrapper']['note'] = array(
'#type' => 'textfield',
'#size' => 50,
'#maxlengh' => 100,
'#title' => t('Note'),
'#description' => t('The notes auf this role.'),
'#default_value' => isset($node->note) ? $node->note : '',
);
return $form;
}
/**
* Implements hook_perm()
*/
function dublist_perm() {
return array(
'create dublist node',
'edit dublist nodes',
'delete dublist nodes',
);
}
/**
* Implements hook_access()
*/
function dublist_access($op, $node, $account) {
switch ($op) {
case 'create':
return user_access('create dublist node', $account);
case 'update':
return user_access('edit dublist nodes', $account);
case 'delete':
return user_access('delete dublist nodes', $account);
}
}
?>
Wenn ich den AHAH-Pfad eintippe, erhalte ich folgendes:
{ "status": true, "data": "\x3cfieldset\x3e\x3cdiv class=\"form-item\" id=\"edit-dublist-wrapper-role-wrapper\"\x3e\n \x3clabel for=\"edit-dublist-wrapper-role\"\x3eRolle: \x3c/label\x3e\n \x3cinput type=\"text\" maxlength=\"128\" name=\"dublist_wrapper[role]\" id=\"edit-dublist-wrapper-role\" size=\"30\" value=\"\" class=\"form-text\" /\x3e\n \x3cdiv class=\"description\"\x3eEine Rolle\x3c/div\x3e\n\x3c/div\x3e\n\x3cdiv class=\"form-item\" id=\"edit-dublist-wrapper-note-wrapper\"\x3e\n \x3clabel for=\"edit-dublist-wrapper-note\"\x3eBemerkung: \x3c/label\x3e\n \x3cinput type=\"text\" maxlength=\"128\" name=\"dublist_wrapper[note]\" id=\"edit-dublist-wrapper-note\" size=\"50\" value=\"\" class=\"form-text\" /\x3e\n \x3cdiv class=\"description\"\x3eThe notes auf this role.\x3c/div\x3e\n\x3c/div\x3e\n\x3c/fieldset\x3e\n\x3cdiv id=\"dublist-entries-wrapper\"\x3e\x3c/div\x3e" }
Wrapper-Angaben stimmen nicht ueberein
am 11.10.2009 - 12:53 Uhr
Die Wrapper-Angabe im Hook Menu und in der Funktion dublist_entries() stimmen nicht ueberein.
<?php
'#ahah' => array(
'path' => 'dublist/ahah',
'wrapper' => 'dublist-entries', // <<<<<<<<<<<<<
'method' => 'replace',
'effect' => 'fade',
),
);
?>
<?php
$form['dublist_wrapper'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#weight' => -2,
'#suffix' => '<div id="dublist-entries-wrapper"></div>', // <<<<<<<<<<<<<
);
?>
------------------------
Quiptime Group
Da geht noch was.
einzelne Rollen-Felder mit CSS platzieren
am 11.10.2009 - 13:03 Uhr
Fuer die einzeilige Anzeige der Rollen-Felder, formatiert mit CSS, wirst Du durch den Formularcode "Unterstuetzung" benoetigen.
Hier die Erweiterung des Fieldset welches die Rollenfelder enthaelt - mit einer zusaetzlichen CSS Klasse.
<?php
$form['dublist_wrapper'] = array(
'#type' => 'fieldset',
'#attributes' => array('class' => 'clear-block'); // Damit Floating's das Layout stehen lassen
'#tree' => TRUE,
'#weight' => -2,
'#suffix' => '<div id="dublist-entries-wrapper"></div>',
);
?>
------------------------
Quiptime Group
Da geht noch was.
Firebug -> Konsole -> Netzwerk
am 11.10.2009 - 13:10 Uhr
Also irgendwas scheint mit dem AHAH immer noch nicht zu klappen. Wenn ich auf den Button klicke, dann werden keine neuen Felder erzeugt
Ob ein AHAH Callback ueberhaupt etwas sendet kann man prima mit dem Firebug -> Konsole -> Netzwerk pruefen.
------------------------
Quiptime Group
Da geht noch was.
Danke, stimmt, die Stelle
am 11.10.2009 - 13:11 Uhr
Danke, stimmt, die Stelle hatte ich übersehen.
Momentan kann ich leider nur einen weiteren Eintrag erzeugen. Klicke ich das 2. Mal auf den Button, werden die Daten aus dem 2. Feld gelöscht, aber kein drittes angezeigt.
Brauche ich jetzt doch nen Counter, oder kann man das noch so ausweiten, dass man beliebig viele Felder erzeugen kann? Die Titelzeile ist leider immer noch weg.
Das mit dem CSS schaue ich mir später an, erstmal soll es funktionieren, danach kann das Design kommen.
Modul Devel
am 11.10.2009 - 13:44 Uhr
Titelzeile spaeter.
Warum der AHAH Callback nur ein Feld platziert, also kein 3. Feld anzeigt, und auch noch die Daten des vorher eingefuegten 2. Feldes loescht sind 2. verschiedene Sachen mit verschiedenen Loesungen.
Weitere Felder ist eine Wrapper-Problematik
Das leere 2. Feld haengt damit zusammen das nach dem Klick fuer das 3. Feld die Daten des 2. Feldes zwar an den Callback gesendet werden aber durch den Callback Code in der aktuellen Form nicht wieder an das Formular zurueckgesendet werden.
Mit anderen Worten:
1. Klick baut 2. zusaetzliches Feld
2. Feld wird ausgefuellt
2. Klick fuer 3. Feld sendet Daten des 2. Feldes anAHAH Callback
Im Callback stecken Daten des 2. Feldes in $formstate und muessen zusammen mit dem neuen 3. Feld an die Form gesendet werden.
Hier die Stelle wo im Callback die Daten aufbereitet werden:
<?php
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state); // <<< das "alte" Formular
// Get the data for add more fields.
$add_fields = module_invoke('dublist', 'entries');
// Set the the data for add more fieldset.
$form['dublist_wrapper'][] = $add_fields;
form_set_cache($form_build_id, $form, $form_state); // <<< das "neue" Formular, nach weiterem Klick ist es das "alte"
?>
Verstehst Du den Zusammenhang und die Bedeutung der Codestellen "altes" und "neues" Formular?
============================================================================
Ich hoffe Du arbeitest mit dem Devel Modul. Ist es aktiv kann man folgendes tun:
<?php
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);
// Inhalte der Form Variablen ansehen
//dsm($form_state);
//dsm($form);
// Get the data for add more fields.
$add_fields = module_invoke('dublist', 'entries');
// Set the the data for add more fieldset.
$form['dublist_wrapper'][] = $add_fields;
// Inhalte der Form Variablen ansehen
//dsm($form);
form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
'#redirect' => FALSE,
);
// Rebuild the form.
$form = form_builder('dublist_form', $add_fields, $form_state);
$output = drupal_render($form);
// Inhalte der Form Variablen ansehen
dsm($form);
?>
Um Devel Output aus einem AHA Callback heraus angezeigt zu bekommen muss man (unter Umstaenden) den Cache leeren. Auch dabei ist das Devel Modul hilfreich. Aktiviere den Devel-Block. Er enthaelt einen Link: Cache leeren.
============================================================================
Nun kannst Du Dir ein Bild verschaffen zu welchem Zeitpunkt was in den beiden Formular-Variablen $form und $form_state enthalten ist. Daraus abgeleitet kannst Du Entscheidungen treffen bezueglich dessen was im Callback-Code passieren (noch) muss.
------------------------
Quiptime Group
Da geht noch was.
Ich habe das Developer Modul
am 11.10.2009 - 14:36 Uhr
Ich habe das Developer Modul installiert gehabt, aber ich werde nicht aus den vielen Optionen schlau.
Ich habe mal den dublist_wrapper eintrag gefunden und angeschaut.
Das erste Mal, steht bei ihm nur role und note drin. Beim 2. Aufruf auch noch ne 0, unter der dann ebenfalls ein dublist_wrapper Element liegt.
Daher vermute ich mal, dass beim 2. Klicken des Buttons, es nicht mehr in das Array eingetragen wird. Aber mir fehlt das Verständnis, was mir im Developer Modul alles angezeigt wird, nachdem ich die dsm($form); Aufrufe eingebaut habe.
Weiß jetzt nicht, ob man ne
am 11.10.2009 - 16:50 Uhr
Weiß jetzt nicht, ob man ne Bearbeitung mitbekommt.
Aber dsm($form_state) zeigt mir an, das mir die Einträge des 1. und 2. Eintrags gespeichert werden. Wieso ich jetzt kein drittes Feld bekomme ist mir immer noch schleierhaft.
Wie schon oben geschrieben, fehlt vielleicht bei irgendwo eine Zählvariable?
Vielleicht hier?
$form['dublist_wrapper'][] = $add_fields;
Ist echt zum Verzweifeln, dabei fehlt mir wohl nur noch nen ganz kleines Detail?
Wenn jemand mir sagen kann, welche Einträge er vom Developer Modul braucht, kann ich das gerne posten.
Wo könnte denn der Fehler liegen, wenn es ein Wrapperfehler ist?
Zitat: Aber
am 11.10.2009 - 16:43 Uhr
Aber dsm($form_state) zeigt mir an, das mir die Einträge des 1. und 2. Eintrags gespeichert werden.
Das bedeutet nicht zwingend das der Inhalt des 2. Feldes bereits gespeichert ist. Es wurde ja noch nicht der finale Submit geklickt. Es gibt keinen Speichervorgang der den Wert des 2. Feldes (im Verlauf des AHAH Callbacks) speichert? Oder gibt es doch einen?
Es bedeutet das der Inhalt des 2. Feldes gesendet wurde.
Du musst nach einem Add more Klick die Werte der Felder in $form pruefen. Das was in $form existiert ist das was bei einem Add more Klick an den AHA Callback geschickt wird und sich dann in $form_state befindet. und
es ist auch das was mit dem finalen Submit an die Submit Funktion geschickt wird und sich dort ebenfalls wieder in $form_state befindet.
Um die Add more Funktionalitaet zu pruefen ist also das was nach dem AHA Callback in $form existiert der Dreh- und Angelpunkt.
Nun zum Problem mit einem weiteren (3.) Feld nach einem weiteren Add more Klick.
1. Das Feld muss im Formular erscheinen. Das klappt nur wenn das Wrapper div am 2. Feld korrekt existiert.
Bitte pruefe das Wrapper div nach einem Add more Klick.
2. Was hat $form (nicht $form_state) fuer einen Inhalt nach dem Add more Klick fuer das 3. Feld?
Interessant ist dabei der Wert/die Werte des 1. und 2. und 3. Feldes.
------------------------
Quiptime Group
Da geht noch was.
Also ich habe jetzt mal die
am 11.10.2009 - 18:10 Uhr
Also ich habe jetzt mal die Form nach der Neubildung überprüft und auf Vorschau geklickt.
Siehe da, es werden dort 3 Einträge jeweils von Rolle und Bemerkungen angezeigt, ohne das da jetzt Werte drinstehen.
Alle Einträge sind auch komplett vor dem schließenden dublist-entries-wrapper. Mir fiel dabei aber auf, dass es keinen öffnenden Eintrag für den wrapper gibt. Ist das so normal?
Nachfolgend ein Auszug aus Firebug, wie das für einen Eintrag aussieht, weiß nicht, ob du damit was anfangen kannst.
<span id="thmr_6" class="thmr_call">
<span id="thmr_5" class="thmr_call">
<fieldset>
<span id="thmr_1" class="thmr_call">
<div id="edit-dublist-wrapper-role-wrapper" class="form-item">
<label for="edit-dublist-wrapper-role">Rolle: </label>
<input id="edit-dublist-wrapper-role" class="form-text" type="text" value="" size="30" name="dublist_wrapper[role]" maxlength="128"/>
</div>
</span>
<span id="thmr_3" class="thmr_call">
<div id="edit-dublist-wrapper-note-wrapper" class="form-item">
<label for="edit-dublist-wrapper-note">Bemerkung: </label>
<input id="edit-dublist-wrapper-note" class="form-text" type="text" value="" size="50" name="dublist_wrapper[note]" maxlength="128"/>
</div>
</span>
</fieldset>
</span>
<div id="dublist-entries-wrapper"/>
Jetzt wird es sicher unübersichtlich, aber das sind die drei Rückgaben, die mir das Devel Modul anzeigt. Vielleicht siehst du da, ob es nen unerwarteten Fehler gibt.
*
dublist_wrapper (Array, 23 elements)
o
#type (String, 8 characters ) fieldset
o
#tree (Boolean) TRUE
o
#weight (Integer) -2
o
#suffix (String, 40 characters ) <div id="dublist-entries-wrapper"></div>
o
role (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 30
+
#maxlengh (Integer) 100
+
#title (String, 5 characters ) Rolle
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#weight (Integer) 0
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[role]
+
#id (String, 25 characters ) edit-dublist-wrapper-role
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
note (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 50
+
#maxlengh (Integer) 100
+
#title (String, 9 characters ) Bemerkung
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#weight (Float) 0.001
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[note]
+
#id (String, 25 characters ) edit-dublist-wrapper-note
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
#post (NULL)
o
#programmed (NULL)
o
#parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#array_parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#processed (Boolean) FALSE
o
#description (NULL)
o
#attributes (Array, 0 elements)
o
#required (Boolean) FALSE
o
#collapsible (Boolean) FALSE
o
#collapsed (Boolean) FALSE
o
#value (NULL)
o
#process (Array, 1 element)
+
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
o
#defaults_loaded (Boolean) TRUE
o
#sorted (Boolean) TRUE
o
#title (NULL)
o
#children (String, 624 characters ) <span id="thmr_1" class="thmr_call"> <div cla...
+
<span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span>
o
#printed (Boolean) TRUE
*
#defaults_loaded (Boolean) TRUE
*
#processed (Boolean) FALSE
*
#title (NULL)
*
#description (NULL)
*
#children (String, 734 characters ) <span id="thmr_5" class="thmr_call"> <fieldse...
o
<span id="thmr_5" class="thmr_call"> <fieldset><span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span> </fieldset> </span> <div id="dublist-entries-wrapper"></div>
*
#printed (Boolean) TRUE
*
dublist_wrapper (Array, 23 elements)
o
#type (String, 8 characters ) fieldset
o
#tree (Boolean) TRUE
o
#weight (Integer) -2
o
#suffix (String, 40 characters ) <div id="dublist-entries-wrapper"></div>
o
role (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 30
+
#maxlengh (Integer) 100
+
#title (String, 5 characters ) Rolle
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#weight (Integer) 0
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[role]
+
#id (String, 25 characters ) edit-dublist-wrapper-role
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
note (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 50
+
#maxlengh (Integer) 100
+
#title (String, 9 characters ) Bemerkung
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#weight (Float) 0.001
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[note]
+
#id (String, 25 characters ) edit-dublist-wrapper-note
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
#post (NULL)
o
#programmed (NULL)
o
#parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#array_parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#processed (Boolean) FALSE
o
#description (NULL)
o
#attributes (Array, 0 elements)
o
#required (Boolean) FALSE
o
#collapsible (Boolean) FALSE
o
#collapsed (Boolean) FALSE
o
#value (NULL)
o
#process (Array, 1 element)
+
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
o
#defaults_loaded (Boolean) TRUE
o
#sorted (Boolean) TRUE
o
#title (NULL)
o
#children (String, 624 characters ) <span id="thmr_1" class="thmr_call"> <div cla...
+
<span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span>
o
#printed (Boolean) TRUE
*
#defaults_loaded (Boolean) TRUE
*
#processed (Boolean) FALSE
*
#title (NULL)
*
#description (NULL)
*
#children (String, 734 characters ) <span id="thmr_5" class="thmr_call"> <fieldse...
o
<span id="thmr_5" class="thmr_call"> <fieldset><span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span> </fieldset> </span> <div id="dublist-entries-wrapper"></div>
*
#printed (Boolean) TRUE
*
dublist_wrapper (Array, 23 elements)
o
#type (String, 8 characters ) fieldset
o
#tree (Boolean) TRUE
o
#weight (Integer) -2
o
#suffix (String, 40 characters ) <div id="dublist-entries-wrapper"></div>
o
role (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 30
+
#maxlengh (Integer) 100
+
#title (String, 5 characters ) Rolle
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) role
+
#weight (Integer) 0
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[role]
+
#id (String, 25 characters ) edit-dublist-wrapper-role
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
note (Array, 25 elements)
+
#type (String, 9 characters ) textfield
+
#size (Integer) 50
+
#maxlengh (Integer) 100
+
#title (String, 9 characters ) Bemerkung
+
#default_value (String, 0 characters )
+
#post (NULL)
+
#programmed (NULL)
+
#tree (Boolean) TRUE
+
#parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#array_parents (Array, 2 elements)
#
0 (String, 15 characters ) dublist_wrapper
#
1 (String, 4 characters ) note
+
#weight (Float) 0.001
+
#processed (Boolean) TRUE
+
#description (NULL)
+
#attributes (Array, 0 elements)
+
#required (Boolean) FALSE
+
#input (Boolean) TRUE
+
#maxlength (Integer) 128
+
#autocomplete_path (Boolean) FALSE
+
#process (Array, 1 element)
#
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
+
#name (String, 21 characters ) dublist_wrapper[note]
+
#id (String, 25 characters ) edit-dublist-wrapper-note
+
#value (String, 0 characters )
+
#defaults_loaded (Boolean) TRUE
+
#sorted (Boolean) TRUE
+
#printed (Boolean) TRUE
o
#post (NULL)
o
#programmed (NULL)
o
#parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#array_parents (Array, 1 element)
+
0 (String, 15 characters ) dublist_wrapper
o
#processed (Boolean) FALSE
o
#description (NULL)
o
#attributes (Array, 0 elements)
o
#required (Boolean) FALSE
o
#collapsible (Boolean) FALSE
o
#collapsed (Boolean) FALSE
o
#value (NULL)
o
#process (Array, 1 element)
+
0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
o
#defaults_loaded (Boolean) TRUE
o
#sorted (Boolean) TRUE
o
#title (NULL)
o
#children (String, 624 characters ) <span id="thmr_1" class="thmr_call"> <div cla...
+
<span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span>
o
#printed (Boolean) TRUE
*
#defaults_loaded (Boolean) TRUE
*
#processed (Boolean) FALSE
*
#title (NULL)
*
#description (NULL)
*
#children (String, 734 characters ) <span id="thmr_5" class="thmr_call"> <fieldse...
o
<span id="thmr_5" class="thmr_call"> <fieldset><span id="thmr_1" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-role-wrapper"> <label for="edit-dublist-wrapper-role">Rolle: </label> <input type="text" maxlength="128" name="dublist_wrapper[role]" id="edit-dublist-wrapper-role" size="30" value="" class="form-text" /> </div> </span> <span id="thmr_3" class="thmr_call"> <div class="form-item" id="edit-dublist-wrapper-note-wrapper"> <label for="edit-dublist-wrapper-note">Bemerkung: </label> <input type="text" maxlength="128" name="dublist_wrapper[note]" id="edit-dublist-wrapper-note" size="50" value="" class="form-text" /> </div> </span> </fieldset> </span> <div id="dublist-entries-wrapper"></div>
*
#printed (Boolean) TRUE
Das Du glaubst das oeffnende
am 11.10.2009 - 22:50 Uhr
Das Du glaubst das oeffnende div des Wrapper fehlt ist ein Trugschluss.
<div id="dublist-entries-wrapper"/>
So stellt Firebug ein leeres div dar. Es ist der oeffnende und schliessende Tag zugleich. In der Quelltextansich des Browser sollte das Wrapper div vollstaendig mit oeffnendem und schliessendem Tag zu sehen sein.
Der Rest des Post - der Code der Develausgabe- ist hier an dieser Stelle in dieser Form nicht zu deuten.
Ich vermute folgendes:
Die Werte der $form Variable welche dem/den Add more Feld/Feldern entsprechen werden nicht richtig verwertet bzw. im AHAH nicht richtig angewendet.
Entsinne Dich was ich von der Array-Bildung dieser Werte gesagt habe damit ein Add more klick nicht bestehende Feld-Werte ueberschreibt.
Es ist diese Stelle im AHA Callback:
<?php
// Set the the data for add more fieldset.
$form['my_fields'][] = $add_fields;
?>
Jetzt musst Du mal testen. Lasse mal [] weg und sehe Dir die Dev Ausgaben von $form an nach einem Add more Klick. Eventuell ist die Form API "clever" und bildet selbstaendig Array-Werte eines $form Wertes und es kommt dadurch zu einer richtigen Anwendung der Add more Felder.
Wenn nicht muessen wir weiter sehen.
PS
Wenn Du den Devel Themer abstellst hast Du uebersichtlicheren Code. Die span Tags stoeren irgendwie.
------------------------
Quiptime Group
Da geht noch was.
Also
am 12.10.2009 - 15:04 Uhr
Also $form['dublist_wrapper'] = $add_fields; ändert auch nichts an der Sachlage.
Falls es was hilft anbei was Firebug ausspuckt.
<form id="node-form" enctype="multipart/form-data" method="post" accept-charset="UTF-8" action="/node/63/edit">
<div>
<div class="node-form">
<div class="standard">
<fieldset>
</fieldset>
<div id="dublist-entries-wrapper">
</div>
<fieldset class="menu-item-form collapsible collapsed">
</fieldset>
<input id="edit-add-role" class="form-submit ahah-processed" type="submit" value="More roles" name="op"/>
<input id="edit-changed" type="hidden" value="1255270428" name="changed"/>
<input id="form-8b6f974a42d456334d731638ebfb5fb8" type="hidden" value="form-8b6f974a42d456334d731638ebfb5fb8" name="form_build_id"/>
<input id="edit-dublist-node-form-form-token" type="hidden" value="f3d923df2a6870004507944ecbe90724" name="form_token"/>
<input id="edit-dublist-node-form" type="hidden" value="dublist_node_form" name="form_id"/>
<fieldset class=" collapsible collapsed">
</fieldset>
<fieldset class=" collapsible collapsed">
</fieldset>
<div class="attachments">
</div>
<fieldset class=" collapsible collapsed">
</fieldset>
<fieldset class=" collapsible">
</fieldset>
</div>
<div class="admin">
</div>
<input id="edit-submit-1" class="form-submit" type="submit" value="Speichern" name="op"/>
<input id="edit-preview" class="form-submit" type="submit" value="Vorschau" name="op"/>
<input id="edit-delete" class="form-submit" type="submit" value="Löschen" name="op"/>
</div>
</div>
Wenn ich nur das dsm($form); aufrufe, sehe ich nirgends Einträge über die aktuelle Belegung von $form, $form_state etc. Die bekomme ich erst wenn ich das mit formstate mache. Die Einträge sind alle identisch, daher nur einer, falls es überhaupt etwas bringt.
<?php
*
storage (NULL)
*
submitted (Boolean) FALSE
*
values (Array, 19 elements)
o
dublist_wrapper (Array, 2 elements)
+
role (String, 0 characters )
+
note (String, 0 characters )
o
menu (Array, 3 elements)
+
link_title (String, 0 characters )
+
parent (String, 15 characters ) primary-links:0
+
weight (String, 1 characters ) 0
o
changed (String, 10 characters ) 1255270428
o
form_build_id (String, 37 characters ) form-fae8964603b9f6c083cfeafb37a01b06
o
form_token (String, 32 characters ) f3d923df2a6870004507944ecbe90724
o
form_id (String, 17 characters ) dublist_node_form
o
log (String, 0 characters )
o
print_display (String, 1 characters ) 1
o
print_display_urllist (String, 1 characters ) 1
o
print_pdf_display (String, 1 characters ) 1
o
print_pdf_display_urllist (String, 1 characters ) 1
o
files (Array, 1 element)
+
upload (String, 0 characters )
o
comment (String, 1 characters ) 2
o
pathauto_perform_alias (String, 1 characters ) 1
o
name (String, 6 characters ) pewiha
o
date (String, 25 characters ) 2009-10-10 10:33:56 +0100
o
status (String, 1 characters ) 1
o
sticky (String, 1 characters ) 1
o
op (String, 10 characters ) More roles
?>
Habe mal mein Modul gepackt,
am 16.10.2009 - 22:12 Uhr
Habe mal mein Modul gepackt, samt install und info file. Vielleicht mag es ja jemand anschauen und testen. Wie schon oben geschrieben, ich kann leider nicht mehr als drei Eingabefelder anlegen und die Daten werden auch nicht gespeichert, zumindest in den Feldern.
Hier der Link zum Archiv: http://www.pewiha.kemena-it.com/sites/default/files/dublist.tar