Issue #1241938 by swentel, Niklas Fiekas, yched: Added support for #placeholder to relevant Field API widgets.

8.0.x
webchick 2012-11-28 23:26:16 -08:00
parent 3f9edaa32c
commit 63619f5c64
13 changed files with 141 additions and 7 deletions

View File

@ -20,11 +20,27 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase;
* label = @Translation("E-mail"), * label = @Translation("E-mail"),
* field_types = { * field_types = {
* "email" * "email"
* },
* settings = {
* "placeholder" = ""
* } * }
* ) * )
*/ */
class EmailDefaultWidget extends WidgetBase { class EmailDefaultWidget extends WidgetBase {
/**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
*/
public function settingsForm(array $form, array &$form_state) {
$element['placeholder'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
return $element;
}
/** /**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
*/ */
@ -32,6 +48,7 @@ class EmailDefaultWidget extends WidgetBase {
$element['value'] = $element + array( $element['value'] = $element + array(
'#type' => 'email', '#type' => 'email',
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
'#placeholder' => $this->getSetting('placeholder'),
); );
return $element; return $element;
} }

View File

@ -56,6 +56,9 @@ class EmailFieldTest extends WebTestBase {
'bundle' => 'test_bundle', 'bundle' => 'test_bundle',
'widget' => array( 'widget' => array(
'type' => 'email_default', 'type' => 'email_default',
'settings' => array(
'placeholder' => 'example@example.com',
),
), ),
'display' => array( 'display' => array(
'full' => array( 'full' => array(
@ -69,6 +72,7 @@ class EmailFieldTest extends WebTestBase {
$this->drupalGet('test-entity/add/test_bundle'); $this->drupalGet('test-entity/add/test_bundle');
$langcode = LANGUAGE_NOT_SPECIFIED; $langcode = LANGUAGE_NOT_SPECIFIED;
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget found.'); $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget found.');
$this->assertRaw('placeholder="example@example.com"');
// Submit a valid e-mail address and ensure it is accepted. // Submit a valid e-mail address and ensure it is accepted.
$value = 'test@example.com'; $value = 'test@example.com';

View File

@ -58,6 +58,9 @@ class LinkFieldTest extends WebTestBase {
), ),
'widget' => array( 'widget' => array(
'type' => 'link_default', 'type' => 'link_default',
'settings' => array(
'placeholder_url' => 'http://example.com',
),
), ),
'display' => array( 'display' => array(
'full' => array( 'full' => array(
@ -71,6 +74,7 @@ class LinkFieldTest extends WebTestBase {
// Display creation form. // Display creation form.
$this->drupalGet('test-entity/add/test_bundle'); $this->drupalGet('test-entity/add/test_bundle');
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][url]", '', 'Link URL field is displayed'); $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][url]", '', 'Link URL field is displayed');
$this->assertRaw('placeholder="http://example.com"');
// Verify that a valid URL can be submitted. // Verify that a valid URL can be submitted.
$value = 'http://www.example.com/'; $value = 'http://www.example.com/';
@ -121,6 +125,10 @@ class LinkFieldTest extends WebTestBase {
), ),
'widget' => array( 'widget' => array(
'type' => 'link_default', 'type' => 'link_default',
'settings' => array(
'placeholder_url' => 'http://example.com',
'placeholder_title' => 'Enter a title for this link',
),
), ),
'display' => array( 'display' => array(
'full' => array( 'full' => array(
@ -141,11 +149,15 @@ class LinkFieldTest extends WebTestBase {
// Display creation form. // Display creation form.
$this->drupalGet('test-entity/add/test_bundle'); $this->drupalGet('test-entity/add/test_bundle');
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][url]", '', 'URL field found.'); $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][url]", '', 'URL field found.');
$this->assertRaw('placeholder="http://example.com"');
if ($title_setting === DRUPAL_DISABLED) { if ($title_setting === DRUPAL_DISABLED) {
$this->assertNoFieldByName("{$this->field['field_name']}[$langcode][0][title]", '', 'Title field not found.'); $this->assertNoFieldByName("{$this->field['field_name']}[$langcode][0][title]", '', 'Title field not found.');
$this->assertNoRaw('placeholder="Enter a title for this link"');
} }
else { else {
$this->assertRaw('placeholder="Enter a title for this link"');
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][title]", '', 'Title field found.'); $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][title]", '', 'Title field found.');
if ($title_setting === DRUPAL_REQUIRED) { if ($title_setting === DRUPAL_REQUIRED) {
// Verify that the title is required, if the URL is non-empty. // Verify that the title is required, if the URL is non-empty.

View File

@ -97,19 +97,53 @@ function link_field_widget_info() {
$widgets['link_default'] = array( $widgets['link_default'] = array(
'label' => 'Link', 'label' => 'Link',
'field types' => array('link'), 'field types' => array('link'),
'settings' => array(
'placeholder_title' => '',
'placeholder_url' => '',
),
); );
return $widgets; return $widgets;
} }
/**
* Implements hook_field_widget_settings_form().
*/
function link_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
$form['placeholder_url'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder for URL'),
'#default_value' => $settings['placeholder_url'],
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
$form['placeholder_title'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder for link title'),
'#default_value' => $settings['placeholder_title'],
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
'#states' => array(
'invisible' => array(
':input[name="instance[settings][title]"]' => array('value' => DRUPAL_DISABLED),
),
),
);
return $form;
}
/** /**
* Implements hook_field_widget_form(). * Implements hook_field_widget_form().
*/ */
function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$settings = $instance['settings']; $settings = $instance['settings'];
$widget_settings = $instance['widget']['settings'];
$element['url'] = array( $element['url'] = array(
'#type' => 'url', '#type' => 'url',
'#title' => t('URL'), '#title' => t('URL'),
'#placeholder' => isset($widget_settings['placeholder_url']) ? $widget_settings['placeholder_url'] : '',
'#default_value' => isset($items[$delta]['url']) ? $items[$delta]['url'] : NULL, '#default_value' => isset($items[$delta]['url']) ? $items[$delta]['url'] : NULL,
'#maxlength' => 2048, '#maxlength' => 2048,
'#required' => $element['#required'], '#required' => $element['#required'],
@ -117,6 +151,7 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
$element['title'] = array( $element['title'] = array(
'#type' => 'textfield', '#type' => 'textfield',
'#title' => t('Title'), '#title' => t('Title'),
'#placeholder' => isset($widget_settings['placeholder_title']) ? $widget_settings['placeholder_title'] : '',
'#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL, '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL,
'#maxlength' => 255, '#maxlength' => 255,
'#access' => $settings['title'] != DRUPAL_DISABLED, '#access' => $settings['title'] != DRUPAL_DISABLED,

View File

@ -22,11 +22,27 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase;
* "number_integer", * "number_integer",
* "number_decimal", * "number_decimal",
* "number_float" * "number_float"
* },
* settings = {
* "placeholder" = ""
* } * }
* ) * )
*/ */
class NumberWidget extends WidgetBase { class NumberWidget extends WidgetBase {
/**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
*/
public function settingsForm(array $form, array &$form_state) {
$element['placeholder'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
return $element;
}
/** /**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
*/ */
@ -39,6 +55,7 @@ class NumberWidget extends WidgetBase {
$element += array( $element += array(
'#type' => 'number', '#type' => 'number',
'#default_value' => $value, '#default_value' => $value,
'#placeholder' => $this->getSetting('placeholder'),
); );
// Set the step for floating point and decimal numbers. // Set the step for floating point and decimal numbers.

View File

@ -59,6 +59,9 @@ class NumberFieldTest extends WebTestBase {
'bundle' => 'test_bundle', 'bundle' => 'test_bundle',
'widget' => array( 'widget' => array(
'type' => 'number', 'type' => 'number',
'settings' => array(
'placeholder' => '0.00'
),
), ),
'display' => array( 'display' => array(
'default' => array( 'default' => array(
@ -72,6 +75,7 @@ class NumberFieldTest extends WebTestBase {
$this->drupalGet('test-entity/add/test_bundle'); $this->drupalGet('test-entity/add/test_bundle');
$langcode = LANGUAGE_NOT_SPECIFIED; $langcode = LANGUAGE_NOT_SPECIFIED;
$this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget is displayed'); $this->assertFieldByName("{$this->field['field_name']}[$langcode][0][value]", '', 'Widget is displayed');
$this->assertRaw('placeholder="0.00"');
// Submit a signed decimal value within the allowed precision and scale. // Submit a signed decimal value within the allowed precision and scale.
$value = '-1234.5678'; $value = '-1234.5678';

View File

@ -22,7 +22,8 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase;
* "text_long" * "text_long"
* }, * },
* settings = { * settings = {
* "rows" = "5" * "rows" = "5",
* "placeholder" = ""
* } * }
* ) * )
*/ */
@ -39,6 +40,12 @@ class TextareaWidget extends WidgetBase {
'#required' => TRUE, '#required' => TRUE,
'#min' => 1, '#min' => 1,
); );
$element['placeholder'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
return $element; return $element;
} }
@ -50,6 +57,7 @@ class TextareaWidget extends WidgetBase {
'#type' => 'textarea', '#type' => 'textarea',
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
'#rows' => $this->getSetting('rows'), '#rows' => $this->getSetting('rows'),
'#placeholder' => $this->getSetting('placeholder'),
'#attributes' => array('class' => array('text-full')), '#attributes' => array('class' => array('text-full')),
); );

View File

@ -22,7 +22,8 @@ use Drupal\Core\Annotation\Translation;
* }, * },
* settings = { * settings = {
* "rows" = "9", * "rows" = "9",
* "summary_rows" = "3" * "summary_rows" = "3",
* "placeholder" = ""
* } * }
* ) * )
*/ */

View File

@ -22,7 +22,8 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase;
* "text" * "text"
* }, * },
* settings = { * settings = {
* "size" = "60" * "size" = "60",
* "placeholder" = ""
* } * }
* ) * )
*/ */
@ -39,6 +40,12 @@ class TextfieldWidget extends WidgetBase {
'#required' => TRUE, '#required' => TRUE,
'#min' => 1, '#min' => 1,
); );
$element['placeholder'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
return $element; return $element;
} }
@ -50,6 +57,7 @@ class TextfieldWidget extends WidgetBase {
'#type' => 'textfield', '#type' => 'textfield',
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
'#size' => $this->getSetting('size'), '#size' => $this->getSetting('size'),
'#placeholder' => $this->getSetting('placeholder'),
'#maxlength' => $this->field['settings']['max_length'], '#maxlength' => $this->field['settings']['max_length'],
'#attributes' => array('class' => array('text-full')), '#attributes' => array('class' => array('text-full')),
); );

View File

@ -114,6 +114,9 @@ class TextFieldTest extends WebTestBase {
), ),
'widget' => array( 'widget' => array(
'type' => $widget_type, 'type' => $widget_type,
'settings' => array(
'placeholder' => 'A placeholder on ' . $widget_type,
),
), ),
'display' => array( 'display' => array(
'full' => array( 'full' => array(
@ -128,6 +131,7 @@ class TextFieldTest extends WebTestBase {
$this->drupalGet('test-entity/add/test_bundle'); $this->drupalGet('test-entity/add/test_bundle');
$this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed'); $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
$this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', 'Format selector is not displayed'); $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', 'Format selector is not displayed');
$this->assertRaw(format_string('placeholder="A placeholder on !widget_type"', array('!widget_type' => $widget_type)));
// Submit with some value. // Submit with some value.
$value = $this->randomName(); $value = $this->randomName();

View File

@ -25,7 +25,7 @@ abstract class FieldUiTestBase extends WebTestBase {
parent::setUp(); parent::setUp();
// Create test user. // Create test user.
$admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer users')); $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy', 'administer users', 'bypass node access'));
$this->drupalLogin($admin_user); $this->drupalLogin($admin_user);
// Create content type, with underscores. // Create content type, with underscores.

View File

@ -23,13 +23,27 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase;
* }, * },
* settings = { * settings = {
* "size" = "60", * "size" = "60",
* "autocomplete_path" = "taxonomy/autocomplete" * "autocomplete_path" = "taxonomy/autocomplete",
* "placeholder" = ""
* }, * },
* multiple_values = TRUE * multiple_values = TRUE
* ) * )
*/ */
class TaxonomyAutocompleteWidget extends WidgetBase { class TaxonomyAutocompleteWidget extends WidgetBase {
/**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
*/
public function settingsForm(array $form, array &$form_state) {
$element['placeholder'] = array(
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('The placeholder is a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.'),
);
return $element;
}
/** /**
* Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
*/ */
@ -45,6 +59,7 @@ class TaxonomyAutocompleteWidget extends WidgetBase {
'#default_value' => taxonomy_implode_tags($tags), '#default_value' => taxonomy_implode_tags($tags),
'#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $field['field_name'], '#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $field['field_name'],
'#size' => $this->getSetting('size'), '#size' => $this->getSetting('size'),
'#placeholder' => $this->getSetting('placeholder'),
'#maxlength' => 1024, '#maxlength' => 1024,
'#element_validate' => array('taxonomy_autocomplete_validate'), '#element_validate' => array('taxonomy_autocomplete_validate'),
); );

View File

@ -142,7 +142,12 @@ class TermTest extends TaxonomyTestBase {
function testNodeTermCreationAndDeletion() { function testNodeTermCreationAndDeletion() {
// Enable tags in the vocabulary. // Enable tags in the vocabulary.
$instance = $this->instance; $instance = $this->instance;
$instance['widget'] = array('type' => 'taxonomy_autocomplete'); $instance['widget'] = array(
'type' => 'taxonomy_autocomplete',
'settings' => array(
'placeholder' => 'Start typing here.',
),
);
field_update_instance($instance); field_update_instance($instance);
$terms = array( $terms = array(
'term1' => $this->randomName(), 'term1' => $this->randomName(),
@ -159,8 +164,12 @@ class TermTest extends TaxonomyTestBase {
// free-tagging field created by the default profile. // free-tagging field created by the default profile.
$edit[$instance['field_name'] . "[$langcode]"] = drupal_implode_tags($terms); $edit[$instance['field_name'] . "[$langcode]"] = drupal_implode_tags($terms);
// Verify the placeholder is there.
$this->drupalGet('node/add/article');
$this->assertRaw('placeholder="Start typing here."');
// Preview and verify the terms appear but are not created. // Preview and verify the terms appear but are not created.
$this->drupalPost('node/add/article', $edit, t('Preview')); $this->drupalPost(NULL, $edit, t('Preview'));
foreach ($terms as $term) { foreach ($terms as $term) {
$this->assertText($term, 'The term appears on the node preview'); $this->assertText($term, 'The term appears on the node preview');
} }