वेबमैक्स को अजाक्स के साथ प्रोग्रामेटिक रूप से कैसे सबमिट करें?


8

मैं वेबफ़ॉर्म पर Drupal 7. मैं प्रस्तुत करने के लिए एक अजाक्स कार्यान्वयन पर काम कर रहा हूँ किसी भी अच्छे खोजने के लिए सक्षम नहीं था hookवेबफ़ॉर्म सबमिट बटन और रूप में '#ajax' जोड़ें तो मैं एक करने के लिए एक नज़र था बदलने के लिए Drupal 6 मॉड्यूल है कि एक बाहरी स्क्रिप्ट से इस कार्यक्षमता को लागू करता है।

इसलिए मैंने अपने स्वयं के मॉड्यूल और जावास्क्रिप्ट कोड के साथ जाने का फैसला hook_menu()किया Drupal 7 में मैंने जो कस्टम मेनू कॉलबैक परिभाषित किया है , उसके लिए एक अजाक्स पोस्ट अनुरोध को आग लगाने के लिए ।

जावास्क्रिप्ट हिस्सा ठीक काम करता है, लेकिन मैं वेबफॉर्म को प्रोग्रामेटिक रूप से सबमिट करने की कोशिश कर रहा हूं।

यहाँ मेरा जावास्क्रिप्ट कोड है:

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 सर्वर त्रुटियां मिलती हैं।

मुझे लगता है कि डी 6 और डी 7 फॉर्म एपीआई काफी अलग हैं और मुझे यकीन नहीं है कि कहां से काम शुरू करना है। मैंने इसे डीबग करने की कोशिश की है, लेकिन मैं यह पता नहीं लगा सकता कि 500 ​​त्रुटियों को क्या पैदा कर रहा है।

मैं वेबफॉर्म 3 का उपयोग करता हूं और जो मॉड्यूल मैंने कोड लिया है वह वेबफॉर्म के संस्करण 3 पर भी Drupal 6 के लिए निर्भर करता है। लेकिन दोनों मॉड्यूल को एक ही प्रकार के कार्य और एक ही प्रकार की कार्यक्षमता प्रदान करनी चाहिए। पहला वर्कअराउंड: यह उन मानों से आ सकता है जो मैं पास करता हूं जो डी 7 फॉर्म एपी के साथ संगत नहीं होगा।

मेरे लॉग में मेरे पास है:

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).

- संपादित करें -

मैं अब लाइन से लाइन डिबगिंग कर रहा हूं, अंत में कोड का यह टुकड़ा डी 7 मॉड्यूल बनने लायक हो सकता है;)

मुझे 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);

अब मैं drupal_execute () के समतुल्य को खोजने का प्रयास कर रहा हूं, जो D7 में अब मौजूद नहीं है।

- संपादित करें (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;
}

एक कदम आगे जाने के लिए मैं अब संसाधित रूप से त्रुटियों को प्राप्त करना चाहूंगा, ताकि मैं उन्हें जसन ऑब्जेक्ट के साथ वापस भेज सकूं। कोई विचार ?

जवाबों:


4

मैं भी कुछ ऐसा ही कर रहा था और ई। डी। संत चेमास का समाधान ज्यादातर मेरे लिए काम कर रहा था। हालाँकि, कुछ चीजें थीं जिन्हें मुझे जोड़ना था:

पहले, मुझे प्रोसेसिंग फॉर्म से पहले इसे form_state array में जोड़ना था

'method' => 'post',

फिर, नीचे की ओर, फ़ॉर्म को संसाधित करने के लिए कुछ समायोजन और यदि कोई हो तो त्रुटि संदेश लौटाएँ:

  // Prevent the form from redirecting the request
  $form_state['no_redirect'] = TRUE;
  // Executing the pressed button action
  drupal_build_form($form_id, $form_state);
  // See if the form submitted successfully
  if (!$form_state['executed']) {
    // If the form didn't submit successfully, get the errors
    // which are set bu drupal_set_message
    $messages = drupal_get_messages('error');
    $messages = implode('<br />', $messages['error']);
  }
  else {
    // If form submitted successfully, create a nice message.
    $messages = "Thanks for contacting us! We will let you know when the Beta is live!";
  }
  // drupal_json_output seems to confuse some browsers, who want to save as a file 
  print drupal_json_encode(array(
    'message' => $messages,
    'status' => $form_state['executed'],
  ));

मुझे यकीन नहीं है कि यह करने का सबसे अच्छा तरीका है, लेकिन यह मेरे लिए काम कर पाया। बेशक, आप बस आगे जाना चाहते हैं और त्रुटि संदेशों को प्रस्तुत करना चाहते हैं और पूरी तरह से प्रदान की गई त्रुटि संदेश बॉक्स लौटा सकते हैं, और इसके अलावा, आप $ form_state सरणी से "पुष्टिकरण संदेश" को चिपका सकते हैं ताकि आप सफलता संदेश से नियंत्रण कर सकें। वेबफॉर्म यूआई।


यह बहुत अच्छा है, लेकिन मुझे असफलता मिलती रहती है ($ form_state ['निष्पादित'] = गलत)। और drupal_get_messages ('त्रुटि') में कुछ भी नहीं है। आश्चर्य है कि मैं यह कैसे डिबग कर सकता हूं।
सायबरटोस्ट

मुझे स्पष्ट करना चाहिए कि मैं कर्ल के माध्यम से प्रस्तुत करने की कोशिश कर रहा हूं, जैसे कर्ल -vvv -X POST -H "X-Requested-With: XMLHttpRequest" -d 'सबमिट किया गया [contact_fullname] = my my 20name & Submit [contact_email] = test% 40example। com और सबमिट किया गया [contact_message] = टेस्ट% 20message '" localhost / fubar / 31 "। सामग्री भेजी जाती है और form_state आबादी है, लेकिन drupal_form_build () निष्पादित / सबमिट नहीं किया जाता है।
सायबरटोस्ट

-1

मुझे बताएं कि क्या मैं गलत हूं, लेकिन चूंकि वेबफॉर्म सबमिट करना एक नोड है, इसलिए सीधे अपने page callback( प्रोग्राम क्षेत्र सत्यापन के साथ (या जावास्क्रिप्ट का उपयोग करने से पहले क्या कर सकता है) के साथ नोड को प्रोग्रामेटिक रूप से क्यों न बनाएं )

यह कुछ इस तरह हो सकता है

if(!function_exists("node_object_prepare"))
{
  include_once(drupal_get_path('module', 'node') . '/node.pages.inc');
}
$node = new stdClass();                                                         
$node->is_new = TRUE;
$node->type = 'YOUR_NODE_TYPE_HERE';                                
node_object_prepare($node);

// then all the fields you need

node_validate($node);
$node = node_submit($node);
node_save($node);
$nid = $node->nid;

Et voilà! :)


3
वास्तव में वेबफॉर्म सबमिशन नोड्स नहीं हैं। वेबफॉर्म अपने स्वयं के तालिकाओं में प्रस्तुतियाँ संग्रहीत करता है। इसलिए हमारे पास सबमिशन जोड़ने के लिए नया नोड नहीं बनाया जा सकता है। इसके अलावा, मैं चाहता हूँ कि पूरे वेबफॉर्म सत्यापन वर्कफ़्लो को एक बार फ़ॉर्म निष्पादित होने के बाद ट्रिगर किया जाए ताकि यह आवश्यक फ़ील्ड्स आदि की जांच कर सके ...
E. de Saint Chamas
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.