Drupal 7에서 Webform 제출을 위해 Ajax 구현을 작업 중입니다 hook
. Webform 제출 버튼을 변경하고 양식에 '#ajax'를 추가하여 Drupal 6 모듈 을 살펴볼 수있는 좋은 점 을 찾을 수 없었습니다. 외부 스크립트에서이 기능을 구현합니다.
그래서 hook_menu()
Drupal 7에서 정의한 사용자 정의 메뉴 콜백에 Ajax 게시 요청을 실행하기 위해 자체 모듈 및 JavaScript 코드를 사용하기로 결정했습니다 .
JavaScript 부분은 정상적으로 작동하지만 프로그래밍 방식으로 웹 양식을 제출하는 데 문제가 있습니다.
내 JavaScript 코드는 다음과 같습니다.
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
}
});
}
}
그리고 내 모듈 코드 (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;
}
양식을 제출하면 500 서버 오류가 발생합니다.
D6 및 D7 양식 API가 상당히 다르고이 코드를 작동시킬 위치를 잘 모르겠습니다. 디버깅을 시도했지만 500 오류가 발생하는 원인을 알 수 없습니다.
나는 webform 3을 사용하고 코드를 취한 모듈은 webform의 버전 3에 의존하지만 Drupal 6에 의존합니다. 그러나 두 모듈 모두 동일한 기능과 동일한 종류의 기능을 제공해야합니다. 첫 번째 해결 방법 : D7 양식 API와 호환되지 않는 값을 전달할 수 있습니다.
내 로그에 나는 가지고있다 :
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).
-- 편집하다 --
나는 지금 한 줄씩 디버깅하고 있습니다.이 코드는 D7 모듈이 될 가치가 있습니다.)
D7 설명서에서 drupal_rebuild_form () 인수가 D6에서 변경 되었으며이$form_state
단계에서 더 이상 비울 수 없다는 것을 알았으므로 다음 과 같이 코드를 업데이트했습니다.
$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);
이제 D7에 더 이상 존재하지 않는 drupal_execute ()와 동등한 것을 찾으려고합니다.
-편집 (2)-
나는 며칠 전에 일하고 솔루션을 공유하기 위해 돌아 왔으며 조언과 개선 제안을 얻을 수 있습니다.
<?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;
}
한 단계 더 나아가려면 이제 처리 된 양식에서 오류를 가져 와서 json 객체와 함께 다시 보낼 수 있습니다. 어떤 아이디어?