AJAX chiama nel plug-in del tipo di contenuto CTools?


10

Sto creando un tipo di contenuto dei pannelli CTools (ovvero, quella cosa che inserisci nei pannelli quando aggiungi contenuto, non un tipo di nodo) e sto cercando di utilizzare l' #ajaxattributo di un elemento del modulo per impostare alcuni valori predefiniti. Vedi il codice sotto.

Questo è tutto all'interno della my_module_content_type_edit_form($form, &$form_state)chiamata del tipo di contenuto , a proposito.

  $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')),
  );

Il mio callback è il seguente.

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'];
}

Indipendentemente dal fatto che il ritorno che sto suggerendo possa effettivamente funzionare, watchdog()non funziona nemmeno.

So che CTools fa alcune cose strane con AJAX, ma non può essere così strano. Hai idea di come farei quello che voglio fare?

Grazie!

In alternativa: come impostare un valore predefinito in base al valore di un'opzione di modulo precedente?

Ho capito come fare, ma è un po 'confuso: crei nuovi campi modulo per ogni fork delle dipendenze. È quindi possibile unire i valori insieme hook_content_type_edit_form_submit(), utilizzando quello che corrisponde al valore scelto per il componente che inizialmente ha modificato tutto.

Lascio aperta la domanda perché io (e, francamente, ogni programmatore con cui sto lavorando) sto davvero cercando un buon modo per usare AJAX all'interno di questi moduli di modifica del tipo di contenuto del Pannello.

Aggiornamento: sembra che tu non possa fare nulla con #attached, neanche.

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

Essendo uno sviluppatore di Drupal "Pannelli per tutto", immagino di poter trovare un uso anche in futuro, quindi ho aggiunto una generosità, vediamo cosa succede.
Letharion,

Caspita, quella generosità andava e veniva senza nemmeno un commento (Grazie BTW, Letharion). Ciò che sto chiedendo è impossibile o qualcosa del genere?
Aendrew

Vale la pena notare che sono stato in grado di aggiungere correttamente Javascript usando ctools_add_js();o drupal_add_js();alla fine di hook_content_type_edit_form();. Se stai semplicemente facendo cose relative all'interfaccia utente, sembra che potrebbe essere la migliore chiamata (almeno fino a quando qualcuno non risponde correttamente a questa domanda).
aendrew

Risposte:


8

Risposta breve: dovresti usare #ajax ['percorso'].

Risposta lunga:

Avere un callback ajax non aiuta in quanto ctools crea le sue forme in modo diverso. Il callback effettuato da system / ajax non riesce a trovare la definizione di modulo completa, pertanto non è possibile trovare un elemento per elaborare la richiesta ajax. L'uso di #ajax [percorso] attiva semplicemente una voce di menu.

Puoi verificare tu stesso scaricando il modulo quando usi #ajax [callback]

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

Ho modificato simplecontext_content_type_edit_form aggiungendo il widget di completamento automatico dell'utente e il tuo campo che funzionano entrambi :)

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')),
  );
...

Dato che ora usi il percorso #ajax, devi aggiungere una voce di menu come mi è piaciuto

<?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"));
}

Un nittpick su #attached [js]: il js inline dovrebbe essere key => value come:

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

Ho usato Firebug per verificare il valore risultante e non l'effetto risultante. Quindi spero che questo aiuti a risolvere il tuo problema.


Wow. Sono così entusiasta di avere finalmente una risposta a questa domanda. Lo proverò tra poco. Grazie anche per la nota sul bit #attaccato, è proprio quello che avevo inizialmente (ma l'ho cambiato perché pensavo che non potesse essere giusto).
Aendrew

Quindi, qualche successo? Sarebbe interessante sapere prima della fine della taglia :)
Letharion,

Spero di ottenere la mia taglia: p
Clemens Tolboom,

Ci scusiamo per il ritardo, avendo un po 'di tempo per farlo funzionare - quando provo a restituire l'array $ form, mi dice che la mia funzione di validazione non è definita. Lo è, e quando provo a ri-dichiararlo nel mio modulo (al contrario del file del plugin del tipo di contenuto), mi dice che lo sto ridichiando. Immagino che non sia quello che devo fare, ma non riesco a capire come strutturare drupal_json_output in modo che produca qualcosa che la mia forma interpreterà come una risposta significativa. Qualsiasi aiuto? Un callback di esempio migliore aiuterebbe MOLTO. Grazie!
aendrew

Ho perso la piccola parte della tua domanda che riguarda il valore di ritorno : return $ form ['link_target'] ['# default_value']; quale stai cercando di restituire un modulo drupal in un contesto html / javascript . Non funzionerà. Hai visto qualcosa di simile a quello che vuoi nell'interfaccia utente dei pannelli? (Io stesso disabilito JavaScript di tanto in tanto con l'interfaccia utente delle viste solo per vedere il flusso di lavoro non js) (modificato questo commento un milione di volte ... imbarazzante)
Clemens Tolboom,

2

Ho avuto un problema simile, in cui volevo includere un tipo di elemento multimediale in un plug-in del tipo di contenuto CTools, che utilizza anche ajax per selezionare un'immagine.

Utilizza la propria impostazione 'percorso' ajax, invece dell'impostazione 'callback', ma quando si seleziona un'immagine, il modulo è stato ricostruito senza l'elemento multimediale.

Ho fatto risalire al fatto che drupal_rebuild_form non è riuscito a trovare né la funzione wrapper del modulo CTools, né le effettive funzioni del modulo impostazioni. Quindi l'ho risolto aggiungendo queste righe di codice al modulo delle impostazioni di 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');

}

Forse mi manca qualcosa di ovvio per cui i file include non vengono caricati, ma includerli manualmente risolto il problema per me.


0

da parte mia, ho dovuto scrivere una funzione wrapper di modulo nel file .module e includere manualmente il riquadro (dove è definito il contenuto del modulo originale) in questo modo:

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

Ora, durante una chiamata Ajax, Drupal è in grado di recuperare il mio modulo in modo da poter utilizzare l'API del modulo AJAX standard.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.