โทร AJAX ในปลั๊กอินประเภทเนื้อหา CTools?


10

ฉันกำลังสร้างประเภทเนื้อหา CTools Panels (เช่นสิ่งที่คุณแทรกลงในพาเนลเมื่อเพิ่มเนื้อหาไม่ใช่ประเภทของโหนด) และฉันพยายามใช้#ajaxแอตทริบิวต์ของไอเท็มฟอร์มเพื่อตั้งค่าเริ่มต้นบางอย่าง ดูรหัสด้านล่าง

นี่คือทั้งหมดที่อยู่ในการmy_module_content_type_edit_form($form, &$form_state)โทรของประเภทเนื้อหาโดยวิธี

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'callback' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none'=>t('No Link'), 'internal'=>t('Internal Link'), 'external'=>t('External Link'), 'document'=>t('Document Link')),
  );

การติดต่อกลับของฉันมีดังต่อไปนี้

function my_module_set_target($form, $form_state) {
  watchdog("Test", "Testing callback", array(), WATCHDOG_ALERT);
  $form['link_target']['#default_value'] = '_parent';

  return $form['link_target']['#default_value'];
}

ไม่ว่าผลตอบแทนที่ฉันแนะนำจะใช้งานได้จริงหรือwatchdog()ไม่ไม่ได้ผล

ฉันรู้ว่า CTools ทำสิ่งแปลก ๆ กับ AJAX แต่มันไม่สามารถเป็นสิ่งที่แปลก คุณมีความคิดเกี่ยวกับวิธีที่ฉันจะทำสิ่งที่ฉันต้องการจะทำอย่างไร

ขอบคุณ!

อีกวิธีหนึ่ง:ฉันจะตั้งค่าเริ่มต้นตามค่าของตัวเลือกฟอร์มก่อนหน้าได้อย่างไร

ฉันรู้วิธีการทำเช่นนี้ แต่มันค่อนข้างแฮ็ค - คุณสร้างเขตข้อมูลฟอร์มใหม่สำหรับแต่ละการพึ่งพา จากนั้นคุณสามารถผสานค่าเข้าด้วยกันhook_content_type_edit_form_submit()โดยใช้ค่าใดค่าหนึ่งที่ตรงกับค่าที่เลือกสำหรับองค์ประกอบที่เริ่มต้นทุกอย่างแยกกัน

ฉันเปิดคำถามทิ้งไว้เพราะ (และตรงไปตรงมาโปรแกรมเมอร์ทุกคนที่ฉันทำงานด้วย) ต้องการวิธีที่ดีในการใช้ AJAX ในรูปแบบการแก้ไขประเภทเนื้อหาของพาเนลเหล่านี้

อัปเดต:ดูเหมือนคุณจะไม่สามารถทำสิ่งใดด้วย #attached เช่นกัน

$form['link'][$i] = array(
  '#type' => 'fieldset',
  '#title' => t('Link #@num', array('@num' => $i)),
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
  '#attached' => array(
    'js' => array(
      'alert("Yay.");', 'inline'
    ),
  )
);

ในฐานะที่เป็นนักพัฒนา Drupal ฉันคิดว่าฉันสามารถใช้สิ่งนี้ได้ในอนาคตเช่นกันดังนั้นฉันจึงเพิ่มเงินช่วยเหลือดูว่าจะเกิดอะไรขึ้น
Letharion

ว้าวเงินรางวัลนั้นมาถึงแล้วโดยไม่แสดงความคิดเห็นเลย (ขอบคุณ BTW, Letharion) สิ่งที่ฉันถามเป็นไปไม่ได้หรืออะไร?
aendrew

ควรจะเป็นที่น่าสังเกตว่าฉันได้รับสามารถที่จะประสบความสำเร็จเพิ่ม Javascript ใช้ctools_add_js();หรือที่ส่วนท้ายของdrupal_add_js(); hook_content_type_edit_form();หากคุณเพิ่งทำสิ่งที่เกี่ยวข้องกับ UI อย่างง่ายดูเหมือนว่าอาจเป็นการโทรที่ดีที่สุด (อย่างน้อยก็จนกว่าจะมีคนตอบคำถามนี้อย่างถูกต้อง)
aendrew

คำตอบ:


8

คำตอบสั้น ๆ : คุณควรใช้ #ajax ['path']

คำตอบยาว:

การมี ajax callback ไม่ได้ช่วยเพราะ ctools สร้างรูปแบบที่แตกต่างออกไป การเรียกกลับที่ดำเนินการโดยระบบ / ajax ไม่สามารถหาคำจำกัดความของแบบฟอร์มที่สมบูรณ์ดังนั้นจึงไม่สามารถหาองค์ประกอบในการประมวลผลคำขอ ajax สำหรับ การใช้ #ajax [path] เพียงเรียกรายการเมนู

คุณสามารถตรวจสอบด้วยตัวคุณเองโดยการทิ้งแบบฟอร์มเมื่อใช้ #ajax [โทรกลับ]

function ajax_form_callback() {
  list($form, $form_state) = ajax_get_form();
  drupal_process_form($form['#form_id'], $form, $form_state);

ฉันได้แก้ไข simplecontext_content_type_edit_form โดยเพิ่มวิดเจ็ตการเติมข้อความอัตโนมัติของผู้ใช้และฟิลด์ของคุณที่ทำงานทั้งสอง :)

function simplecontext_content_type_edit_form($form, &$form_state) {
  $conf = $form_state['conf'];

  $form['owner_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Username'),
    '#default_value' => 'admin',
    '#autocomplete_path' => 'user/autocomplete',
    '#size' => '6',
    '#maxlength' => '60',
    '#description' => '$description',
  );

  $form['link_type'] = array(
    '#type' => 'radios',
    '#title' => t('Link Type'),
    '#ajax' => array(
      'path' => 'my_module_set_target'
    ),
    '#default_value' => empty($conf['link_type']) ? '_blank' : $conf['link_type'],
    '#options' => array('none' => t('No Link'), 'internal' => t('Internal Link'), 'external' => t('External Link'), 'document' => t('Document Link')),
  );
...

ตามที่คุณใช้ #ajax path คุณต้องเพิ่มรายการเมนูตามที่ฉันต้องการ

<?php

function my_module_menu() {
  $items = array(
    'my_module_set_target' => array(
      'title' => 'AJAX Example',
      'page callback' => 'my_module_set_target',
      'access callback' => TRUE,
      'expanded' => TRUE,
    )
  );
  return $items;
}

function my_module_set_target() {
  drupal_json_output( array('data' => "ABC"));
}

nittpick เกี่ยวกับ #attached [js]: inline js ควรเป็น key => ค่าที่ต้องการ:

'#attached' => array(
  'js' => array(
    'alert("Yay.");' => 'inline',
  ),
),

ฉันใช้ Firebug เพื่อตรวจสอบค่าผลลัพธ์ไม่ใช่ผลลัพธ์ที่ได้ ดังนั้นฉันหวังว่านี่จะช่วยแก้ไขปัญหาของคุณ


ว้าว. ในที่สุดฉันก็ได้รับคำตอบให้กับคำถามนี้ จะลองทำดูสักหน่อย ขอบคุณสำหรับบันทึกย่อบน #attached บิตนั่นคือสิ่งที่ฉันมีในตอนแรก (แต่เปลี่ยนเพราะฉันคิดว่าไม่ถูกต้อง)
aendrew

ดังนั้นความสำเร็จใด ๆ จะน่าสนใจที่ต้องรู้ก่อนที่เงินรางวัลที่มีมากกว่า :)
Letharion

ฉันหวังว่าฉันจะได้รับเงินรางวัลของฉัน: p
Clemens Tolboom

ขออภัยในความล่าช้าด้วยการใช้เวลาสักครู่ในการทำงาน - เมื่อฉันพยายามคืนอาร์เรย์ $ form มันบอกฉันว่าฟังก์ชั่นตรวจสอบความถูกต้องของฉันไม่ได้ถูกกำหนดไว้ มันคือและเมื่อฉันพยายามประกาศอีกครั้งในโมดูลของฉัน (ตรงข้ามกับไฟล์ปลั๊กอินประเภทเนื้อหา) มันจะบอกฉันว่าฉันประกาศใหม่อีกครั้ง ฉันเดาว่าไม่ใช่สิ่งที่ฉันต้องทำ แต่ฉันไม่สามารถหาวิธีจัดโครงสร้าง drupal_json_output ดังนั้นมันจึงแสดงผลบางอย่างที่แบบฟอร์มของฉันจะตีความเป็นการตอบสนองที่มีความหมาย ความช่วยเหลือใด ๆ ตัวอย่างการโทรกลับที่ดีกว่าจะช่วยได้มาก ขอบคุณ!
aendrew

ฉันพลาดส่วนเล็ก ๆ ของคำถามของคุณซึ่งเกี่ยวกับค่าส่งคืน : return $ form ['link_target'] ['# default_value']; ซึ่งเป็นความพยายามของคุณเพื่อส่งคืนแบบฟอร์มdrupalไปยังบริบทhtml / javascript ที่จะไม่ทำงาน คุณเห็นสิ่งที่คล้ายกันในสิ่งที่คุณต้องการใน UI แผงควบคุมหรือไม่? (ตัวเองปิดการใช้งาน JavaScript ตอนนี้และจากนั้นกับมุมมอง UI เพียงเพื่อดูเวิร์กโฟลว์ที่ไม่ใช่ js) (แก้ไขความคิดเห็นนี้หนึ่งล้านครั้ง ... น่าอึดอัดใจ)
Clemens Tolboom

2

ฉันมีปัญหาที่คล้ายกันซึ่งฉันต้องการที่จะรวมประเภทองค์ประกอบสื่อลงในปลั๊กอินประเภทเนื้อหา CTools ที่ยังใช้ Ajax ในการเลือกภาพ

มันใช้การตั้งค่า 'เส้นทาง' อาแจ็กซ์ของตัวเองแทนการตั้งค่า 'โทรกลับ' แต่เมื่อเลือกภาพรูปแบบจะถูกสร้างขึ้นใหม่โดยไม่มีองค์ประกอบสื่อทั้งหมด

ฉันติดตามสิ่งนี้กับความจริงที่ว่า drupal_rebuild_form ไม่สามารถหาได้ทั้งฟังก์ชั่นห่อหุ้มแบบฟอร์ม CTools หรือฟังก์ชั่นการตั้งค่าที่แท้จริง ดังนั้นฉันแก้ไขได้โดยการเพิ่มบรรทัดของรหัสเหล่านี้ไปยังแบบฟอร์มการตั้งค่า ctools:

function custom_module_my_content_plugin_content_type_edit_form($form, &$form_state) {

$background_image = isset($conf['background_image']) ? $conf['background_image'] : array();
  $form['background_image'] = array(
    '#title' => t('Background image'),
    '#default_value' => $background_image,
    '#type' => 'media',
    '#input' => TRUE,
    '#extended' => TRUE,
    '#tree' => TRUE,
    '#media_options' => array(),
  );

  // The two function calls below are necessary if we want to use a media
  // element type, because it causes ajax requests, which in turn call
  // drupal_form_rebuild(), and without the below includes, Drupal will
  // not be able to rebuild the form.

  // Include the CTools content type plugin file, because it provides
  // the ctools_content_configure_form_defaults() function, which is needed
  // when rebuilding the form, because of an ajax action, like selecting
  // a media element.
  ctools_form_include($form_state, 'content');

  // Include this plugin file as well, so that when the form is rebuilt, it
  // can successfully retrieve the settings form.
  ctools_form_include($form_state, 'my_content_plugin', 'custom_module', 'plugins/content_types/my_content_plugin');

}

บางทีฉันอาจขาดอะไรบางอย่างที่เห็นได้ชัดว่าทำไมไฟล์รวมถึงไม่โหลด แต่รวมถึงพวกเขาแก้ไขปัญหาให้ฉันด้วยตนเอง


0

ในด้านของฉันฉันต้องเขียนฟังก์ชั่น wrapper แบบฟอร์มใน. โมดูลไฟล์และรวมบานหน้าต่างด้วยตนเอง (ที่กำหนดเนื้อหาของแบบฟอร์มต้นฉบับ) เช่นนั้น:

function mymodule_form($form, &$form_state) {
  // include mymodule/panes/mypane.inc
  ctools_include('mypane', 'mymodule', 'panes');
  return mymodule_form_content($form, $form_state);
}

ตอนนี้ในระหว่างการโทร ajax Drupal สามารถดึงฟอร์มของฉันได้ดังนั้นฉันจึงสามารถใช้ AJAX ฟอร์ม API มาตรฐานได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.