Drupal 7 Form API: Sử dụng #states cho multiple conditionals (AND, OR and XOR)

Drupal 7 Form API: Sử dụng #states cho multiple conditionals (AND, OR and XOR)

I've been playing with D7 forms lately and have found #states to be somewhat challenging due to lack of documentation on Form API page.
I've poked around a bit and decided to write a blog with my findings in case someone else is in need of this info down the road.
If you are looking for a robust solution for conditional fields, I would suggest looking into conditional fields or a more lightweight approach field conditional states (thanks for the comment Arjan and rooby).

If you have a simple, one off case where you have a conditional field and are reluctant to introduce 2-3k lines of code, you can use hook_form_alter() and #states API.
For this example I will use a very simple content type, Item, with following fields:

Title (title) [text]
Item Type (field_item_type) [select_list]:

    tv_show|TV Show
    movie|Movie
    banana|Banana for Scale
    truck|Truck

Format (field_format) [select_list]:

    video_dvd|DVD
    video_bluray|Blu-Ray
    video_3d|3D Blu-Ray

So I want to hide format field by default and display it only in case we are creating an Item of type TV Show or Movie.
I've created a simple module with the form alter that looks like this:

<?php
 
/**
 *  Implements hook_form_alter().
 */
function mtm_formapi_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'item_node_form') {
    $form['field_format']['#states'] = array(
      'visible' => array(
        ':input[name="field_item_type[und]"]' => array('value' => 'tv_show'),
      ),
    );
  }
}

The above code is pretty much it when it comes to Form API documentation on #states.
What it does is display field_format if the item type is TV Show, that is if :input[name="field_item_type[und]"] selector matches tv_show, otherwise it hides the format field.
But what about if there is more than one valid condition or if we need to meet multiple conditions?
Unfortunately, this is where things get a bit chaotic. There is not a common pattern that you can follow. Instead, you will need to change your strategy a bit depending on what your need is.
In case where you have multiple conditions which all need to be met, you can follow the pattern established in #state API docs:

    '[field-selector]' => array('[evaluate]'),
    '[field-selector2]' => array('[evaluate]'),
    ...
<?php
 
/**
 *  Implements hook_form_alter().
 */
function mtm_formapi_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'item_node_form') {
    $form['field_format']['#states'] = array(
      'visible' => array(
        ':input[name="field_item_type[und]"]' => array('value' => 'tv_show'),
        '#edit-title' => array('value' => 'test'),
      ),
    );
  }
}

The above will only show format field if title is test AND Item type is TV Show.
However, our original task was to display format if our Item type is TV Show OR Movie. The pattern in the docs will not work in this case.
Instead the pattern is the following:

    array('[field-selector]' => array('[evaluate]')),
    '[OR/XOR]',
    array('[field-selector2]' => array('[evaluate]')),
    ...
<?php
 
/**
 *  Implements hook_form_alter().
 */
function mtm_formapi_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'item_node_form') {
    $form['field_format']['#states'] = array(
      'visible' => array(
        array(
          array(':input[name="field_item_type[und]"]' => array('value' => 'tv_show')),
          'or',
          array(':input[name="field_item_type[und]"]' => array('value' => 'movie')),
        ),
      ),
    );
  }
}

Note above, we are using indexed instead of associative array and each individual statement is wrapped in an array.
The same pattern will work for XOR statements, all you have to do is replace 'or' with 'xor'. In addition, OR condition is implied when using the pattern above. That is, if I were to omit 'or' in the previous statement, the code would still behave as expected.

The support for OR and XOR came a bit latter, thus the chaos in the pattern and documentation.
One thing to keep in mind, if you are using jquery_update 1.7 and are using the OR and XOR, make sure you update it to the latest version as it overrides the form states.js and 1.7 doesn't support OR/XOR's.

 

Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
1/3 trong số hơn 1 triệu sinh viên nước ngoài tại Mỹ là công dân Trung Quốc

SV Trung Quốc - hàng không, công nghệ và kỹ thuật cao kẹt nghề nghiệp tại Mỹ

Từ mùa hè năm ngoái, sinh viên Trung Quốc theo học các ngành liên quan đến sản xuất robot, hàng không, công nghệ và kỹ thuật cao bị kiểm soát thị thực chặt chẽ hơn ở Mỹ.

Twitter vượt mốc 200 triệu người dùng

Twitter vượt mốc 200 triệu người dùng

Hôm qua (18/12), Twitter đã công bố rằng mạng xã hội này vừa vượt qua mốc 200 triệu người dùng hoạt động thường xuyên.

Hướng dẫn thêm Links to Fields trong Views

Hướng dẫn thêm Links to Fields trong Views

This blog post is the answer to a common request we get from people learning how to use Views.

Công ty diệt chuột T&C

 

Diet con trung