Index: /trunk/admin/batch_manager.php
===================================================================
--- /trunk/admin/batch_manager.php	(revision 29248)
+++ /trunk/admin/batch_manager.php	(revision 29249)
@@ -536,4 +536,5 @@
 $heights = array();
 $ratios = array();
+$dimensions = array();
 
 // get all width, height and ratios
@@ -566,26 +567,18 @@
 }
 
-
-
-$widths = array_unique($widths);
-sort($widths);
-
-$heights = array_unique($heights);
-sort($heights);
-
-$ratios = array_unique($ratios);
-sort($ratios);
-
-$dimensions['widths'] = implode(',', $widths);
-$dimensions['heights'] = implode(',', $heights);
-$dimensions['ratios'] = implode(',', $ratios);
+foreach (array('widths','heights','ratios') as $type)
+{
+  ${$type} = array_unique(${$type});
+  sort(${$type});
+  $dimensions[$type] = implode(',', ${$type});
+}
 
 $dimensions['bounds'] = array(
   'min_width' => $widths[0],
-  'max_width' => $widths[count($widths)-1],
+  'max_width' => end($widths),
   'min_height' => $heights[0],
-  'max_height' => $heights[count($heights)-1],
+  'max_height' => end($heights),
   'min_ratio' => $ratios[0],
-  'max_ratio' => $ratios[count($ratios)-1],
+  'max_ratio' => end($ratios),
   );
 
@@ -618,11 +611,11 @@
 }
 
-foreach (array_keys($ratio_categories) as $ratio_category)
-{
-  if (count($ratio_categories[$ratio_category]) > 0)
-  {
-    $dimensions['ratio_'.$ratio_category] = array(
-      'min' => $ratio_categories[$ratio_category][0],
-      'max' => array_pop($ratio_categories[$ratio_category]),
+foreach (array_keys($ratio_categories) as $type)
+{
+  if (count($ratio_categories[$type]) > 0)
+  {
+    $dimensions['ratio_'.$type] = array(
+      'min' => $ratio_categories[$type][0],
+      'max' => end($ratio_categories[$type]),
       );
   }
@@ -645,4 +638,5 @@
 
 $filesizes = array();
+$filesize = array();
 
 $query = '
@@ -676,5 +670,5 @@
 $filesize['bounds'] = array(
   'min' => $filesizes[0],
-  'max' => $filesizes[count($filesizes)-1],
+  'max' => end($filesizes),
   );
 
Index: /trunk/admin/themes/clear/theme.css
===================================================================
--- /trunk/admin/themes/clear/theme.css	(revision 29248)
+++ /trunk/admin/themes/clear/theme.css	(revision 29249)
@@ -295,5 +295,5 @@
 #batchManagerGlobal .thumbSelected {background-color:#C2F5C2 !important}
 #batchManagerGlobal #selectedMessage {background-color:#C2F5C2;}
-#filter_dimension_width_info, #filter_dimension_height_info, #filter_dimension_ratio_info, #filter_filesize_info {color:#ff7700;font-weight:bold;}
+.slider-info {color:#ff7700;font-weight:bold;}
 
 .selectedComment {background-color:#C2F5C2;}
Index: /trunk/admin/themes/default/js/batchManagerGlobal.js
===================================================================
--- /trunk/admin/themes/default/js/batchManagerGlobal.js	(revision 29248)
+++ /trunk/admin/themes/default/js/batchManagerGlobal.js	(revision 29249)
@@ -44,4 +44,8 @@
 });
 
+$('[data-slider=widths]').pwgDoubleSlider(sliders.widths);
+$('[data-slider=heights]').pwgDoubleSlider(sliders.heights);
+$('[data-slider=ratios]').pwgDoubleSlider(sliders.ratios);
+$('[data-slider=filesizes]').pwgDoubleSlider(sliders.filesizes);
 
 
Index: /trunk/admin/themes/default/js/doubleSlider.js
===================================================================
--- /trunk/admin/themes/default/js/doubleSlider.js	(revision 29249)
+++ /trunk/admin/themes/default/js/doubleSlider.js	(revision 29249)
@@ -0,0 +1,43 @@
+(function($){
+
+/**
+ * OPTIONS:
+ * values {mixed[]}
+ * selected {object} min and max
+ * text {string}
+ */
+$.fn.pwgDoubleSlider = function(options) {
+  var that = this;
+  
+  function onChange(e, ui) {
+    that.find('[data-input=min]').val(options.values[ui.values[0]]);
+    that.find('[data-input=max]').val(options.values[ui.values[1]]);
+
+    that.find('.slider-info').html(sprintf(
+      options.text,
+      options.values[ui.values[0]],
+      options.values[ui.values[1]]
+    ));
+  }
+
+  var slider = this.find('.slider-slider').slider({
+    range: true,
+    min: 0,
+    max: options.values.length - 1,
+    values: [
+      options.values.indexOf(options.selected.min),
+      options.values.indexOf(options.selected.max)
+    ],
+    slide: onChange,
+    change: onChange
+  });
+
+  this.find('.slider-choice').on('click', function(){
+    slider.slider('values', 0, options.values.indexOf($(this).data('min')));
+    slider.slider('values', 1, options.values.indexOf($(this).data('max')));
+  });
+
+  return this;
+};
+
+}(jQuery));
Index: /trunk/admin/themes/default/template/batch_manager_global.tpl
===================================================================
--- /trunk/admin/themes/default/template/batch_manager_global.tpl	(revision 29248)
+++ /trunk/admin/themes/default/template/batch_manager_global.tpl	(revision 29249)
@@ -5,6 +5,7 @@
 {combine_script id='common' load='footer' path='admin/themes/default/js/common.js'}
 
-{combine_script id='jquery.ui.slider' require='jquery.ui' load='footer' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'}
+{combine_script id='jquery.ui.slider' require='jquery.ui' load='async' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'}
 {combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"}
+{combine_script id='doubleSlider' load='async' require='jquery.ui.slider' path='admin/themes/default/js/doubleSlider.js'}
 
 {combine_script id='LocalStorageCache' load='footer' path='admin/themes/default/js/LocalStorageCache.js'}
@@ -17,5 +18,5 @@
 {combine_script id='jquery.ajaxmanager' load='async' path='themes/default/js/plugins/jquery.ajaxmanager.js'}
 
-{combine_script id='batchManagerGlobal' load='async' require='jquery,datepicker,jquery.colorbox,addAlbum' path='admin/themes/default/js/batchManagerGlobal.js'}
+{combine_script id='batchManagerGlobal' load='async' require='jquery,datepicker,jquery.colorbox,addAlbum,doubleSlider' path='admin/themes/default/js/batchManagerGlobal.js'}
 
 {footer_script}
@@ -265,130 +266,4 @@
   checkPermitAction();
 
-	{* /* dimensions sliders */
-	/**
-	 * find the key from a value in the startStopValues array
-	 */ *}
-  function getSliderKeyFromValue(value, values) {
-    for (var key in values) {
-      if (values[key] == value) {
-        return key;
-      }
-    }
-
-    return 0;
-  }
-
-  var dimension_values = {
-    width:[{$dimensions.widths}],
-    height:[{$dimensions.heights}],
-    ratio:[{$dimensions.ratios}]
-  };
-
-	function onSliderChange(type, ui, pattern) {
-		$("input[name='filter_dimension_min_"+type+"']").val(dimension_values[type][ui.values[0]]);
-		$("input[name='filter_dimension_max_"+type+"']").val(dimension_values[type][ui.values[1]]);
-
-		$("#filter_dimension_"+type+"_info").html(sprintf(
-			pattern,
-			dimension_values[type][ui.values[0]],
-			dimension_values[type][ui.values[1]]
-		));
-	}
-	
-  $("#filter_dimension_width_slider").slider({
-    range: true,
-    min: 0,
-    max: dimension_values['width'].length - 1,
-    values: [
-      getSliderKeyFromValue({$dimensions.selected.min_width}, dimension_values['width']),
-      getSliderKeyFromValue({$dimensions.selected.max_width}, dimension_values['width'])
-    ],
-		slide: function(event, ui) {
-			onSliderChange('width', ui, "{'between %d and %d pixels'|translate|escape:'javascript'}");
-		},
-		change: function(event, ui) {
-			onSliderChange('width', ui, "{'between %d and %d pixels'|translate|escape:'javascript'}");
-		}
-  });
-
-  $("#filter_dimension_height_slider").slider({
-    range: true,
-    min: 0,
-    max: dimension_values['height'].length - 1,
-    values: [
-      getSliderKeyFromValue({$dimensions.selected.min_height}, dimension_values['height']),
-      getSliderKeyFromValue({$dimensions.selected.max_height}, dimension_values['height'])
-    ],
-		slide: function(event, ui) {
-			onSliderChange('height', ui, "{'between %d and %d pixels'|translate|escape:'javascript'}");
-		},
-		change: function(event, ui) {
-			onSliderChange('height', ui, "{'between %d and %d pixels'|translate|escape:'javascript'}");
-		}
-  });
-
-  $("#filter_dimension_ratio_slider").slider({
-    range: true,
-    min: 0,
-    max: dimension_values['ratio'].length - 1,
-    values: [
-      getSliderKeyFromValue({$dimensions.selected.min_ratio}, dimension_values['ratio']),
-      getSliderKeyFromValue({$dimensions.selected.max_ratio}, dimension_values['ratio'])
-    ],
-		slide: function(event, ui) {
-			onSliderChange('ratio', ui, "{'between %.2f and %.2f'|translate|escape:'javascript'}");
-		},
-		change: function(event, ui) {
-			onSliderChange('ratio', ui, "{'between %.2f and %.2f'|translate|escape:'javascript'}");
-		}
-  });
-
-  $("a.dimensions-choice").click(function() {
-    var type = jQuery(this).data("type");
-    var min = jQuery(this).data("min");
-    var max = jQuery(this).data("max");
-
-		$("#filter_dimension_"+ type +"_slider")
-			.slider("values", 0, getSliderKeyFromValue(min, dimension_values[type]) )
-			.slider("values", 1, getSliderKeyFromValue(max, dimension_values[type]) );
-  });
-
-  {* filesize, copied from dimensions filter and modified, to be moved in a plugin later *}
-  var filesize_values = [{$filesize.list}];
-
-  function filesize_onSliderChange(ui, pattern) {
-    $("input[name='filter_filesize_min']").val(filesize_values[ui.values[0]]);
-    $("input[name='filter_filesize_max']").val(filesize_values[ui.values[1]]);
-
-    $("#filter_filesize_info").html(sprintf(
-      pattern,
-      filesize_values[ui.values[0]],
-      filesize_values[ui.values[1]]
-    ));
-  }
-	
-  $("#filter_filesize_slider").slider({
-    range: true,
-    min: 0,
-    max: filesize_values.length - 1,
-    values: [
-      getSliderKeyFromValue({$filesize.selected.min}, filesize_values),
-      getSliderKeyFromValue({$filesize.selected.max}, filesize_values)
-    ],
-    slide: function(event, ui) {
-      filesize_onSliderChange(ui, "{'between %s and %s MB'|translate|escape:'javascript'}");
-    },
-    change: function(event, ui) {
-      filesize_onSliderChange(ui, "{'between %s and %s MB'|translate|escape:'javascript'}");
-    }
-  });
-
-  $("a.filesize-choice").click(function() {
-    $("#filter_filesize_slider")
-      .slider("values", 0, 0)
-      .slider("values", 1, filesize_values.length - 1);
-  });
-
-
   jQuery("select[name=filter_prefilter]").change(function() {
     jQuery("#empty_caddie").toggle(jQuery(this).val() == "caddie");
@@ -397,4 +272,43 @@
 });
 
+{*<!-- sliders config -->*}
+var sliders = {
+  widths: {
+    values: [{$dimensions.widths}],
+    selected: {
+      min: {$dimensions.selected.min_width},
+      max: {$dimensions.selected.max_width},
+    },
+    text: '{'between %d and %d pixels'|translate|escape:'javascript'}'
+  },
+
+  heights: {
+    values: [{$dimensions.heights}],
+    selected: {
+      min: {$dimensions.selected.min_height},
+      max: {$dimensions.selected.max_height},
+    },
+    text: '{'between %d and %d pixels'|translate|escape:'javascript'}'
+  },
+
+  ratios: {
+    values: [{$dimensions.ratios}],
+    selected: {
+      min: {$dimensions.selected.min_ratio},
+      max: {$dimensions.selected.max_ratio},
+    },
+    text: '{'between %.2f and %.2f'|translate|escape:'javascript'}'
+  },
+
+  filesizes: {
+    values: [{$filesize.list}],
+    selected: {
+      min: {$filesize.selected.min},
+      max: {$filesize.selected.max},
+    },
+    text: '{'between %s and %s MB'|translate|escape:'javascript'}'
+  }
+};
+
 {/footer_script}
 
@@ -404,5 +318,5 @@
 
   <form action="{$F_ACTION}" method="post">
-	<input type="hidden" name="start" value="{$START}">
+  <input type="hidden" name="start" value="{$START}">
 
   <fieldset>
@@ -462,38 +376,38 @@
         <a href="#" class="removeFilter" title="remove this filter"><span>[x]</span></a>
         <input type="checkbox" name="filter_dimension_use" class="useFilterCheckbox" {if isset($filter.dimension)}checked="checked"{/if}>
-        {'Dimensions'|@translate}
+        {'Dimensions'|translate}
 
         <blockquote>
-          {'Width'|@translate} <span id="filter_dimension_width_info">{'between %d and %d pixels'|@translate:$dimensions.selected.min_width:$dimensions.selected.max_width}</span>
-          | <a class="dimensions-choice" data-type="width" data-min="{$dimensions.bounds.min_width}" data-max="{$dimensions.bounds.max_width}">{'Reset'|@translate}</a>
-          <div id="filter_dimension_width_slider"></div>
-
-          {'Height'|@translate} <span id="filter_dimension_height_info">{'between %d and %d pixels'|@translate:$dimensions.selected.min_height:$dimensions.selected.max_height}</span>
-          | <a class="dimensions-choice" data-type="height" data-min="{$dimensions.bounds.min_height}" data-max="{$dimensions.bounds.max_height}">{'Reset'|@translate}</a>
-          <div id="filter_dimension_height_slider"></div>
-
-          {'Ratio'|@translate} ({'Width'|@translate}/{'Height'|@translate}) <span id="filter_dimension_ratio_info">{'between %.2f and %.2f'|@translate:$dimensions.selected.min_ratio:$dimensions.selected.max_ratio}</span>
-{if isset($dimensions.ratio_portrait)}
-          | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_portrait.min}" data-max="{$dimensions.ratio_portrait.max}">{'Portrait'|@translate}</a>
-{/if}
-{if isset($dimensions.ratio_square)}
-          | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_square.min}" data-max="{$dimensions.ratio_square.max}">{'square'|@translate}</a>
-{/if}
-{if isset($dimensions.ratio_landscape)}
-          | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_landscape.min}" data-max="{$dimensions.ratio_landscape.max}">{'Landscape'|@translate}</a>
-{/if}
-{if isset($dimensions.ratio_panorama)}
-          | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.ratio_panorama.min}" data-max="{$dimensions.ratio_panorama.max}">{'Panorama'|@translate}</a>
-{/if}
-          | <a class="dimensions-choice" data-type="ratio" data-min="{$dimensions.bounds.min_ratio}" data-max="{$dimensions.bounds.max_ratio}">{'Reset'|@translate}</a>
-          <div id="filter_dimension_ratio_slider"></div>
+          <div data-slider="widths">
+            {'Width'|translate} <span class="slider-info">{'between %d and %d pixels'|translate:$dimensions.selected.min_width:$dimensions.selected.max_width}</span>
+            | <a class="slider-choice" data-min="{$dimensions.bounds.min_width}" data-max="{$dimensions.bounds.max_width}">{'Reset'|translate}</a>
+            <div class="slider-slider"></div>
+
+            <input type="hidden" data-input="min" name="filter_dimension_min_width" value="{$dimensions.selected.min_width}">
+            <input type="hidden" data-input="max" name="filter_dimension_max_width" value="{$dimensions.selected.max_width}">
+          </div>
+
+          <div data-slider="heights">
+            {'Height'|translate} <span class="slider-info">{'between %d and %d pixels'|translate:$dimensions.selected.min_height:$dimensions.selected.max_height}</span>
+            | <a class="slider-choice" data-min="{$dimensions.bounds.min_height}" data-max="{$dimensions.bounds.max_height}">{'Reset'|translate}</a>
+            <div class="slider-slider"></div>
+            
+            <input type="hidden" data-input="min" name="filter_dimension_min_height" value="{$dimensions.selected.min_height}">
+            <input type="hidden" data-input="max" name="filter_dimension_max_height" value="{$dimensions.selected.max_height}">
+          </div>
+
+          <div data-slider="ratios">
+            {'Ratio'|translate} ({'Width'|@translate}/{'Height'|@translate}) <span class="slider-info">{'between %.2f and %.2f'|translate:$dimensions.selected.min_ratio:$dimensions.selected.max_ratio}</span>
+            {if isset($dimensions.ratio_portrait)}| <a class="slider-choice" data-min="{$dimensions.ratio_portrait.min}" data-max="{$dimensions.ratio_portrait.max}">{'Portrait'|translate}</a>{/if}
+            {if isset($dimensions.ratio_square)}| <a class="slider-choice" data-min="{$dimensions.ratio_square.min}" data-max="{$dimensions.ratio_square.max}">{'square'|translate}</a>{/if}
+            {if isset($dimensions.ratio_landscape)}| <a class="slider-choice" data-min="{$dimensions.ratio_landscape.min}" data-max="{$dimensions.ratio_landscape.max}">{'Landscape'|translate}</a>{/if}
+            {if isset($dimensions.ratio_panorama)}| <a class="slider-choice" data-min="{$dimensions.ratio_panorama.min}" data-max="{$dimensions.ratio_panorama.max}">{'Panorama'|translate}</a>{/if}
+            | <a class="slider-choice" data-min="{$dimensions.bounds.min_ratio}" data-max="{$dimensions.bounds.max_ratio}">{'Reset'|translate}</a>
+            <div class="slider-slider"></div>
+
+            <input type="hidden" data-input="min" name="filter_dimension_min_ratio" value="{$dimensions.selected.min_ratio}">
+            <input type="hidden" data-input="max" name="filter_dimension_max_ratio" value="{$dimensions.selected.max_ratio}">
+          </div>
         </blockquote>
-
-        <input type="hidden" name="filter_dimension_min_width" value="{$dimensions.selected.min_width}">
-        <input type="hidden" name="filter_dimension_max_width" value="{$dimensions.selected.max_width}">
-        <input type="hidden" name="filter_dimension_min_height" value="{$dimensions.selected.min_height}">
-        <input type="hidden" name="filter_dimension_max_height" value="{$dimensions.selected.max_height}">
-        <input type="hidden" name="filter_dimension_min_ratio" value="{$dimensions.selected.min_ratio}">
-        <input type="hidden" name="filter_dimension_max_ratio" value="{$dimensions.selected.max_ratio}">
       </li>
 
@@ -510,14 +424,16 @@
         <a href="#" class="removeFilter" title="remove this filter"><span>[x]</span></a>
         <input type="checkbox" name="filter_filesize_use" class="useFilterCheckbox" {if isset($filter.filesize)}checked="checked"{/if}>
-        {'Filesize'|@translate}
+        {'Filesize'|translate}
 
         <blockquote>
-          <span id="filter_filesize_info">{'between %s and %s MB'|@translate:$filesize.selected.min:$filesize.selected.max}</span>
-          | <a class="filesize-choice">{'Reset'|@translate}</a>
-          <div id="filter_filesize_slider"></div>
+          <div data-slider="filesizes">
+            <span class="slider-info">{'between %s and %s MB'|translate:$filesize.selected.min:$filesize.selected.max}</span>
+            | <a class="slider-choice" data-min="{$filesize.bounds.min}" data-max="{$filesize.bounds.max}">{'Reset'|translate}</a>
+            <div class="slider-slider"></div>
+
+            <input type="hidden" data-input="min" name="filter_filesize_min" value="{$filesize.selected.min}">
+            <input type="hidden" data-input="max" name="filter_filesize_max" value="{$filesize.selected.max}">
+          </div>
         </blockquote>
-
-        <input type="hidden" name="filter_filesize_min" value="{$filesize.selected.min}">
-        <input type="hidden" name="filter_filesize_max" value="{$filesize.selected.max}">
       </li>
     </ul>
