Puncte:0

Add rows to form tableselect with AJAX

drapel na

I would like to:

1.) Add rows to a tableselect form element when a user clicks on a button.

2.) See which rows are selected when a user clicks on another button.

Part one is complete (I've only included relevant code):

public function buildForm(array $form, FormStateInterface $form_state) {

  //Tableselect
  $header = [
    'first_name' => $this->t('First Name'),
  ]

  $form['results'] = [
    '#type' => 'tableselect',
    '#title' => $this->t('Select contact to add to message list'),
    '#header' => $header,
    '#options' => [],
    '#multiple' => TRUE,
    '#empty' => $this->t('No users found'), 
    '#prefix' => '<div id="search-results">',
    '#suffix' => '</div>',
  ];

  //This button adds rows to tableselect
  $form['button_one'] = [
    '#type' => 'button',
    '#value' => $this->t('Search'),
    '#ajax' => [
      'callback' => '::contactSearch',
      'wrapper' => 'search-results',
      'effect' => 'fade',
    ],
  ];

  //This button displays $form_state in a kint
  $form['button_two'] = [
    '#type' => 'button',
    '#value' => $this->t('Debug'),
    '#ajax' => [
      'callback' => '::debugSearch',
      'wrapper' => 'search-results',
      'effect' => 'fade',
    ],
  ];

  //This is for kint
  $form['debug'] = [
    '#type' => 'container',
    '#attributes' => [
      'id' => ['debug-out'],
    ],
  ];

}

/**
 * Ajax callback for button one
 */
public function contactSearch(array &$form, FormStateInterface $form_state) {

  //The AJAX callback replaces the tableselect with one that has more rows.
  $header = [
    'first_name' => $this->t('First Name'),
  ];

  $rows = [
    1 => 'Ben',
    2 => 'Sarah',
    3 => 'Steve',
  ];

  $form['results'] = [
    '#type' => 'tableselect',
    '#title' => $this->t('Select contact to add to message list'),
    '#header' => $header,
    '#options' => $rows,
    '#multiple' => TRUE,
    '#empty' => $this->t('No users found'), 
    '#prefix' => '<div id="search-results">',
    '#suffix' => '</div>',
  ];

  //This seems to be necessary specifically for tableselect
  $form['results'] = Tableselect::processTableselect($form['results'], $form_state, $form);
  $response->addCommand(new ReplaceCommand('#search-results', $form['results']));
  return $response;

}

/**
 * Ajax callback for button two
 */
public function debugSearch(array &$form, FormStateInterface $form_state) {

  //Show current state of tableselect in a kint
  $response = new AjaxResponse();
  $debugOut = @Kint::dump($form_state->getValue('results'));
  $response->addCommand(new ReplaceCommand('#debug-out', $debugOut));
  return $response;

}

What I expect:

I expect button one to update $form so that when I click on button two, $form_state->getValue('results') will return which rows are selected.

What happens:

The button 2 AJAX function doesn't register any change to the tableselect element.

Visually, the tableselect changes as I expect after clicking button one: the extra rows are added. But the AJAX callback for button 2 doesn't see any change.

I need to know which rows are selected AFTER the tableselect has been updated.

Puncte:1
drapel na

Pe această problemă DA exista un comentariu:

Nu puteți schimba elemente pe callback sau validateForm(), trebuie să le puneți pe metoda buildForm().

Ceea ce făceam. Am adăugat rânduri la $form în interiorul apelului AJAX.

Deci, creez o metodă numită de buildForm() care evaluează numărul de pe rânduri pe baza valorilor din $form_state:

    $form['search_results']['results'] = [
      '#type' => 'tableselect',
      '#title' => $this->t('Selectați contactul de adăugat la lista de mesaje'),
      '#header' => $header,
      '#options' => $this->getRows($form_state),
      '#multiple' => TRUE,
      '#empty' => $this->t('Nu a fost găsit niciun utilizator'), 
      '#prefix' => '<div id="search-results">',
      '#sufix' => '</div>',
    ];

Înțeleg că apelul invers AJAX va apela din nou buildForm(), care va apela metoda mea getRows().

Noile rânduri din tableselect returnate folosind această abordare sunt disponibile în $Form și $form_state va arăta care sunt selectate.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.