it-swarm.com.de

Verwenden Sie drupal #states, um ein Radio zu überprüfen

Ich möchte einige jquery .change-Funktionen übersetzen, um #states in der Form-API zu verwenden.

var radio1 = jQuery('input:radio[name=radio_1]');
var radio2 = jQuery('input:radio[name=radio_2]');

radio1.change(function() {
if (radio1.filter(':checked').val() == 0) {
  radio2[1].checked = true;
}
else {
  radio2[0].checked = true;
}
});

radio2.change(function() {
if (radio2.filter(':checked').val() == 0) {
  radio1[1].checked = true;
}
else {
  radio1[0].checked = true;
}
});

Logik:
Wenn Radio1-Wert 0 ausgewählt ist, wird Radio2-Wert 1 ausgewählt.
Wenn Radio1-Wert 1 ausgewählt ist, wird Radio2-Wert 0 ausgewählt.
Wenn Radio2-Wert 0 ausgewählt ist, wird Radio1-Wert 1 ausgewählt.
Wenn Radio2-Wert 1 ausgewählt ist, wird Radio1-Wert 0 ausgewählt.

Ein Blick auf form_example_states_form () zeigt, dass die Syntax lautet:

'#states' => array(
  'action_to_take_on_this_form_element' => array(
    'jquery_selector_for_another_element' => array(
      'condition_type' => value,
    ),
  ),
),

Was mir fehlt, ist "action_to_take_on_this_form_element". Ich weiß nicht, wie ich den Wert 0 oder 1 des Optionsfelds auswählen soll. Alles, was ich in Bezug auf realisierbare Optionen habe, ist aktiviert/deaktiviert (siehe drupal_process_states () für eine Liste).

Was ich aktuell habe

'#states' => array(
  'checked' => array(
    ':input[name="radio_2"]' => array(
      'value' => 0,
    ),
  ),
  'unchecked' => array(
    ':input[name="radio_2"]' => array(
      'value' => 1,
    ),
  ),
),

und das scheint nicht zu funktionieren. Ich brauche so etwas wie aktiviert [0], um das Optionsfeld Wert 0 auszuwählen.

Bearbeiten: Hier ist der Arbeitscode. Möchte keine Inline-Js verwenden.

function your_form(&$form, $form_state) {
  $form['radios1'] = array(
    '#type' => 'radios',
    '#title' => 'Radios 1',
    '#options' => array(
      0 => 'zero',
      1 => 'one',
    ),
    '#default_value' => 0,
  );

  $form['radios2'] = array(
    '#type' => 'radios',
    '#title' => 'Radios 2',
    '#options' => array(
      0 => 'zero',
      1 => 'one',
    ),
    '#default_value' => 1,
  );

  $form['#attached']['js'][] = array(
    'data' => "var radio1 = jQuery('input:radio[name=radios1]');
var radio2 = jQuery('input:radio[name=radios2]');

radio1.change(function() {
if (radio1.filter(':checked').val() == 0) {
  radio2[1].checked = true;
}
else {
  radio2[0].checked = true;
}
});

radio2.change(function() {
if (radio2.filter(':checked').val() == 0) {
  radio1[1].checked = true;
}
else {
  radio1[0].checked = true;
}
});",
    'type' => 'inline',
  );

  return $form;
}

Demo-Video: https://www.youtube.com/watch?v=lXfMFaTTVes

6
mikeytown2

Mit der Eigenschaft form_api # after_build können Sie einen Rückruf festlegen, in dem Sie die einzelnen Optionsfeldelemente (nicht das gruppierte "Radios" -Element) bearbeiten können.

function your_form(&$form, $form_state) {
  $form['radios1'] = array(
    '#type' => 'radios',
    '#title' => 'Radios 1',
    '#options' => array(
      0 => 'zero',
      1 => 'one',
    )
  );

  $form['radios2'] = array(
    '#type' => 'radios',
    '#title' => 'Radios 2',
    '#options' => array(
      0 => 'zero',
      1 => 'one',
    )
  );

  $form['#after_build'] = array('your_form_after_build_function');

  return $form;
}

function your_form_after_build_function($form) {
  $form['radios1'][0]['#states'] = array(
    'checked' => array(
      ':input[name="radios2"]' => array('value' => 1),
    ),
  );

  $form['radios1'][1]['#states'] = array(
    'checked' => array(
      ':input[name="radios2"]' => array('value' => 0),
    ),
  );

  $form['radios2'][0]['#states'] = array(
    'checked' => array(
      ':input[name="radios1"]' => array('value' => 1),
    ),
  );

  $form['radios2'][1]['#states'] = array(
    'checked' => array(
      ':input[name="radios1"]' => array('value' => 0),
    ),
  );

  return $form;
}
6
Paul Querol

Da #states derzeit für Radios abgehört wird, besteht eine andere Möglichkeit darin, einen #ajax-Rückruf zu verwenden, sofern die zusätzlichen Serveranforderungen für Sie kein Problem darstellen:

function my_form($form, &$form_state) {
  $form = array(
    'radios1' => array(
      '#title' => 'Radios 1',
      '#type' => 'radios',
      '#options' => array(0 => 'Zero', 1 => 'One'),
      '#prefix' => '<div id="radios1-ajax-wrapper">',
      '#suffix' => '</div>',
      '#ajax' => array(
        'callback' => '_my_ajax_callback',
        'wrapper' => 'radios2-ajax-wrapper',
      ),
    ),
    'radios2' => array(
      '#title' => 'Radios 2',
      '#type' => 'radios',
      '#options' => array(0 => 'Zero', 1 => 'One'),
      '#prefix' => '<div id="radios2-ajax-wrapper">',
      '#suffix' => '</div>',
      '#ajax' => array(
        'callback' => '_my_ajax_callback',
        'wrapper' => 'radios1-ajax-wrapper',
      ),
    ),
  );

  if (isset($form_state['triggering_element'])) {
    switch ($form_state['triggering_element']['#name']) {
      case 'radios1':
        unset($form_state['input']['radios2']);
        if ($form_state['values']['radios1'] == 0) {
          $form['radios2']['#default_value'] = 1;
        }
        elseif ($form_state['values']['radios1'] == 1) {
          $form['radios2']['#default_value'] = 0;
        }
        break;

      case 'radios2':
        unset($form_state['input']['radios1']);
        if ($form_state['values']['radios2'] == 0) {
          $form['radios1']['#default_value'] = 1;
        }
        elseif ($form_state['values']['radios2'] == 1) {
          $form['radios1']['#default_value'] = 0;
        }
        break;
    }
  }

  return $form;
}

function _my_ajax_callback($form, &$form_state) {
  switch ($form_state['triggering_element']['#name']) {
    case 'radios1':
      return $form['radios2'];

    case 'radios2':
      return $form['radios1'];
  }
}

Ich würde dies jedoch nicht als langfristige Lösung empfehlen.


Meine ursprüngliche Idee unten leidet unter dem gleichen Fehler wie bei der Verwendung einer # after_build-Funktion, daher das Durchgestrichen.

Angesichts der Tatsache, dass die Methode #after_build leicht vom Radiotyp abweicht, besteht eine alternative Methode, die für mich zu funktionieren scheint, darin, das Formular aus einzelnen Funkelementen zu erstellen und die Funkgruppierungen mithilfe von #attributes zu ändern. Auf diese Weise können Sie #states in Ihrem Formularkonstruktor festlegen, ohne eine # after_build-Funktion zu benötigen:

function my_form($form, &$form_state) {
  $form = array(
    'radios1' => array(
      '#type' => 'container',
      '#prefix' => '<label for="edit-radios1">Radios 1</label>',
      '#tree' => TRUE,
      1 => array(
        '#type' => 'radio',
        '#title' => 'One',
        '#return_value' => 1,
        '#attributes' => array(
          'name' => array(
            'radios1',
          ),
        ),
        '#states' => array(
          'checked' => array(
            ':input[name="radios2"]' => array('value' => 2),
          ),
        ),
      ),
      2 => array(
        '#type' => 'radio',
        '#title' => 'Two',
        '#return_value' => 2,
        '#attributes' => array(
          'name' => array(
            'radios1',
          ),
        ),
        '#states' => array(
          'checked' => array(
            ':input[name="radios2"]' => array('value' => 1),
          ),
        ),
      ),
    ),
    'radios2' => array(
      '#type' => 'container',
      '#prefix' => '<label for="edit-radios2">Radios 2</label>',
      '#tree' => TRUE,
      1 => array(
        '#type' => 'radio',
        '#title' => 'One',
        '#return_value' => 1,
        '#attributes' => array(
          'name' => array(
            'radios2',
          ),
        ),
        '#states' => array(
          'checked' => array(
            ':input[name="radios1"]' => array('value' => 2),
          ),
        ),
      ),
      2 => array(
        '#type' => 'radio',
        '#title' => 'Two',
        '#return_value' => 2,
        '#attributes' => array(
          'name' => array(
            'radios2',
          ),
        ),
        '#states' => array(
          'checked' => array(
            ':input[name="radios1"]' => array('value' => 1),
          ),
        ),
      ),
    ),
  );

  return $form;
}

Beachten Sie, dass ich Ihre "Zero or One" -Radios für dieses Beispiel in "One or Two" geändert habe, weil ein weiterer Fehler im Kern bedeutet, dass ein Radio mit dem Wert 0 beim Erstellen des Formulars immer überprüft wird . Wenn Sie unbedingt den Wert 0 verwenden müssen, müssen Sie diesen Fehler auf irgendeine Weise umgehen.

2
morbiD

Schau mal hier :

Stattdessen müssen Sie 'value' => 'name' verwenden, wobei 'name' der Name der Funkoption ist, die Sie auswählen müssen. In Ihrem Beispiel könnte es '1' statt 1 sein.

1
GwenM