Come evitare "È stata rilevata una scelta illegale" durante l'aggiornamento dei valori dell'elenco di selezione tramite Ajax?


10

Ho quattro campi di riferimento dell'entità all'entità utente in un modulo. Il modulo host è il modulo di modifica del nodo. Tre di questi sono elenchi selezionati, l'ultimo è Inline Entity Form .

Dopo aver aggiunto un'entità utente tramite IEF, sto provando ad aggiornare i valori degli elenchi di selezione:

function ebep_users_feature_users_list_ajax($form, $form_state) {

  $ief = array_shift($form_state['inline_entity_form']);
  $options = array('_node' => t('- None -'));
  $commands = array();

  foreach($ief['entities'] as $data) {
    $options[$data['entity']->uid] = $data['entity']->name;
  }

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#options'] = $options;
    $commands[] = ajax_command_replace('#'.$fieldName.'_wrapper', drupal_render($form[$fieldName]));
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

Funziona, ma quando provo ad aggiungere un altro utente tramite IEF ricevo:

È stata rilevata una scelta illegale. Si prega di contattare l'amministratore del sito.


alcune delle Relateddomande qui elencate a destra sono state risolte?
Jimajamma,

@Jimajamma sembra che su ajax la ricostruzione del modulo di callback non funzioni. Come posso abilitarlo? $ form_state ['rebuild'] = TRUE non fa nulla ...
Codium

@Jimajamma quindi le soluzioni correlate non funzionano
Codium

Ho risposto alla tua domanda qui poiché è una domanda duplicata drupal.stackexchange.com/questions/15989/…
Sina Salek,

Risposte:


15

--- Risposta originale. È sbagliato, controlla l'aggiornamento di seguito.

Basta impostare

$bla['#validated'] = TRUE

Sulla selezione che verrà aggiornato con AJAX.

Acquista "La scelta illegale è stata rilevata"

--- Aggiornamento 17 dic 2019 ---

In realtà non era un buon consiglio, molto tempo fa, ora lo so meglio.

La funzione di callback Ajax dovrebbe restituire solo il pezzo di modulo che è stato modificato o alcuni comandi ajax.

In questo caso, la modifica del modulo deve essere effettuata sulla funzione del modulo o su un hook di modifica del modulo. Le funzioni di costruzione e convalida dei moduli vengono eseguite ogni volta che viene chiamato un callback ajax. Basta controllare $ form_state sulla build del modulo o modificare la funzione e regolare i valori di conseguenza.

Vedi Risolvi l'errore "È stata rilevata una scelta illegale ..."


1
Se ricordo bene l'ho provato, senza successo nel mio caso, grazie
Codium

1
Temo che questo non funzioni neanche per me.
kevin.coyle,

Questo non rende il modulo meno sicuro?
Binny,

Sì, tutti i commenti precedenti sono giusti. La risposta è stata aggiornata
Jaimealsilva,

3

Ho riscontrato questo problema numerose volte in Drupal 6, modificando i valori dell'elenco Seleziona tramite Ajax.

Ecco cosa puoi fare

  1. Se possibile, prova a inserire tutti i possibili valori nell'API di campo, devi modificare quel campo, quindi quando modifichi i valori, dovrai assicurarti che solo i valori elencati siano nell'elenco.
  2. La soluzione che ho implementato era, è possibile modificare il tipo di campo dall'elenco Seleziona in campo di testo, dall'API di campo e chiedere a Drupal di salvare il valore così com'è. Ora, in fase di esecuzione del modulo, dovrai modificare il modulo, cambiare il tipo per selezionare l'elenco e inserire le opzioni che desideri. Anche durante l'invio, dovrai assegnare il valore corretto richiesto dal campo, che verrà salvato nel DB così com'è. Assicurati che il gestore di invio venga chiamato prima del gestore di invio del modulo predefinito, per poterlo utilizzarearray_merge

Se la prima soluzione funziona per te, risparmierai molto tempo nella codifica e nel test delle cose. MA se l'elenco nel menu a discesa è dinamico e non hai alcun controllo su di esso, potresti dover scegliere una seconda soluzione.

Pubblica post in caso di problemi, ho fatto un sacco di lavoro su questo problema, per il mio progetto, e l'ho fatto per circa 50 moduli, PHEW !!! :)


3

Ho trovato il modo migliore per aggirare questo è di impostare #valuenell'elenco di selezione.

Se abbiamo il valore in formstate ed è nelle nostre opzioni, non avremo un errore. Se il nostro valore non è tra le opzioni, seleziona la prima opzione tra le nostre opzioni e usala.

$form['example'] = array(
    '#type' => 'select',
    '#title' => t('Example'),
    '#options' => $options,
    '#value' => isset($form_state['values']['example']) && in_array($form_state['values']['example'],$options)?$form_state['values']['example']:key($options),
  );

2

La mia soluzione:

/**
 * Implements hook_form_FORM_ID_alter()
 */
function ebep_users_feature_form_ebep_exhibitor_profile_node_form_alter(&$form, &$form_state, $form_id) {

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#prefix'] = '<div id="'.$fieldName . '_wrapper">';
    $form[$fieldName]['und']['#suffix'] = '</div>';
    $form[$fieldName]['und']['#options'] = _ebep_users_feature_getOptionsValuesFromIEFList($form_state);
  }

  $form['#attached']['css'] = array(
    drupal_get_path('module', 'ebep_users_feature') . '/assets/styles.css',
  );

  $form['#attached']['js'] = array(
    drupal_get_path('module', 'ebep_users_feature') . '/assets/scripts.js',
  );

  $form['users_refresh'] = array(
    '#type' => 'submit',
    '#value' => t('Refresh users list'),
    '#ajax' => array(
      'callback' => 'ebep_users_feature_users_list_ajax',
    ),
  );
}

function ebep_users_feature_users_list_ajax($form, $form_state) {

  $commands = array();

  foreach(_ebep_users_feature_getUserListFieldNames() as $fieldName) {
    $form[$fieldName]['und']['#options'] = _ebep_users_feature_getOptionsValuesFromIEFList($form_state);
    $commands[] = ajax_command_replace('#'.$fieldName.'_wrapper', drupal_render($form[$fieldName]));
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

function _ebep_users_feature_getOptionsValuesFromIEFList($form_state) {
  static $options = array();

  if (empty($options)) {
    $ief = array_shift($form_state['inline_entity_form']);
    $options['_node'] = t('- None -');

    foreach($ief['entities'] as $data) {
      $options[$data['entity']->uid] = $data['entity']->name;
    }
  }

  return $options;
}

-1

Nel tuo callback ajax, aggiungi:

...

drupal_get_messages();
form_get_errors();

return array('#type' => 'ajax', '#commands' => $commands);

Come precauzione di sicurezza, la _form_validate()funzione principale controlla se la chiave #options di un elemento è cambiata rispetto a ciò che è stato impostato nella build originale (che hanno). Chiamando drupal_get_messages()e in form_get_errors()pratica diciamo a Drupal di ignorare eventuali errori / messaggi durante l'esecuzione della nostra richiesta Ajax. :)


Il messaggio di errore è sparito ma l'elemento select contiene ancora la classe di errore. Come rimuoverlo o impedirlo?
Tejas Vaidya,

Questo è l'equivalente Drupal di mettere il nastro sopra una spia sul cruscotto del veicolo.
Frank Robert Anderson,
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.