Saya sedang mengerjakan implementasi Ajax untuk pengiriman Webform pada Drupal 7. Saya tidak dapat menemukan yang baik hook
untuk mengubah tombol pengiriman Webform dan menambahkan '#ajax' di formulir jadi saya melihat-lihat modul Drupal 6 yang mengimplementasikan fungsi ini dari skrip eksternal.
Jadi saya memutuskan untuk pergi dengan modul saya sendiri dan kode JavaScript untuk mem-posting permintaan posting Ajax ke callback menu kustom yang telah saya definisikan di hook_menu()
, dalam Drupal 7.
Bagian JavaScript berfungsi dengan baik tetapi saya mengalami masalah saat mencoba mengirimkan Webform secara terprogram.
Ini kode JavaScript saya:
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
}
});
}
}
Dan kode modul saya (berdasarkan modul webform_ajax):
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;
}
Ketika saya mengirimkan formulir saya, saya mendapatkan 500 kesalahan server.
Saya kira API bentuk D6 & D7 sangat berbeda dan saya tidak yakin harus mulai dari mana kode ini bekerja. Saya telah mencoba untuk debug tetapi saya tidak tahu apa yang menghasilkan 500 kesalahan.
Saya menggunakan webform 3 dan modul saya mengambil kode juga bergantung pada versi 3 dari webform tetapi untuk Drupal 6. Tetapi kedua modul harus menyediakan fungsi yang sama dan jenis fungsi yang sama di belakang. Solusi pertama: Mungkin berasal dari nilai yang saya lewati yang tidak akan kompatibel dengan D7 dari api.
Dalam log saya, saya punya:
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).
- EDIT -
Saya sedang men-debug baris demi baris sekarang, pada akhirnya bagian kode ini dapat menjadi modul D7;)
Saya menemukan dalam dokumentasi D7 bahwa argumen drupal_rebuild_form () telah berubah dari D6, dan bahwa argumen $form_state
tidak dapat kosong lagi pada tahap ini, jadi saya memperbarui kode saya dengan cara ini:
$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);
Sekarang saya mencoba untuk menemukan yang setara dengan drupal_execute (), yang tidak ada lagi di D7.
- Edit (2) -
Saya berhasil beberapa hari yang lalu dan kembali untuk berbagi solusi, dan mungkin mendapatkan beberapa saran dan saran perbaikan.
<?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;
}
Untuk melangkah lebih jauh, saya ingin sekarang mendapatkan kesalahan dari formulir yang diproses sehingga saya bisa mengirimnya kembali dengan objek json. Ada ide?
Beri tahu saya jika saya salah tetapi karena pengiriman formulir web adalah simpul, mengapa tidak membuat simpul secara langsung di dalam program Anda
page callback
(dengan validasi bidang (atau dapat dilakukan sebelum mengirim menggunakan javascript))Bisa jadi sesuatu seperti
Dan lagi! :)
sumber