Ich arbeite an einer Ajax-Implementierung für das Webform-Submit auf Drupal 7. Ich konnte nichts Gutes finden hook
, um den Webform-Submit-Button zu ändern und '#ajax' in das Formular einzufügen, also habe ich mir ein Drupal 6-Modul angesehen , das implementiert diese Funktionalität aus einem externen Skript.
Deshalb habe ich mich für mein eigenes Modul und JavaScript-Code entschieden, um eine Ajax-Post-Anfrage an einen benutzerdefinierten Menü-Rückruf zu senden, den ich hook_menu()
in Drupal 7 definiert habe.
Der JavaScript-Teil funktioniert einwandfrei, aber ich habe Probleme beim programmgesteuerten Senden des Webformulars.
Hier ist mein JavaScript-Code:
function formSubmit(event, formId) {
event.preventDefault();
var form = jQuery("#" + formId);
var postData = form.serialize();
var nodeId = formId.substring(20);
var msg = '';
msg += form.find('#edit-submitted-name').attr('value') ? '' : 'Please enter your name';
console.log(form.find('#edit-submitted-name').attr('value'));
console.log(form.find('#edit-submitted-e-mail').attr('value'));
if(msg) {
alert(msg);
} else {
jQuery.ajax({
url: Drupal.settings.basePath + 'webform_ajax/' + nodeId,
fid:formId,
type: 'POST',
data: postData,
success: function(ajaxData) {
console.log(ajaxData);
console.log('Hello world');
// can't get here
}
});
}
}
Und mein Modulcode (basierend auf dem webform_ajax-Modul):
function custom_menu() {
$items = array();
$items['webform_ajax/%'] = array(
'page callback' => '_custom_webform_ajax',
'page arguments' => array(1,2),
'access callback' => '_custom_webform_ajax_access',
);
return $items;
}
function _custom_webform_ajax($nid, $data) {
//$sid = $_POST['details']['sid'];
$local_POST = $_POST;
$form_build_id = $_POST['form_build_id'];
$form_id = 'webform_client_form_' . $nid;
$node = node_load($nid);
$submission = array();
$form_state = array();
$form = form_get_cache($form_build_id, $form_state);
$form_array = drupal_rebuild_form($form_id, $form_state, array($form_state, $node, $submission), $form_build_id);
$form_state['clicked_button'] = $form_array['actions']['submit'];
if (is_array($local_POST['submitted'])) {
foreach ($local_POST['submitted'] as $submit_index => $submit) {
$form_state['storage']['submitted'][$submit_index] = $submit;
$form_state['values']['submitted'][$submit_index] = $submit;
}
}
// Clearing empty values from $form_state
if (is_array($form_state['values']['submitted'])) {
foreach ($form_state['values']['submitted'] as $value_index => $value) {
if (!$value) {
unset($form_state['values']['submitted'][$value_index]);
}
}
}
// Executing the pressed button action
drupal_execute($form_id, $form_state, $node, array());
// Get the HTML for the error messages
$error_html = theme('status_messages', 'error');
// Building the resulting form after the processing of the button
$form_array = drupal_rebuild_form($form_id, $form_state, array($form_state, $node, $submission), $form_build_id);
$form = drupal_render_form($form_id, $form_array);
return drupal_json_output(array(
'message' => $error_html,
'status' => 'sent',
));
}
function _custom_webform_ajax_access() {
// Todo: Add webform access conditions
return true;
}
Wenn ich mein Formular abschicke, erhalte ich 500 Serverfehler.
Ich denke, die D6- und D7-Formular-APIs sind sehr unterschiedlich und ich bin mir nicht sicher, wo ich anfangen soll, damit dieser Code funktioniert. Ich habe versucht, es zu debuggen, aber ich kann nicht herausfinden, was die 500 Fehler erzeugt.
Ich verwende Webform 3 und das Modul, für das ich den Code verwendet habe, basiert ebenfalls auf Version 3 von Webform, jedoch für Drupal 6. Beide Module sollten jedoch dieselben Funktionen und Funktionen bieten. Erste Problemumgehung: Es kann von den Werten kommen, die ich übergebe und die nicht mit D7 form api kompatibel wären.
In meinem Log habe ich:
Argument 1 passed to drupal_array_nested_key_exists() must be an array, null given, called in D:\wamp\www\productionsite\includes\form.inc on line 1986 and defined in drupal_array_nested_key_exists() (line 6296 of D:\wamp\www\productionsite\includes\common.inc).
- BEARBEITEN -
Ich debugge jetzt Zeile für Zeile, am Ende könnte dieser Code es wert sein, ein D7-Modul zu werden;)
Ich habe in der D7-Dokumentation festgestellt , dass sich die Argumente von drupal_rebuild_form () von D6 geändert haben und dass die Argumente $form_state
zu diesem Zeitpunkt nicht mehr leer sein können. Deshalb habe ich meinen Code folgendermaßen aktualisiert:
$form_state = array('submitted' => false, 'values' => array());
$form = form_get_cache($form_build_id, $form_state);
$form_array = drupal_rebuild_form($form_id, $form_state, $form);
Jetzt versuche ich, das Äquivalent von drupal_execute () zu finden, das in D7 nicht mehr existiert.
- Bearbeiten (2) -
Ich habe es vor ein paar Tagen zum Laufen gebracht und komme zurück, um die Lösung zu teilen und vielleicht einige Ratschläge und Verbesserungsvorschläge zu erhalten.
<?php
function custom_menu() {
$items = array();
$items['webform_ajax/%'] = array(
'page callback' => '_custom_webform_ajax',
'page arguments' => array(1,2),
'access callback' => '_custom_webform_ajax_access',
);
return $items;
}
function _custom_webform_ajax($nid, $data) {
$local_POST = $_POST;
$form_build_id = $_POST['form_build_id'];
$form_id = 'webform_client_form_' . $nid;
$node = node_load($nid);
$submission = array();
$form_state = array(
'submitted' => false,
'values' => array(),
'build_info' => array(
'args' => array(
$node,
array(),
FALSE
)
)
);
$form = form_get_cache($form_build_id, $form_state);
$form_array = drupal_rebuild_form($form_id, $form_state);
// Add the clicked button before processing the form
$form_state['clicked_button'] = $form_array['actions']['submit'];
if (is_array($local_POST['submitted'])) {
foreach ($local_POST['submitted'] as $submit_index => $submit) {
$form_state['values']['submitted'][$submit_index] = $submit;
}
}
// Clearing empty values from $form_state
if (is_array($form_state['values']['submitted'])) {
foreach ($form_state['values']['submitted'] as $value_index => $value) {
if (!$value) {
unset($form_state['values']['submitted'][$value_index]);
}
}
}
$form_state['values']['details']['nid'] = $nid;
// Executing the pressed button action
drupal_build_form($form_id, $form_state);
return drupal_json_output(array(
'message' => t('Your submission has been received. Thank you for contacting us.'),
'status' => 'sent',
));
}
function _custom_webform_ajax_access() {
// TODO: Add user role / perm check
return true;
}
Um noch einen Schritt weiter zu gehen, möchte ich jetzt die Fehler aus dem verarbeiteten Formular abrufen, damit ich sie mit dem json-Objekt zurücksenden kann. Irgendwelche Ideen ?