diff --git a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
index 0ac151f..1e2a13d 100644
--- a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
+++ b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
@@ -90,7 +90,7 @@ function testTextField() {
*/
function testTextFieldFormatted() {
// Make node body multiple.
- $edit = array('field[cardinality]' => -1);
+ $edit = array('field[container][cardinality]' => -1);
$this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
$this->drupalGet('node/add/article');
$this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.');
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index 22069f7..a879a37 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -921,13 +921,35 @@ function field_ui_field_edit_form($form, &$form_state, $instance) {
if (field_behaviors_widget('multiple_values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
$description .= '
' . t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like.");
}
- $form['field']['cardinality'] = array(
- '#type' => 'select',
+
+ $cardinality = $field['cardinality'];
+ $form['field']['container'] = array(
+ // We can't use the container element because it doesn't support the
+ // title and description property.
+ '#type' => 'item',
+ '#field_prefix' => '
',
+ '#field_suffix' => '
',
'#title' => t('Number of values'),
- '#options' => array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + drupal_map_assoc(range(1, 10)),
- '#default_value' => $field['cardinality'],
'#description' => $description,
);
+ $form['field']['container']['cardinality'] = array(
+ '#type' => 'select',
+ '#options' => array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + drupal_map_assoc(range(1, 5)) + array('other' => t('More')),
+ '#default_value' => ($cardinality < 6) ? $cardinality : 'other',
+ );
+ // @todo Convert when http://drupal.org/node/1207060 gets in.
+ $form['field']['container']['cardinality_other'] = array(
+ '#type' => 'number',
+ '#default_value' => $cardinality > 5 ? $cardinality : 6,
+ '#min' => 1,
+ '#title' => t('Custom value'),
+ '#title_display' => 'invisible',
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="field[container][cardinality]"]' => array('value' => 'other'),
+ ),
+ ),
+ );
// Add additional field type settings. The field type module is
// responsible for not returning settings that cannot be changed if
@@ -1037,6 +1059,13 @@ function field_ui_field_edit_form_validate($form, &$form_state) {
$field_name = $instance['field_name'];
$entity = $form['#entity'];
+ // Validate field cardinality.
+ $cardinality = $form_state['values']['field']['container']['cardinality'];
+ $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+ if ($cardinality == 'other' && empty($cardinality_other)) {
+ form_error($form['field']['container']['cardinality_other'], t('Number of values is required.'));
+ }
+
if (isset($form['instance']['default_value_widget'])) {
$element = $form['instance']['default_value_widget'];
@@ -1077,6 +1106,15 @@ function field_ui_field_edit_form_submit($form, &$form_state) {
$field = $form['#field'];
$entity = $form['#entity'];
+ // Save field cardinality.
+ $cardinality = $form_state['values']['field']['container']['cardinality'];
+ $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+ if ($cardinality == 'other') {
+ $cardinality = $cardinality_other;
+ }
+ $form_state['values']['field']['cardinality'] = $cardinality;
+ unset($form_state['values']['field']['container']);
+
// Merge incoming values into the field.
$field = array_merge($field, $form_state['values']['field']);
try {
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 6aaec65..9108cc3 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -65,6 +65,7 @@ function testCRUDFields() {
$this->createField();
$this->updateField();
$this->addExistingField();
+ $this->cardinalitySettings();
}
/**
@@ -163,6 +164,49 @@ function addExistingField() {
}
/**
+ * Tests the cardinality settings of a field.
+ *
+ * We do not test if the number can be submitted with anything else than a
+ * numeric value. That is tested already in FormTest::testNumber().
+ */
+ function cardinalitySettings() {
+ $field_edit_path = 'admin/structure/types/manage/article/fields/body';
+
+ // Assert the cardinality other field cannot be empty when cardinality is
+ // set to other.
+ $edit = array(
+ 'field[container][cardinality]' => 'other',
+ 'field[container][cardinality_other]' => '',
+ );
+ $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+ $this->assertText('Please enter a number.');
+
+ // Assert the cardinality field is set to 'Other' when the value is greater
+ // than 5.
+ $edit = array(
+ 'field[container][cardinality]' => 'other',
+ 'field[container][cardinality_other]' => 16,
+ );
+ $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+ $this->assertText('Saved Body configuration.');
+ $this->drupalGet($field_edit_path);
+ $this->assertFieldByXPath("//select[@name='field[container][cardinality]']", 'other');
+ $this->assertFieldByXPath("//input[@name='field[container][cardinality_other]']", 16);
+
+ // Assert the cardinality other field is set back to 6 after changing the
+ // cardinality to less than 6.
+ $edit = array(
+ 'field[container][cardinality]' => 3,
+ 'field[container][cardinality_other]' => 16,
+ );
+ $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+ $this->assertText('Saved Body configuration.');
+ $this->drupalGet($field_edit_path);
+ $this->assertFieldByXPath("//select[@name='field[container][cardinality]']", 3);
+ $this->assertFieldByXPath("//input[@name='field[container][cardinality_other]']", 6);
+ }
+
+ /**
* Asserts field settings are as expected.
*
* @param $bundle