Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 291566

Display Bug when using #states (Forms API) with Ajax Request

$
0
0

FAPI #states do not update properly after AJAX requests.

Steps to reproduce

To replicate the bug, you need a content type with a field that makes an AJAX request and another field that has a state dependent on that field. In my use case, I have a content type with an image field and a text field that should only show when an image has been uploaded.
1. Have a content type with an image and a text field
2. Create a custom module that adds a state to your text field to only display when the image field has value. It would look something like this:

use Drupal\Core\Form\FormStateInterface;

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_page_form' || $form_id == 'node_page_edit_form') {
    $form['field_my_text_field']['#states'] = [
      'visible' => [
        ':input[name="files[field_my_image_field_0]"]' => ['filled' => TRUE],
      ],
    ];
  }
}

3. Go to your content type and upload an image. You would expect to see field_my_text_field because the image field has an image and the state should react to the AJAX call. However, you won't see field_my_text_field. Save your node, and go back to edit your node. Now you should see field_my_text_field.
4. Apply the patch from #80 and go through the steps again. Now on step 3, you should see field_my_text_field immediately after you upload an image.

Original report

I use a custom module which makes heavy use of the Forms API to do mathematical calculations.

The form which you can see at http://linsenrechner.de/node/27 is rendered with the #states attribute. each line uses a container to display two fields. When these fields are filled, a new line should appear.
This works perfect, BEFORE the calculation button is pressed and the ajax request is done.
After this, the behaviour of the form changes: When two fields of a specific line are filled not only one new line appears. In this case, all lines, which are defined in the form, appear at the same time.

The author of the custom module, sukr_s (http://drupal.org/user/554988) wasn't able to exactly locate the bug, but believes it's in states.js

Here are the form arrays, which are used to create the form at http://linsenrechner.de/node/27

$form['container0'] = array(
   '#type'   => 'container',
   '#weight'        => -53,
); 

$form['container0']['markup0'] = array(
   '#weight'        => -52,
   '#markup' => "<div id='ocalc_header_33'></div>
                 <div id='ocalc_header_33'>$ocalc_sag_height</div>
                 <div id='ocalc_header_33'>$ocalc_zone</div>",
); 


$form['container0'][$wrapper]['sag0'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_sag_height." 0",
    '#title_display' => 'invisible',
    '#weight'        => -51,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#prefix'  => "<div class='form-item-sag0'>$ocalc_zone 0</div>",
    '#field_suffix'  => "mm",
  );

$form['container0'][$wrapper]['zone0'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_zone." 0",
    '#title_display' => 'invisible',
    '#weight'        => -50,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm",
  );

$form['container1'] = array(
   '#type'   => 'container',
   '#weight'        => -43,
   '#states' => array('visible' => array(
		':input[name=sag0]'  => array ('filled' => TRUE),
		':input[name=zone0]' => array ('filled' => TRUE),
    ),
  ),
); 


$form['container1'][$wrapper]['sag1'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_sag_height." 1",
    '#title_display' => 'invisible',
    '#weight'        => -42,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm", 
    '#prefix' => "<div class='form-item-sag1'>$ocalc_zone 1</div>",
  );
  
 $form['container1'][$wrapper]['zone1'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_zone." 1",
    '#title_display' => 'invisible',
    '#weight'        => -41,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm",                   
  );
 
$form['container2'] = array(
   '#type'   => 'container',
   '#weight'        => -33,
   '#states' => array('visible' => array(
		':input[name=sag0]'  => array ('filled' => TRUE),
		':input[name=zone0]' => array ('filled' => TRUE),
		':input[name=sag1]'  => array ('filled' => TRUE),
		':input[name=zone1]' => array ('filled' => TRUE),
    ),
  ),
); 


$form['container2'][$wrapper]['sag2'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_sag_height." 2",
    '#title_display' => 'invisible',
    '#weight'        => -32,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm", 
    '#prefix' => "<div class='form-item-sag1'>$ocalc_zone 2</div>",
  );
  
 $form['container2'][$wrapper]['zone2'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_zone." 2",
    '#title_display' => 'invisible',
    '#weight'        => -31,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm",                 
  );

 
$form['container3'] = array(
   '#type'   => 'container',
   '#weight'        => -23,
   '#states' => array('visible' => array(
		':input[name=sag0]'  => array ('filled' => TRUE),
		':input[name=zone0]' => array ('filled' => TRUE),
		':input[name=sag1]'  => array ('filled' => TRUE),
		':input[name=zone1]' => array ('filled' => TRUE),
		':input[name=sag2]'  => array ('filled' => TRUE),
		':input[name=zone2]' => array ('filled' => TRUE),
    ),
  ),
); 


$form['container3'][$wrapper]['sag3'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_sag_height." 3",
    '#title_display' => 'invisible',
    '#weight'        => -22,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm", 
    '#prefix' => "<div class='form-item-sag1'>$ocalc_zone 3</div>",
  );
  
 $form['container3'][$wrapper]['zone3'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_zone." 3",
    '#title_display' => 'invisible',
    '#weight'        => -21,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm",                 
  );

$form['container4'] = array(
   '#type'   => 'container',
   '#weight'        => -13,
   '#states' => array('visible' => array(
		':input[name=sag0]'  => array ('filled' => TRUE),
		':input[name=zone0]' => array ('filled' => TRUE),
		':input[name=sag1]'  => array ('filled' => TRUE),
		':input[name=zone1]' => array ('filled' => TRUE),
		':input[name=sag2]'  => array ('filled' => TRUE),
		':input[name=zone2]' => array ('filled' => TRUE),
		':input[name=sag3]'  => array ('filled' => TRUE),
		':input[name=zone3]' => array ('filled' => TRUE),
    ),
  ),
); 


$form['container4'][$wrapper]['sag4'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_sag_height." 4",
    '#title_display' => 'invisible',
    '#weight'        => -12,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm", 
    '#prefix' => "<div class='form-item-sag1'>$ocalc_zone 4</div>",
  );
  
 $form['container4'][$wrapper]['zone4'] = array(
    '#type'          => 'textfield',
    '#title'         => $ocalc_zone." 4",
    '#title_display' => 'invisible',
    '#weight'        => -11,
    '#maxlength'     => 4,
    '#size'          => 4,
    '#field_suffix'  => "mm",                   
  );

Viewing all articles
Browse latest Browse all 291566

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>