diff --git a/better_exposed_filters.css b/better_exposed_filters.css
index bc1c2d9..4d49803 100644
--- a/better_exposed_filters.css
+++ b/better_exposed_filters.css
@@ -13,3 +13,13 @@ fieldset.bef-select-as-checkboxes-fieldset.collapsed legend
 {
   position: relative;
 }
+
+/*
+ * Styles for the jQuery UI slider widgets.
+ */
+.bef-slider.ui-slider-horizontal {
+  margin-top: 6px;
+}
+.bef-slider.ui-slider-vertical {
+  margin-top: 12px;
+}
diff --git a/better_exposed_filters.js b/better_exposed_filters.js
index 3a7b59b..971752e 100644
--- a/better_exposed_filters.js
+++ b/better_exposed_filters.js
@@ -83,11 +83,11 @@
       ;
 
       // Check for and initialize datepickers
-      if (Drupal.settings.better_exposed_filters.bef_datepicker) {
+      if (Drupal.settings.better_exposed_filters.datepicker) {
         // Note: JavaScript does not treat "" as null
-        if (Drupal.settings.better_exposed_filters.bef_dateformat) {
+        if (Drupal.settings.better_exposed_filters.datepicker_options.dateformat) {
           $('.bef-datepicker').datepicker({
-            dateFormat: Drupal.settings.better_exposed_filters.bef_dateformat
+            dateFormat: Drupal.settings.better_exposed_filters.datepicker_options.dateformat
           });
         }
         else {
@@ -124,6 +124,128 @@
       });
     }
   }
+
+  Drupal.behaviors.better_exposed_filters_slider = {
+    attach: function(context, settings) {
+      if (Drupal.settings.better_exposed_filters.slider) {
+        $.each(Drupal.settings.better_exposed_filters.slider_options, function(i, sliderOptions) {
+          // Only make one slider per filter.
+          $("#" + sliderOptions.viewId + " #edit-" + sliderOptions.id + "-wrapper").once('slider-filter', function() {
+            var $input = $(this).find('input[type=text]');
+
+            // This is a "between" or "not between" filter with two values.
+            if ($input.length == 2) {
+              var $min = $input.parent().find('input#edit-' + sliderOptions.id + '-min'),
+                  $max = $input.parent().find('input#edit-' + sliderOptions.id + '-max'),
+                  default_min,
+                  default_max;
+
+              if (!$min.length || !$max.length) {
+                return;
+              }
+
+              // Get the default values.
+              // We use slider min & max if there are no defaults.
+              default_min = parseFloat(($min.val() == '') ? sliderOptions.min : $min.val(), 10);
+              default_max = parseFloat(($max.val() == '') ? sliderOptions.max : $max.val(), 10);
+              // Set the element value in case we are using the slider min & max.
+              $min.val(default_min);
+              $max.val(default_max);
+
+              $min.parents('div.views-widget').after(
+                $('<div class="bef-slider"></div>').slider({
+                  range: true,
+                  min: parseFloat(sliderOptions.min, 10),
+                  max: parseFloat(sliderOptions.max, 10),
+                  step: parseFloat(sliderOptions.step, 10),
+                  animate: sliderOptions.animate ? sliderOptions.animate : false,
+                  orientation: sliderOptions.orientation,
+                  values: [default_min, default_max],
+                  // Update the textfields as the sliders are moved
+                  slide: function (event, ui) {
+                    $min.val(ui.values[0]);
+                    $max.val(ui.values[1]);
+                  },
+                  // This fires when the value is set programmatically or the
+                  // stop event fires.
+                  // This takes care of the case that a user enters a value
+                  // into the text field that is not a valid step of the slider.
+                  // In that case the slider will go to the nearest step and
+                  // this change event will update the text area.
+                  change: function (event, ui) {
+                    $min.val(ui.values[0]);
+                    $max.val(ui.values[1]);
+                  },
+                  // Attach stop listeners.
+                  stop: function(event, ui) {
+                    // Click the auto submit button.
+                    $(this).parents('form').find('.ctools-auto-submit-click').click();
+                  }
+                })
+              );
+
+              // Update the slider when the fields are updated.
+              $min.blur(function() {
+                befUpdateSlider($(this), 0, sliderOptions);
+              });
+              $max.blur(function() {
+                befUpdateSlider($(this), 1, sliderOptions);
+              });
+            }
+            // This is single value filter.
+            else if ($input.length == 1) {
+              if ($input.attr('id') != 'edit-' + sliderOptions.id) {
+                return;
+              }
+
+              // Get the default value. We use slider min if there is no default.
+              var default_value = parseFloat(($input.val() == '') ? sliderOptions.min : $input.val(), 10);
+              // Set the element value in case we are using the slider min.
+              $input.val(default_value);
+
+              $input.parents('div.views-widget').after(
+                $('<div class="bef-slider"></div>').slider({
+                  min: parseFloat(sliderOptions.min, 10),
+                  max: parseFloat(sliderOptions.max, 10),
+                  step: parseFloat(sliderOptions.step, 10),
+                  animate: sliderOptions.animate ? sliderOptions.animate : false,
+                  orientation: sliderOptions.orientation,
+                  value: default_value,
+                  // Update the textfields as the sliders are moved.
+                  slide: function (event, ui) {
+                    $input.val(ui.value);
+                  },
+                  // This fires when the value is set programmatically or the
+                  // stop event fires.
+                  // This takes care of the case that a user enters a value
+                  // into the text field that is not a valid step of the slider.
+                  // In that case the slider will go to the nearest step and
+                  // this change event will update the text area.
+                  change: function (event, ui) {
+                    $input.val(ui.value);
+                  },
+                  // Attach stop listeners.
+                  stop: function(event, ui) {
+                    // Click the auto submit button.
+                    $(this).parents('form').find('.ctools-auto-submit-click').click();
+                  }
+                })
+              );
+
+              // Update the slider when the field is updated.
+              $input.blur(function() {
+                befUpdateSlider($(this), null, sliderOptions);
+              });
+            }
+            else {
+              return;
+            }
+          })
+        });
+      }
+    }
+  };
+
   /*
    * Helper functions
    */
@@ -138,4 +260,60 @@
       : $elem.closest('.form-item', context).removeClass('highlight');
   }
 
+  /**
+   * Update a slider when a related input element is changed.
+   *
+   * We don't need to check whether the new value is valid based on slider min,
+   * max, and step because the slider will do that automatically and then we
+   * update the textfield on the slider's change event.
+   *
+   * We still have to make sure that the min & max values of a range slider
+   * don't pass each other though, however once this jQuery UI bug is fixed we
+   * won't have to. - http://bugs.jqueryui.com/ticket/3762
+   *
+   * @param $el
+   *   A jQuery object of the updated element.
+   * @param valIndex
+   *   The index of the value for a range slider or null for a non-range slider.
+   * @param sliderOptions
+   *   The options for the current slider.
+   */
+  function befUpdateSlider($el, valIndex, sliderOptions) {
+    var val = parseFloat($el.val(), 10),
+        currentMin = $el.parents('div.views-widget').next('.bef-slider').slider('values', 0),
+        currentMax = $el.parents('div.views-widget').next('.bef-slider').slider('values', 1);
+    // If we have a range slider.
+    if (valIndex != null) {
+      // Make sure the min is not more than the current max value.
+      if (valIndex == 0 && val > currentMax) {
+        val = currentMax;
+      }
+      // Make sure the max is not more than the current max value.
+      if (valIndex == 1 && val < currentMin) {
+        val = currentMin;
+      }
+      // If the number is invalid, go back to the last value.
+      if (isNaN(val)) {
+        val = $el.parents('div.views-widget').next('.bef-slider').slider('values', valIndex);
+      }
+    }
+    else {
+      // If the number is invalid, go back to the last value.
+      if (isNaN(val)) {
+        val = $el.parents('div.views-widget').next('.bef-slider').slider('value');
+      }
+    }
+    // Make sure we are a number again.
+    val = parseFloat(val, 10);
+    // Set the slider to the new value.
+    // The slider's change event will then update the textfield again so that
+    // they both have the same value.
+    if (valIndex != null) {
+      $el.parents('div.views-widget').next('.bef-slider').slider('values', valIndex, val);
+    }
+    else {
+      $el.parents('div.views-widget').next('.bef-slider').slider('value', val);
+    }
+  }
+
 }) (jQuery);
diff --git a/better_exposed_filters.module b/better_exposed_filters.module
index 76eae42..9a03aef 100644
--- a/better_exposed_filters.module
+++ b/better_exposed_filters.module
@@ -87,3 +87,97 @@ function bef_sort_combine_submit($form, &$form_state) {
   // And pass this along to Views
   views_exposed_form_submit($form, $form_state);
 }
+
+/**
+ * Form element validation handler for BEF jQuery slider required fields.
+ */
+function better_exposed_filters_element_validate_slider_required($element, &$form_state) {
+  $value = $element['#value'];
+  // If a jQuery slider format has been selected make sure the min & max value
+  // fields are not empty.
+  if ($value == '' && _better_exposed_filters_slider_selected($element, $form_state)) {
+    form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
+  }
+}
+
+/**
+ * Form element validation handler for BEF jQuery slider animate setting.
+ */
+function better_exposed_filters_element_validate_slider_animate($element, &$form_state) {
+  $value = $element['#value'];
+  if ($value !== '' && _better_exposed_filters_slider_selected($element, $form_state) &&
+      ((!is_numeric($value) || intval($value) != $value || $value <= 0) &&
+       !in_array($value, array('slow', 'normal', 'fast')))) {
+    form_error($element, t('%name must be "slow", "normal", "fast" or the number of milliseconds to run the animation (e.g. 1000).', array('%name' => $element['#title'])));
+  }
+}
+
+/**
+ * Form element validation handler for BEF jQuery slider min and max settings.
+ *
+ * The max value must be greater than the min value.
+ */
+function better_exposed_filters_element_validate_slider_min_max($element, &$form_state) {
+  $value = $element['#value'];
+  $slider_min = $form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['slider_options']['bef_slider_min'];
+  $slider_max = $form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['slider_options']['bef_slider_max'];
+
+  if ($value !== '' && _better_exposed_filters_slider_selected($element, $form_state)) {
+    // Must not have more than 11 decimal places.
+    if (_better_exposed_filters_get_num_decimal_places($value) > 11) {
+      form_error($element, t('%name must not have more than 11 decimal places.', array('%name' => $element['#title'])));
+    }
+    // The slider min must be less than the slider max.
+    if (is_numeric($slider_min) && is_numeric($slider_max) && ($slider_max <= $slider_min)) {
+      form_error($element, t('The Range minimum value must be less than the Range maximum value.'));
+    }
+  }
+}
+
+/**
+ * Form element validation handler for BEF jQuery slider step setting.
+ *
+ * The full specified value range of the slider (range maximum - range minimum)
+ * should be evenly divisible by the step.
+ */
+function better_exposed_filters_element_validate_slider_step($element, &$form_state) {
+  $value = $element['#value'];
+
+  if ($value !== '' && _better_exposed_filters_slider_selected($element, $form_state)) {
+    $slider_min = $form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['slider_options']['bef_slider_min'];
+    $slider_max = $form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['slider_options']['bef_slider_max'];
+
+    // Must be positive.
+    if ($value < 0) {
+      form_error($element, t('%name must be a positive number.', array('%name' => $element['#title'])));
+    }
+    // Must not have more than 5 decimal places.
+    if (_better_exposed_filters_get_num_decimal_places($value) > 5) {
+      form_error($element, t('%name must not have more than 5 decimal places.', array('%name' => $element['#title'])));
+    }
+    // The slider range must be evenly divisible by the step.
+    // We check like this because of the issues PHP has with inaccurate floats,
+    // where 2 might actually be 1.9999999999.
+    // Because of this we can't reliably use fmod().
+    if (is_numeric($slider_min) && is_numeric($slider_max) && !ctype_digit((string) abs(($slider_max - $slider_min) / $value))) {
+      form_error($element, t('The range of the slider (Range maximum - Range minimum) should be evenly divisible by the step.'));
+    }
+  }
+}
+
+/**
+ * Return whether or not the slider has been selected for the given filter.
+ */
+function _better_exposed_filters_slider_selected($element, &$form_state) {
+  return (isset($element['#bef_filter_id']) &&
+          isset($form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['bef_format']) &&
+          $form_state['values']['exposed_form_options']['bef'][$element['#bef_filter_id']]['bef_format'] == 'bef_slider');
+}
+
+/**
+ * Return the number of decimal places of the given number.
+ */
+function _better_exposed_filters_get_num_decimal_places($number) {
+  $str = (string) $number;
+  return strlen(substr(strrchr($str, '.'), 1));
+}
diff --git a/better_exposed_filters_exposed_form_plugin.inc b/better_exposed_filters_exposed_form_plugin.inc
index 68ca833..0b16ead 100644
--- a/better_exposed_filters_exposed_form_plugin.inc
+++ b/better_exposed_filters_exposed_form_plugin.inc
@@ -214,6 +214,9 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
       // Used for date-based filters
       $bef_datepicker = FALSE;
 
+      // Used for numeric filters.
+      $bef_slider = FALSE;
+
       /*
        * Check various filter types and determine what options are available
        */
@@ -244,6 +247,12 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
         $bef_datepicker = TRUE;
       }
 
+      // The date filter handler extends the numeric filter handler so we have
+      // to exclude it specifically.
+      if ($filter instanceof views_handler_filter_numeric && !($filter instanceof views_handler_filter_date)) {
+        $bef_slider = TRUE;
+      }
+
       // All filters can use the default filter exposed by Views
       $display_options = array('default' => t('Default select list'));
 
@@ -264,6 +273,10 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
         $display_options['bef_datepicker'] = t('jQuery UI Datepicker');
       }
 
+      if ($bef_slider) {
+        $display_options['bef_slider'] = t('jQuery UI slider');
+      }
+
       if ($bef_standard) {
         // Less used BEF options, so put them last.
         $display_options['bef_links'] = t('Links');
@@ -281,6 +294,87 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
         '#options' => $display_options,
       );
 
+      if ($bef_slider) {
+        // Fieldset for jQuery slider options.
+        $bef_options[$label]['slider_options'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Slider options for @identifier', array('@identifier' => $identifier)),
+          '#collapsible' => TRUE,
+          '#collapsed' => FALSE,
+          '#states' => array(
+            'visible' => array(
+              ':input[name="exposed_form_options[bef][' . $label . '][bef_format]"]' => array('value' => 'bef_slider'),
+            ),
+          ),
+        );
+
+        $bef_options[$label]['slider_options']['bef_slider_min'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Range minimum'),
+          '#default_value' => $this->options['bef'][$label]['slider_options']['bef_slider_min'],
+          '#bef_filter_id' => $label,
+          '#states' => array(
+            'required' => array(
+              ':input[name="exposed_form_options[bef][' . $label . '][bef_format]"]' => array('value' => 'bef_slider'),
+            ),
+          ),
+          '#description' => t('The minimum allowed value for the jQuery range slider. It can be positive, negative, or zero and have up to 11 decimal places.'),
+          '#element_validate' => array('element_validate_number', 'better_exposed_filters_element_validate_slider_required', 'better_exposed_filters_element_validate_slider_min_max'),
+        );
+        $bef_options[$label]['slider_options']['bef_slider_max'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Range maximum'),
+          '#default_value' => $this->options['bef'][$label]['slider_options']['bef_slider_max'],
+          '#bef_filter_id' => $label,
+          '#states' => array(
+            'required' => array(
+              ':input[name="exposed_form_options[bef][' . $label . '][bef_format]"]' => array('value' => 'bef_slider'),
+            ),
+          ),
+          '#description' => t('The maximum allowed value for the jQuery range slider. It can be positive, negative, or zero and have up to 11 decimal places.'),
+          '#element_validate' => array('element_validate_number', 'better_exposed_filters_element_validate_slider_required', 'better_exposed_filters_element_validate_slider_min_max'),
+        );
+        $bef_options[$label]['slider_options']['bef_slider_step'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Step'),
+          '#default_value' => empty($this->options['bef'][$label]['slider_options']['bef_slider_step']) ? 1 : $this->options['bef'][$label]['slider_options']['bef_slider_step'],
+          '#bef_filter_id' => $label,
+          '#states' => array(
+            'required' => array(
+              ':input[name="exposed_form_options[bef][' . $label . '][bef_format]"]' => array('value' => 'bef_slider'),
+            ),
+          ),
+          '#description' => t('Determines the size or amount of each interval or step the slider takes between the min and max.') . '<br />' .
+                            t('The full specified value range of the slider (Range maximum - Range minimum) must be evenly divisible by the step.') . '<br />' .
+                            t('The step must be a positive number of up to 5 decimal places.'),
+          '#element_validate' => array('element_validate_number', 'better_exposed_filters_element_validate_slider_required', 'better_exposed_filters_element_validate_slider_step'),
+        );
+        $bef_options[$label]['slider_options']['bef_slider_animate'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Animate'),
+          '#default_value' => $this->options['bef'][$label]['slider_options']['bef_slider_animate'],
+          '#bef_filter_id' => $label,
+          '#description' => t('Whether to slide handle smoothly when user click outside handle on the bar. Allowed values are "slow", "normal", "fast" or the number of milliseconds to run the animation (e.g. 1000). If left blank, there will be no animation, the slider will just jump to the new value instantly.'),
+          '#element_validate' => array('better_exposed_filters_element_validate_slider_animate'),
+        );
+        $bef_options[$label]['slider_options']['bef_slider_orientation'] = array(
+          '#type' => 'select',
+          '#title' => t('Orientation'),
+          '#options' => array(
+            'horizontal' => t('Horizontal'),
+            'vertical' => t('Vertical'),
+          ),
+          '#default_value' => $this->options['bef'][$label]['slider_options']['bef_slider_orientation'],
+          '#bef_filter_id' => $label,
+          '#states' => array(
+            'required' => array(
+              ':input[name="exposed_form_options[bef][' . $label . '][bef_format]"]' => array('value' => 'bef_slider'),
+            ),
+          ),
+          '#description' => t('The orientation of the jQuery range slider.'),
+        );
+      }
+
       // Fieldset to keep the UI from getting out of hand
       $bef_options[$label]['more_options'] = array(
         '#type' => 'fieldset',
@@ -419,10 +513,16 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
     // If we have no visible elements, we don't show the Apply button.
     $show_apply = FALSE;
 
-    // We only want to add the datepicker code once.
-    // TODO: Does this need to be moved to a behavior.attach()?
-    $add_datepicker = FALSE;
-    $datepicker_format = '';
+    // Collect BEF's Javascript settings, add to Drupal.settings at the end.
+    $bef_add_js = FALSE;
+    $bef_js = array(
+      'datepicker' => FALSE,
+      'slider' => FALSE,
+      'settings' => array(),
+    );
+
+    // Some widgets will require additional CSS.
+    $bef_add_css = FALSE;
 
     // Grab BEF settings
     $settings = $this->_bef_get_settings();
@@ -699,7 +799,9 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
       switch ($options['bef_format']) {
         case 'bef_datepicker':
           $show_apply = TRUE;
-          $add_datepicker = TRUE;
+          $bef_add_js = TRUE;
+          $bef_js['datepicker'] = TRUE;
+          $bef_js['datepicker_options'] = array();
 
           if ((
             // Single Date API-based input element
@@ -782,7 +884,7 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
               $form[$field_id]['min']['#attributes']['class'][] = 'bef-datepicker';
               $form[$field_id]['max']['#attributes']['class'][] = 'bef-datepicker';
             }
-            $datepicker_format = str_replace(array_keys($convert), array_values($convert), $format);
+            $bef_js['datepicker_options']['dateformat'] = str_replace(array_keys($convert), array_values($convert), $format);
           }
           else {
             /*
@@ -804,6 +906,24 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
           }
           break;
 
+        case 'bef_slider':
+          $show_apply = TRUE;
+          $bef_add_js = TRUE;
+          $bef_add_css = TRUE;
+          $bef_js['slider'] = TRUE;
+
+          // Add js options for the slider for this filter.
+          $bef_js['slider_options'][$field_id] = array(
+            'min' => $options['slider_options']['bef_slider_min'],
+            'max' => $options['slider_options']['bef_slider_max'],
+            'step' => $options['slider_options']['bef_slider_step'],
+            'animate' => $options['slider_options']['bef_slider_animate'],
+            'orientation' => $options['slider_options']['bef_slider_orientation'],
+            'id' => drupal_html_id($field_id),
+            'viewId' => $form['#id'],
+          );
+          break;
+
         case 'bef_links':
           $show_apply = TRUE;
 
@@ -955,9 +1075,7 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
             }
 
             if ($options['more_options']['bef_select_all_none'] || $options['more_options']['bef_select_all_none_nested']) {
-              // Add BEF's JavaScript to the mix to handle select all/none functionality
-              // @TODO: move to #attached?
-              drupal_add_js(drupal_get_path('module', 'better_exposed_filters') . '/better_exposed_filters.js');
+              $bef_add_js = TRUE;
 
               if ($options['more_options']['bef_select_all_none']) {
                 $form[$field_id]['#bef_select_all_none'] = TRUE;
@@ -1009,18 +1127,21 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
     $form['submit']['#access'] = $show_apply;
     $form['reset']['#access'] = $show_apply;
 
-    // Only add datepicker code once
-    drupal_add_js(array('better_exposed_filters' => array('bef_datepicker' => FALSE)), 'setting');
-    if ($add_datepicker) {
-       // Add Datepicker JS and CSS
-      drupal_add_library('system', 'ui.datepicker');
-      drupal_add_js(drupal_get_path('module', 'better_exposed_filters') . '/better_exposed_filters.js');
+    // Add Javascript as needed.
+    if ($bef_add_js) {
+      // Add jQuery UI library code as needed.
+      if ($bef_js['datepicker']) {
+        drupal_add_library('system', 'ui.datepicker');
+      }
+      if ($bef_js['slider']) {
+        drupal_add_library('system', 'ui.slider');
+      }
 
-      // Trigger datepicker in better_exposed_filters.js
-      drupal_add_js(array('better_exposed_filters' => array(
-        'bef_datepicker' => TRUE,
-        'bef_dateformat' => $datepicker_format,
-      )), 'setting');
+      drupal_add_js(array('better_exposed_filters' => $bef_js), 'setting');
+      drupal_add_js(drupal_get_path('module', 'better_exposed_filters') . '/better_exposed_filters.js');
+    }
+    if ($bef_add_css) {
+      drupal_add_css(drupal_get_path('module', 'better_exposed_filters') . '/better_exposed_filters.css');
     }
 
     // Check for secondary elements
@@ -1166,6 +1287,13 @@ Title Desc|Z -> A</pre> Leave the replacement value blank to remove an option al
           'filter_rewrite_values' => '',
         ),
       ),
+      'slider_options' => array(
+        'bef_slider_min' => 0,
+        'bef_slider_max' => 99999,
+        'bef_slider_step' => 1,
+        'bef_slider_animate' => '',
+        'bef_slider_orientation' => 'horizontal',
+      ),
     );
 
     // Go through each exposed filter and collect settings
