diff --git a/core/includes/common.inc b/core/includes/common.inc
index 32f36b28a2c3745af76b93eb63fe07ed43098d68..eefc05344ca565df4f3f11c76001eef7fa0b158a 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6872,6 +6872,9 @@ function drupal_common_theme() {
'textfield' => array(
'render element' => 'element',
),
+ 'tel' => array(
+ 'render element' => 'element',
+ ),
'form' => array(
'render element' => 'element',
),
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 3469377619659792398778fd736d1014caec6c9d..5663ac6966085b5cad4b486db411d5ba574a1ef1 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3722,6 +3722,42 @@ function theme_textfield($variables) {
return $output . $extra;
}
+/**
+ * Returns HTML for a tel form element.
+ *
+ * @param $variables
+ * An associative array containing:
+ * - element: An associative array containing the properties of the element.
+ * Properties used: #title, #value, #description, #size, #maxlength,
+ * #placeholder, #required, #attributes, #autocomplete_path.
+ *
+ * @ingroup themeable
+ */
+function theme_tel($variables) {
+ $element = $variables['element'];
+ $element['#attributes']['type'] = 'tel';
+ element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
+ _form_set_class($element, array('form-tel'));
+
+ $extra = '';
+ if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
+ drupal_add_library('system', 'drupal.autocomplete');
+ $element['#attributes']['class'][] = 'form-autocomplete';
+
+ $attributes = array();
+ $attributes['type'] = 'hidden';
+ $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
+ $attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
+ $attributes['disabled'] = 'disabled';
+ $attributes['class'][] = 'autocomplete';
+ $extra = '';
+ }
+
+ $output = '';
+
+ return $output . $extra;
+}
+
/**
* Returns HTML for a form.
*
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 172a22e938b8de0fb125b169dde237a8f5945877..6adaf93fc311140d58ded97bfe8730162241d222 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -2235,6 +2235,7 @@ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) {
if (isset($edit[$name])) {
switch ($type) {
case 'text':
+ case 'tel':
case 'textarea':
case 'hidden':
case 'password':
diff --git a/core/modules/simpletest/tests/form.test b/core/modules/simpletest/tests/form.test
index 94dfa8749e16f0a5fa510f3292fde0965035bd2c..784da8849c9bae81542554339612c1217aa85810 100644
--- a/core/modules/simpletest/tests/form.test
+++ b/core/modules/simpletest/tests/form.test
@@ -37,6 +37,9 @@ class FormsTestCase extends DrupalWebTestCase {
$elements['textfield']['element'] = array('#title' => $this->randomName(), '#type' => 'textfield');
$elements['textfield']['empty_values'] = $empty_strings;
+ $elements['telephone']['element'] = array('#title' => $this->randomName(), '#type' => 'tel');
+ $elements['telephone']['empty_values'] = $empty_strings;
+
$elements['password']['element'] = array('#title' => $this->randomName(), '#type' => 'password');
$elements['password']['empty_values'] = $empty_strings;
@@ -258,7 +261,7 @@ class FormsTestCase extends DrupalWebTestCase {
// All the elements should be marked as disabled, including the ones below
// the disabled container.
- $this->assertEqual(count($disabled_elements), 32, t('The correct elements have the disabled property in the HTML code.'));
+ $this->assertEqual(count($disabled_elements), 33, t('The correct elements have the disabled property in the HTML code.'));
$this->drupalPost(NULL, $edit, t('Submit'));
$returned_values['hijacked'] = drupal_json_decode($this->content);
diff --git a/core/modules/simpletest/tests/form_test.module b/core/modules/simpletest/tests/form_test.module
index 5e3fb173ed9b28aae53c47fd315e7a7f2440b564..e1e2435fc3cbfb697d228c8616f769523ec3590f 100644
--- a/core/modules/simpletest/tests/form_test.module
+++ b/core/modules/simpletest/tests/form_test.module
@@ -1027,7 +1027,7 @@ function form_test_select_submit($form, &$form_state) {
* Builds a form to test the placeholder attribute.
*/
function form_test_placeholder_test($form, &$form_state) {
- foreach (array('textfield', 'textarea', 'password') as $type) {
+ foreach (array('textfield', 'textarea', 'password', 'tel') as $type) {
$form[$type] = array(
'#type' => $type,
'#title' => $type,
@@ -1102,7 +1102,7 @@ function form_test_checkboxes_radios($form, &$form_state, $customize = FALSE) {
*/
function _form_test_disabled_elements($form, &$form_state) {
// Elements that take a simple default value.
- foreach (array('textfield', 'textarea', 'hidden') as $type) {
+ foreach (array('textfield', 'textarea', 'tel', 'hidden') as $type) {
$form[$type] = array(
'#type' => $type,
'#title' => $type,
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index ed68dd3132357a3f7f4296f0847fcf4dddad36d4..28768f9b1b80c8880475e3a61cc0323b74ae4460 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -368,6 +368,15 @@ function system_element_info() {
'#theme' => 'textfield',
'#theme_wrappers' => array('form_element'),
);
+ $types['tel'] = array(
+ '#input' => TRUE,
+ '#size' => 30,
+ '#maxlength' => 128,
+ '#autocomplete_path' => FALSE,
+ '#process' => array('ajax_process_form'),
+ '#theme' => 'tel',
+ '#theme_wrappers' => array('form_element'),
+ );
$types['machine_name'] = array(
'#input' => TRUE,
'#default_value' => NULL,
diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css
index bd5c64269c5fa6903994ce0fec9611008e81e4a4..05a2758782f37f1d3dc263615741e40957737f24 100644
--- a/core/themes/bartik/css/style.css
+++ b/core/themes/bartik/css/style.css
@@ -1217,6 +1217,7 @@ select.form-select {
padding: 4px;
}
input.form-text,
+input.form-tel,
textarea.form-textarea,
select.form-select {
border: 1px solid #ccc;
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css
index e1ae4d011a18673829b7ee1d87d5c9f89e5d3339..7470a8ad3e1359da65ef27078cdfe8cbb9b295c8 100644
--- a/core/themes/seven/style.css
+++ b/core/themes/seven/style.css
@@ -609,6 +609,7 @@ div.teaser-checkbox .form-item,
}
.form-disabled input.form-autocomplete,
.form-disabled input.form-text,
+.form-disabled input.form-tel,
.form-disabled input.form-file,
.form-disabled textarea.form-textarea,
.form-disabled select.form-select {
@@ -696,6 +697,7 @@ input.form-button-disabled:active {
}
input.form-autocomplete,
input.form-text,
+input.form-tel,
input.form-file,
textarea.form-textarea,
select.form-select {
@@ -709,6 +711,7 @@ select.form-select {
transition: border linear 0.2s, box-shadow linear 0.2s;
}
input.form-text:focus,
+input.form-tel:focus,
input.form-file:focus,
textarea.form-textarea:focus,
select.form-select:focus {