diff --git a/includes/common.inc b/includes/common.inc
index 4ec37dc..526eb6c 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -6558,6 +6558,9 @@ function drupal_common_theme() {
     'textfield' => array(
       'render element' => 'element',
     ),
+    'number' => array(
+      'render element' => 'element',
+    ),
     'form' => array(
       'render element' => 'element',
     ),
diff --git a/includes/form.inc b/includes/form.inc
index 8f2ee26..b72d2cd 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -3655,6 +3655,40 @@ function theme_textfield($variables) {
 }
 
 /**
+ * Returns HTML for a number 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,
+ *     #required, #attributes, #step.
+ *
+ * @ingroup themeable
+ */
+function theme_number($variables) {
+  $element = $variables['element'];
+  $element['#attributes']['type'] = 'number';
+  element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder', 'step', 'min', 'max'));
+  _form_set_class($element, array('form-text', 'form-number'));
+
+  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
+
+  return $output;
+}
+
+/**
+ * Form element validation handler for #type 'number'.
+ *
+ * Note that #maxlength and #required is validated by _form_validate() already.
+ */
+function form_validate_number(&$element, &$form_state) {
+  $value = $element['#value'];
+  if ($value != '' && !is_numeric($value)) {
+    form_error($element, t('%name must be a number.', array('%name' => $element['#title'])));
+  }
+}
+
+/**
  * Returns HTML for a form.
  *
  * @param $variables
diff --git a/modules/field/field.module b/modules/field/field.module
index b808e59..ec3006b 100644
--- a/modules/field/field.module
+++ b/modules/field/field.module
@@ -1195,12 +1195,3 @@ function _element_validate_integer_positive($element, &$form_state) {
   }
 }
 
-/**
- * Helper form element validator: number.
- */
-function _element_validate_number($element, &$form_state) {
-  $value = $element['#value'];
-  if ($value != '' && !is_numeric($value)) {
-    form_error($element, t('%name must be a number.', array('%name' => $element['#title'])));
-  }
-}
diff --git a/modules/field/modules/number/number.module b/modules/field/modules/number/number.module
index 20e3807..edfaf68 100644
--- a/modules/field/modules/number/number.module
+++ b/modules/field/modules/number/number.module
@@ -94,18 +94,16 @@ function number_field_instance_settings_form($field, $instance) {
   $settings = $instance['settings'];
 
   $form['min'] = array(
-    '#type' => 'textfield',
+    '#type' => 'number',
     '#title' => t('Minimum'),
     '#default_value' => $settings['min'],
     '#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
-    '#element_validate' => array('_element_validate_number'),
   );
   $form['max'] = array(
-    '#type' => 'textfield',
+    '#type' => 'number',
     '#title' => t('Maximum'),
     '#default_value' => $settings['max'],
     '#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
-    '#element_validate' => array('_element_validate_number'),
   );
   $form['prefix'] = array(
     '#type' => 'textfield',
@@ -334,6 +332,7 @@ function number_field_widget_form(&$form, &$form_state, $field, $instance, $lang
     '#maxlength' => $field['type'] == 'number_decimal' ? $field['settings']['precision'] + 2 : 10,
     // Extract the number type from the field type name for easier validation.
     '#number_type' => str_replace('number_', '', $field['type']),
+    '#element_validate' => array('form_validate_number'),
   );
 
   // Add prefix and suffix.
diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc
index 96beb13..ebcdc16 100644
--- a/modules/field_ui/field_ui.admin.inc
+++ b/modules/field_ui/field_ui.admin.inc
@@ -323,7 +323,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
         '#markup' => check_plain($instance['label']),
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#title' => t('Weight for @title', array('@title' => $instance['label'])),
         '#title_display' => 'invisible',
         '#default_value' => $instance['widget']['weight'],
@@ -392,7 +392,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
         '#markup' => check_plain($extra_field['label']),
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#default_value' => $extra_field['weight'],
         '#size' => 3,
         '#attributes' => array('class' => array('field-weight')),
@@ -451,7 +451,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
         '#suffix' => '</div>',
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#default_value' => $max_weight + 1,
         '#size' => 3,
         '#title_display' => 'invisible',
@@ -531,7 +531,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
         '#suffix' => '</div>',
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#default_value' => $max_weight + 2,
         '#size' => 3,
         '#title_display' => 'invisible',
@@ -905,7 +905,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
         '#markup' => check_plain($instance['label']),
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#title' => t('Weight for @title', array('@title' => $instance['label'])),
         '#title_display' => 'invisible',
         '#default_value' => $display['weight'],
@@ -1067,7 +1067,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
         '#markup' => check_plain($extra_field['label']),
       ),
       'weight' => array(
-        '#type' => 'textfield',
+        '#type' => 'number',
         '#title' => t('Weight for @title', array('@title' => $extra_field['label'])),
         '#title_display' => 'invisible',
         '#default_value' => $display['weight'],
diff --git a/modules/system/system.module b/modules/system/system.module
index 3ebc657..4cd80bb 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -355,6 +355,15 @@ function system_element_info() {
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
+  $types['number'] = array(
+    '#input' => TRUE,
+    '#size' => 60,
+    '#maxlength' => 128,
+    '#process' => array('ajax_process_form'),
+    '#element_validate' => array('form_validate_number'),
+    '#theme' => 'number',
+    '#theme_wrappers' => array('form_element'),
+  );
   $types['machine_name'] = array(
     '#input' => TRUE,
     '#default_value' => NULL,
