diff --git a/core/includes/form.inc b/core/includes/form.inc index 85bffc6..8546835 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -3334,6 +3334,9 @@ function form_process_tableselect($element) { * different character, 'replace_pattern' needs to be set accordingly. * - error: (optional) A custom form error message string to show, if the * machine name contains disallowed characters. + * - standalone: (optional) Whether the live preview should stay in it's own + * form element rather than in the prefix of the source element. Defaults + * to FALSE. * - #maxlength: (optional) Should be set to the maximum allowed length of the * machine name. Defaults to 64. * - #disabled: (optional) Should be set to TRUE in case an existing machine @@ -3345,6 +3348,9 @@ function form_process_machine_name($element, &$form_state) { '#title' => t('Machine-readable name'), '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'), '#machine_name' => array(), + '#field_prefix' => '', + '#field_suffix' => '', + '#prefix' => '', ); // A form element that only wants to set one #machine_name property (usually // 'source' only) would leave all other properties undefined, if the defaults @@ -3355,6 +3361,9 @@ function form_process_machine_name($element, &$form_state) { 'label' => t('Machine name'), 'replace_pattern' => '[^a-z0-9_]+', 'replace' => '_', + 'standalone' => FALSE, + 'field_prefix' => $element['#field_prefix'], + 'field_suffix' => $element['#field_suffix'], ); // By default, machine names are restricted to Latin alphanumeric characters. @@ -3378,16 +3387,21 @@ function form_process_machine_name($element, &$form_state) { return $element; } - // Append a field suffix to the source form element, which will contain - // the live preview of the machine name. $suffix_id = $source['#id'] . '-machine-name-suffix'; - $source += array('#field_suffix' => ''); - $source['#field_suffix'] .= '  '; + $element['#machine_name']['suffix'] = '#' . $suffix_id; - $parents = array_merge($element['#machine_name']['source'], array('#field_suffix')); - drupal_array_set_nested_value($form_state['complete_form'], $parents, $source['#field_suffix']); + if (!$element['#machine_name']['standalone']) { + // Append a field suffix to the source form element, which will contain + // the live preview of the machine name. + $source += array('#field_suffix' => ''); + $source['#field_suffix'] .= '  '; - $element['#machine_name']['suffix'] = '#' . $suffix_id; + $parents = array_merge($element['#machine_name']['source'], array('#field_suffix')); + drupal_array_set_nested_value($form_state['complete_form'], $parents, $source['#field_suffix']); + } + else { + $element['#prefix'] .= '  '; + } $js_settings = array( 'type' => 'setting', diff --git a/core/misc/machine-name.js b/core/misc/machine-name.js index 996cf84..59db638 100644 --- a/core/misc/machine-name.js +++ b/core/misc/machine-name.js @@ -19,6 +19,10 @@ Drupal.behaviors.machineName = { * disallowed characters in the machine name; e.g., '[^a-z0-9]+'. * - replace: A character to replace disallowed characters with; e.g., '_' * or '-'. + * - standalone: Whether the preview should stay in it's own element rather + * than the prefix of the source element. + * - field_prefix: The #field_prefix of the form element. + * - field_suffix: The #field_suffix of the form element. */ attach: function (context, settings) { var self = this; @@ -33,12 +37,17 @@ Drupal.behaviors.machineName = { } // Skip processing upon a form validation error on the machine name. if ($target.hasClass('error')) { + $suffix.hide(); return; } // Figure out the maximum length for the machine name. options.maxlength = $target.attr('maxlength'); - // Hide the form item container of the machine name form element. - $wrapper.hide(); + // Hide the form item of the machine name form element. + $wrapper.children().hide(); + if (options.standalone) { + $wrapper.find('.description').show(); + } + // Determine the initial machine name value. Unless the machine name form // element is disabled or not empty, the initial default value is based on // the human-readable form element value. @@ -49,10 +58,12 @@ Drupal.behaviors.machineName = { var machine = self.transliterate($source.val(), options); } // Append the machine name preview to the source field. - var $preview = $('' + machine + ''); - $suffix.empty() - .append(' ').append('' + options.label + ':') - .append(' ').append($preview); + var $preview = $('' + options.field_prefix + Drupal.checkPlain(machine) + options.field_suffix + ''); + $suffix.empty(); + if (options.label) { + $suffix.append(' ').append('' + options.label + ':'); + } + $suffix.append(' ').append($preview); // If the machine name cannot be edited, stop further processing. if ($target.is(':disabled')) { @@ -62,7 +73,7 @@ Drupal.behaviors.machineName = { // If it is editable, append an edit link. var $link = $('' + Drupal.t('Edit') + '') .click(function () { - $wrapper.show(); + $wrapper.children().show(); $target.focus(); $suffix.hide(); $source.unbind('.machineName'); @@ -77,9 +88,9 @@ Drupal.behaviors.machineName = { $source.bind('keyup.machineName change.machineName', function () { machine = self.transliterate($(this).val(), options); // Set the machine name to the transliterated value. - if (machine != options.replace && machine != '') { + if (machine != options.replace && (options.field_prefix + machine + options.field_suffix) != '') { $target.val(machine); - $preview.text(machine); + $preview.html(options.field_prefix + Drupal.checkPlain(machine) + options.field_suffix); $suffix.show(); } else { diff --git a/core/modules/field/modules/list/list.module b/core/modules/field/modules/list/list.module index 0d397a4..c2bff2a 100644 --- a/core/modules/field/modules/list/list.module +++ b/core/modules/field/modules/list/list.module @@ -345,7 +345,7 @@ function list_field_update_forbid($field, $prior_field, $has_data) { // Forbid any update that removes allowed values with actual data. $lost_keys = array_diff(array_keys($prior_field['settings']['allowed_values']), array_keys($field['settings']['allowed_values'])); if (_list_values_in_use($field, $lost_keys)) { - throw new FieldUpdateForbiddenException(t('Cannot update a list field to not include keys with existing data.')); + throw new FieldUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field['field_name']))); } } } diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc index 24a99e1..0e59dd2 100644 --- a/core/modules/field_ui/field_ui.admin.inc +++ b/core/modules/field_ui/field_ui.admin.inc @@ -329,7 +329,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle t('Label'), t('Weight'), t('Parent'), - t('Name'), + t('Machine name'), t('Field'), t('Widget'), array('data' => t('Operations'), 'colspan' => 2), @@ -511,16 +511,24 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle ), ), 'field_name' => array( - '#type' => 'textfield', + '#type' => 'machine_name', '#title' => t('New field name'), '#title_display' => 'invisible', // This field should stay LTR even for RTL languages. '#field_prefix' => 'field_', '#field_suffix' => '‎', - '#attributes' => array('dir'=>'ltr'), + '#attributes' => array('dir' => 'ltr'), '#size' => 10, - '#description' => t('Field name (a-z, 0-9, _)'), + '#maxlength' => 32 - drupal_strlen('field_'), + '#description' => t('Machine name'), '#prefix' => '
 
', + '#machine_name' => array( + 'source' => array('fields', $name, 'label'), + 'exists' => '_field_ui_field_name_exists', + 'standalone' => TRUE, + 'label' => '', + ), + '#required' => FALSE, ), 'type' => array( '#type' => 'select', @@ -695,21 +703,6 @@ function _field_ui_field_overview_form_validate_add_new($form, &$form_state) { $field_name = 'field_' . $field_name; form_set_value($form['fields']['_add_new_field']['field_name'], $field_name, $form_state); } - - // Invalid field name. - if (!preg_match('!^field_[a-z0-9_]+$!', $field_name)) { - form_set_error('fields][_add_new_field][field_name', t('Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%field_name' => $field_name))); - } - if (strlen($field_name) > 32) { - form_set_error('fields][_add_new_field][field_name', t("Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the 'field_' prefix.", array('%field_name' => $field_name))); - } - - // Field name already exists. We need to check inactive fields as well, so - // we can't use field_info_fields(). - $fields = field_read_fields(array('field_name' => $field_name), array('include_inactive' => TRUE)); - if ($fields) { - form_set_error('fields][_add_new_field][field_name', t('Add new field: the field name %field_name already exists.', array('%field_name' => $field_name))); - } } // Missing field type. @@ -732,6 +725,24 @@ function _field_ui_field_overview_form_validate_add_new($form, &$form_state) { } /** + * Render API callback: Checks if a field machine name is taken. + * + * @param $value + * The machine name, not prefixed with 'field_'. + * + * @return + * Whether or not the field machine name is taken. + */ +function _field_ui_field_name_exists($value) { + // Prefix with 'field_'. + $field_name = 'field_' . $value; + + // We need to check inactive fields as well, so we can't use + // field_info_fields(). + return (bool) field_read_fields(array('field_name' => $field_name), array('include_inactive' => TRUE)); +} + +/** * Validates the 'add existing field' row of field_ui_field_overview_form(). * * @see field_ui_field_overview_form_validate() diff --git a/core/modules/field_ui/field_ui.test b/core/modules/field_ui/field_ui.test index c2e3a98..47de230 100644 --- a/core/modules/field_ui/field_ui.test +++ b/core/modules/field_ui/field_ui.test @@ -202,7 +202,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase { // Check all table columns. $table_headers = array( t('Label'), - t('Name'), + t('Machine name'), t('Field'), t('Widget'), t('Operations'),