jquery.slider.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /**
  2. * jQuery EasyUI 1.5.2
  3. *
  4. * Copyright (c) 2009-2017 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. *
  9. */
  10. /**
  11. * slider - jQuery EasyUI
  12. *
  13. * Dependencies:
  14. * draggable
  15. *
  16. */
  17. (function($){
  18. function init(target){
  19. var slider = $('<div class="slider">' +
  20. '<div class="slider-inner">' +
  21. '<a href="javascript:;" class="slider-handle"></a>' +
  22. '<span class="slider-tip"></span>' +
  23. '</div>' +
  24. '<div class="slider-rule"></div>' +
  25. '<div class="slider-rulelabel"></div>' +
  26. '<div style="clear:both"></div>' +
  27. '<input type="hidden" class="slider-value">' +
  28. '</div>').insertAfter(target);
  29. var t = $(target);
  30. t.addClass('slider-f').hide();
  31. var name = t.attr('name');
  32. if (name){
  33. slider.find('input.slider-value').attr('name', name);
  34. t.removeAttr('name').attr('sliderName', name);
  35. }
  36. slider.bind('_resize', function(e,force){
  37. if ($(this).hasClass('easyui-fluid') || force){
  38. setSize(target);
  39. }
  40. return false;
  41. });
  42. return slider;
  43. }
  44. /**
  45. * set the slider size, for vertical slider, the height property is required
  46. */
  47. function setSize(target, param){
  48. var state = $.data(target, 'slider');
  49. var opts = state.options;
  50. var slider = state.slider;
  51. if (param){
  52. if (param.width) opts.width = param.width;
  53. if (param.height) opts.height = param.height;
  54. }
  55. slider._size(opts);
  56. if (opts.mode == 'h'){
  57. slider.css('height', '');
  58. slider.children('div').css('height', '');
  59. } else {
  60. slider.css('width', '');
  61. slider.children('div').css('width', '');
  62. slider.children('div.slider-rule,div.slider-rulelabel,div.slider-inner')._outerHeight(slider._outerHeight());
  63. }
  64. initValue(target);
  65. }
  66. /**
  67. * show slider rule if needed
  68. */
  69. function showRule(target){
  70. var state = $.data(target, 'slider');
  71. var opts = state.options;
  72. var slider = state.slider;
  73. var aa = opts.mode == 'h' ? opts.rule : opts.rule.slice(0).reverse();
  74. if (opts.reversed){
  75. aa = aa.slice(0).reverse();
  76. }
  77. _build(aa);
  78. function _build(aa){
  79. var rule = slider.find('div.slider-rule');
  80. var label = slider.find('div.slider-rulelabel');
  81. rule.empty();
  82. label.empty();
  83. for(var i=0; i<aa.length; i++){
  84. var distance = i*100/(aa.length-1)+'%';
  85. var span = $('<span></span>').appendTo(rule);
  86. span.css((opts.mode=='h'?'left':'top'), distance);
  87. // show the labels
  88. if (aa[i] != '|'){
  89. span = $('<span></span>').appendTo(label);
  90. span.html(aa[i]);
  91. if (opts.mode == 'h'){
  92. span.css({
  93. left: distance,
  94. marginLeft: -Math.round(span.outerWidth()/2)
  95. });
  96. } else {
  97. span.css({
  98. top: distance,
  99. marginTop: -Math.round(span.outerHeight()/2)
  100. });
  101. }
  102. }
  103. }
  104. }
  105. }
  106. /**
  107. * build the slider and set some properties
  108. */
  109. function buildSlider(target){
  110. var state = $.data(target, 'slider');
  111. var opts = state.options;
  112. var slider = state.slider;
  113. slider.removeClass('slider-h slider-v slider-disabled');
  114. slider.addClass(opts.mode == 'h' ? 'slider-h' : 'slider-v');
  115. slider.addClass(opts.disabled ? 'slider-disabled' : '');
  116. var inner = slider.find('.slider-inner');
  117. inner.html(
  118. '<a href="javascript:;" class="slider-handle"></a>' +
  119. '<span class="slider-tip"></span>'
  120. );
  121. if (opts.range){
  122. inner.append(
  123. '<a href="javascript:;" class="slider-handle"></a>' +
  124. '<span class="slider-tip"></span>'
  125. );
  126. }
  127. slider.find('a.slider-handle').draggable({
  128. axis:opts.mode,
  129. cursor:'pointer',
  130. disabled: opts.disabled,
  131. onDrag:function(e){
  132. var left = e.data.left;
  133. var width = slider.width();
  134. if (opts.mode!='h'){
  135. left = e.data.top;
  136. width = slider.height();
  137. }
  138. if (left < 0 || left > width) {
  139. return false;
  140. } else {
  141. setPos(left, this);
  142. return false;
  143. }
  144. },
  145. onStartDrag:function(){
  146. state.isDragging = true;
  147. opts.onSlideStart.call(target, opts.value);
  148. },
  149. onStopDrag:function(e){
  150. setPos(opts.mode=='h'?e.data.left:e.data.top, this);
  151. opts.onSlideEnd.call(target, opts.value);
  152. opts.onComplete.call(target, opts.value);
  153. state.isDragging = false;
  154. }
  155. });
  156. slider.find('div.slider-inner').unbind('.slider').bind('mousedown.slider', function(e){
  157. if (state.isDragging || opts.disabled){return}
  158. var pos = $(this).offset();
  159. setPos(opts.mode=='h'?(e.pageX-pos.left):(e.pageY-pos.top));
  160. opts.onComplete.call(target, opts.value);
  161. });
  162. function setPos(pos, handle){
  163. var value = pos2value(target, pos);
  164. var s = Math.abs(value % opts.step);
  165. if (s < opts.step/2){
  166. value -= s;
  167. } else {
  168. value = value - s + opts.step;
  169. }
  170. if (opts.range){
  171. var v1 = opts.value[0];
  172. var v2 = opts.value[1];
  173. var m = parseFloat((v1+v2)/2);
  174. if (handle){
  175. var isLeft = $(handle).nextAll('.slider-handle').length > 0;
  176. if (value <= v2 && isLeft){
  177. v1 = value;
  178. } else if (value >= v1 && (!isLeft)){
  179. v2 = value;
  180. }
  181. } else {
  182. if (value < v1){
  183. v1 = value;
  184. } else if (value > v2){
  185. v2 = value;
  186. } else {
  187. value < m ? v1 = value : v2 = value;
  188. }
  189. }
  190. $(target).slider('setValues', [v1,v2]);
  191. } else {
  192. $(target).slider('setValue', value);
  193. }
  194. }
  195. }
  196. /**
  197. * set a specified value to slider
  198. */
  199. function setValues(target, values){
  200. var state = $.data(target, 'slider');
  201. var opts = state.options;
  202. var slider = state.slider;
  203. var oldValues = $.isArray(opts.value) ? opts.value : [opts.value];
  204. var newValues = [];
  205. if (!$.isArray(values)){
  206. values = $.map(String(values).split(opts.separator), function(v){
  207. return parseFloat(v);
  208. });
  209. }
  210. slider.find('.slider-value').remove();
  211. var name = $(target).attr('sliderName') || '';
  212. for(var i=0; i<values.length; i++){
  213. var value = values[i];
  214. if (value < opts.min) value = opts.min;
  215. if (value > opts.max) value = opts.max;
  216. var input = $('<input type="hidden" class="slider-value">').appendTo(slider);
  217. input.attr('name', name);
  218. input.val(value);
  219. newValues.push(value);
  220. var handle = slider.find('.slider-handle:eq('+i+')');
  221. var tip = handle.next();
  222. var pos = value2pos(target, value);
  223. if (opts.showTip){
  224. tip.show();
  225. tip.html(opts.tipFormatter.call(target, value));
  226. } else {
  227. tip.hide();
  228. }
  229. if (opts.mode == 'h'){
  230. var style = 'left:'+pos+'px;';
  231. handle.attr('style', style);
  232. tip.attr('style', style + 'margin-left:' + (-Math.round(tip.outerWidth()/2)) + 'px');
  233. } else {
  234. var style = 'top:' + pos + 'px;';
  235. handle.attr('style', style);
  236. tip.attr('style', style + 'margin-left:' + (-Math.round(tip.outerWidth())) + 'px');
  237. }
  238. }
  239. opts.value = opts.range ? newValues : newValues[0];
  240. $(target).val(opts.range ? newValues.join(opts.separator) : newValues[0]);
  241. if (oldValues.join(',') != newValues.join(',')){
  242. opts.onChange.call(target, opts.value, (opts.range?oldValues:oldValues[0]));
  243. }
  244. }
  245. function initValue(target){
  246. var opts = $.data(target, 'slider').options;
  247. var fn = opts.onChange;
  248. opts.onChange = function(){};
  249. setValues(target, opts.value);
  250. opts.onChange = fn;
  251. }
  252. /**
  253. * translate value to slider position
  254. */
  255. function value2pos(target, value){
  256. var state = $.data(target, 'slider');
  257. var opts = state.options;
  258. var slider = state.slider;
  259. var size = opts.mode == 'h' ? slider.width() : slider.height();
  260. var pos = opts.converter.toPosition.call(target, value, size);
  261. if (opts.mode == 'v'){
  262. pos = slider.height() - pos;
  263. }
  264. if (opts.reversed){
  265. pos = size - pos;
  266. }
  267. return pos.toFixed(0);
  268. }
  269. /**
  270. * translate slider position to value
  271. */
  272. function pos2value(target, pos){
  273. var state = $.data(target, 'slider');
  274. var opts = state.options;
  275. var slider = state.slider;
  276. var size = opts.mode == 'h' ? slider.width() : slider.height();
  277. var pos = opts.mode=='h' ? (opts.reversed?(size-pos):pos) : (opts.reversed?pos:(size-pos));
  278. var value = opts.converter.toValue.call(target, pos, size);
  279. return value.toFixed(0);
  280. }
  281. $.fn.slider = function(options, param){
  282. if (typeof options == 'string'){
  283. return $.fn.slider.methods[options](this, param);
  284. }
  285. options = options || {};
  286. return this.each(function(){
  287. var state = $.data(this, 'slider');
  288. if (state){
  289. $.extend(state.options, options);
  290. } else {
  291. state = $.data(this, 'slider', {
  292. options: $.extend({}, $.fn.slider.defaults, $.fn.slider.parseOptions(this), options),
  293. slider: init(this)
  294. });
  295. $(this).removeAttr('disabled');
  296. }
  297. var opts = state.options;
  298. opts.min = parseFloat(opts.min);
  299. opts.max = parseFloat(opts.max);
  300. if (opts.range){
  301. if (!$.isArray(opts.value)){
  302. opts.value = $.map(String(opts.value).split(opts.separator), function(v){
  303. return parseFloat(v);
  304. });
  305. }
  306. if (opts.value.length < 2){
  307. opts.value.push(opts.max);
  308. }
  309. } else {
  310. opts.value = parseFloat(opts.value);
  311. }
  312. opts.step = parseFloat(opts.step);
  313. opts.originalValue = opts.value;
  314. buildSlider(this);
  315. showRule(this);
  316. setSize(this);
  317. });
  318. };
  319. $.fn.slider.methods = {
  320. options: function(jq){
  321. return $.data(jq[0], 'slider').options;
  322. },
  323. destroy: function(jq){
  324. return jq.each(function(){
  325. $.data(this, 'slider').slider.remove();
  326. $(this).remove();
  327. });
  328. },
  329. resize: function(jq, param){
  330. return jq.each(function(){
  331. setSize(this, param);
  332. });
  333. },
  334. getValue: function(jq){
  335. return jq.slider('options').value;
  336. },
  337. getValues: function(jq){
  338. return jq.slider('options').value;
  339. },
  340. setValue: function(jq, value){
  341. return jq.each(function(){
  342. setValues(this, [value]);
  343. });
  344. },
  345. setValues: function(jq, values){
  346. return jq.each(function(){
  347. setValues(this, values);
  348. });
  349. },
  350. clear: function(jq){
  351. return jq.each(function(){
  352. var opts = $(this).slider('options');
  353. setValues(this, opts.range?[opts.min,opts.max]:[opts.min]);
  354. });
  355. },
  356. reset: function(jq){
  357. return jq.each(function(){
  358. var opts = $(this).slider('options');
  359. $(this).slider(opts.range?'setValues':'setValue', opts.originalValue);
  360. });
  361. },
  362. enable: function(jq){
  363. return jq.each(function(){
  364. $.data(this, 'slider').options.disabled = false;
  365. buildSlider(this);
  366. });
  367. },
  368. disable: function(jq){
  369. return jq.each(function(){
  370. $.data(this, 'slider').options.disabled = true;
  371. buildSlider(this);
  372. });
  373. }
  374. };
  375. $.fn.slider.parseOptions = function(target){
  376. var t = $(target);
  377. return $.extend({}, $.parser.parseOptions(target, [
  378. 'width','height','mode',{reversed:'boolean',showTip:'boolean',range:'boolean',min:'number',max:'number',step:'number'}
  379. ]), {
  380. value: (t.val() || undefined),
  381. disabled: (t.attr('disabled') ? true : undefined),
  382. rule: (t.attr('rule') ? eval(t.attr('rule')) : undefined)
  383. });
  384. };
  385. $.fn.slider.defaults = {
  386. width: 'auto',
  387. height: 'auto',
  388. mode: 'h', // 'h'(horizontal) or 'v'(vertical)
  389. reversed: false,
  390. showTip: false,
  391. disabled: false,
  392. range: false,
  393. value: 0,
  394. separator: ',',
  395. min: 0,
  396. max: 100,
  397. step: 1,
  398. rule: [], // [0,'|',100]
  399. tipFormatter: function(value){return value},
  400. converter:{
  401. toPosition:function(value, size){
  402. var opts = $(this).slider('options');
  403. return (value-opts.min)/(opts.max-opts.min)*size;
  404. },
  405. toValue:function(pos, size){
  406. var opts = $(this).slider('options');
  407. return opts.min + (opts.max-opts.min)*(pos/size);
  408. }
  409. },
  410. onChange: function(value, oldValue){},
  411. onSlideStart: function(value){},
  412. onSlideEnd: function(value){},
  413. onComplete: function(value){}
  414. };
  415. })(jQuery);