jquery.slider.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /**
  2. * EasyUI for jQuery 1.5.5.6
  3. *
  4. * Copyright (c) 2009-2018 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 - EasyUI for jQuery
  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 fixVal(value){
  163. var dd = String(opts.step).split('.');
  164. var dlen = dd.length>1 ? dd[1].length : 0;
  165. return parseFloat(value.toFixed(dlen));
  166. }
  167. function setPos(pos, handle){
  168. var value = pos2value(target, pos);
  169. var s = Math.abs(value % opts.step);
  170. if (s < opts.step/2){
  171. value -= s;
  172. } else {
  173. value = value - s + opts.step;
  174. }
  175. value = fixVal(value);
  176. if (opts.range){
  177. var v1 = opts.value[0];
  178. var v2 = opts.value[1];
  179. var m = parseFloat((v1+v2)/2);
  180. if (handle){
  181. var isLeft = $(handle).nextAll('.slider-handle').length > 0;
  182. if (value <= v2 && isLeft){
  183. v1 = value;
  184. } else if (value >= v1 && (!isLeft)){
  185. v2 = value;
  186. }
  187. } else {
  188. if (value < v1){
  189. v1 = value;
  190. } else if (value > v2){
  191. v2 = value;
  192. } else {
  193. value < m ? v1 = value : v2 = value;
  194. }
  195. }
  196. $(target).slider('setValues', [v1,v2]);
  197. } else {
  198. $(target).slider('setValue', value);
  199. }
  200. }
  201. }
  202. /**
  203. * set a specified value to slider
  204. */
  205. function setValues(target, values){
  206. var state = $.data(target, 'slider');
  207. var opts = state.options;
  208. var slider = state.slider;
  209. var oldValues = $.isArray(opts.value) ? opts.value : [opts.value];
  210. var newValues = [];
  211. if (!$.isArray(values)){
  212. values = $.map(String(values).split(opts.separator), function(v){
  213. return parseFloat(v);
  214. });
  215. }
  216. slider.find('.slider-value').remove();
  217. var name = $(target).attr('sliderName') || '';
  218. for(var i=0; i<values.length; i++){
  219. var value = values[i];
  220. if (value < opts.min) value = opts.min;
  221. if (value > opts.max) value = opts.max;
  222. var input = $('<input type="hidden" class="slider-value">').appendTo(slider);
  223. input.attr('name', name);
  224. input.val(value);
  225. newValues.push(value);
  226. var handle = slider.find('.slider-handle:eq('+i+')');
  227. var tip = handle.next();
  228. var pos = value2pos(target, value);
  229. if (opts.showTip){
  230. tip.show();
  231. tip.html(opts.tipFormatter.call(target, value));
  232. } else {
  233. tip.hide();
  234. }
  235. if (opts.mode == 'h'){
  236. var style = 'left:'+pos+'px;';
  237. handle.attr('style', style);
  238. tip.attr('style', style + 'margin-left:' + (-Math.round(tip.outerWidth()/2)) + 'px');
  239. } else {
  240. var style = 'top:' + pos + 'px;';
  241. handle.attr('style', style);
  242. tip.attr('style', style + 'margin-left:' + (-Math.round(tip.outerWidth())) + 'px');
  243. }
  244. }
  245. opts.value = opts.range ? newValues : newValues[0];
  246. $(target).val(opts.range ? newValues.join(opts.separator) : newValues[0]);
  247. if (oldValues.join(',') != newValues.join(',')){
  248. opts.onChange.call(target, opts.value, (opts.range?oldValues:oldValues[0]));
  249. }
  250. }
  251. function initValue(target){
  252. var opts = $.data(target, 'slider').options;
  253. var fn = opts.onChange;
  254. opts.onChange = function(){};
  255. setValues(target, opts.value);
  256. opts.onChange = fn;
  257. }
  258. /**
  259. * translate value to slider position
  260. */
  261. function value2pos(target, value){
  262. var state = $.data(target, 'slider');
  263. var opts = state.options;
  264. var slider = state.slider;
  265. var size = opts.mode == 'h' ? slider.width() : slider.height();
  266. var pos = opts.converter.toPosition.call(target, value, size);
  267. if (opts.mode == 'v'){
  268. pos = slider.height() - pos;
  269. }
  270. if (opts.reversed){
  271. pos = size - pos;
  272. }
  273. return pos;
  274. // return pos.toFixed(0);
  275. }
  276. /**
  277. * translate slider position to value
  278. */
  279. function pos2value(target, pos){
  280. var state = $.data(target, 'slider');
  281. var opts = state.options;
  282. var slider = state.slider;
  283. var size = opts.mode == 'h' ? slider.width() : slider.height();
  284. var pos = opts.mode=='h' ? (opts.reversed?(size-pos):pos) : (opts.reversed?pos:(size-pos));
  285. var value = opts.converter.toValue.call(target, pos, size);
  286. return value;
  287. // return value.toFixed(0);
  288. }
  289. $.fn.slider = function(options, param){
  290. if (typeof options == 'string'){
  291. return $.fn.slider.methods[options](this, param);
  292. }
  293. options = options || {};
  294. return this.each(function(){
  295. var state = $.data(this, 'slider');
  296. if (state){
  297. $.extend(state.options, options);
  298. } else {
  299. state = $.data(this, 'slider', {
  300. options: $.extend({}, $.fn.slider.defaults, $.fn.slider.parseOptions(this), options),
  301. slider: init(this)
  302. });
  303. // $(this).removeAttr('disabled');
  304. $(this)._propAttr('disabled', false);
  305. }
  306. var opts = state.options;
  307. opts.min = parseFloat(opts.min);
  308. opts.max = parseFloat(opts.max);
  309. if (opts.range){
  310. if (!$.isArray(opts.value)){
  311. opts.value = $.map(String(opts.value).split(opts.separator), function(v){
  312. return parseFloat(v);
  313. });
  314. }
  315. if (opts.value.length < 2){
  316. opts.value.push(opts.max);
  317. }
  318. } else {
  319. opts.value = parseFloat(opts.value);
  320. }
  321. opts.step = parseFloat(opts.step);
  322. opts.originalValue = opts.value;
  323. buildSlider(this);
  324. showRule(this);
  325. setSize(this);
  326. });
  327. };
  328. $.fn.slider.methods = {
  329. options: function(jq){
  330. return $.data(jq[0], 'slider').options;
  331. },
  332. destroy: function(jq){
  333. return jq.each(function(){
  334. $.data(this, 'slider').slider.remove();
  335. $(this).remove();
  336. });
  337. },
  338. resize: function(jq, param){
  339. return jq.each(function(){
  340. setSize(this, param);
  341. });
  342. },
  343. getValue: function(jq){
  344. return jq.slider('options').value;
  345. },
  346. getValues: function(jq){
  347. return jq.slider('options').value;
  348. },
  349. setValue: function(jq, value){
  350. return jq.each(function(){
  351. setValues(this, [value]);
  352. });
  353. },
  354. setValues: function(jq, values){
  355. return jq.each(function(){
  356. setValues(this, values);
  357. });
  358. },
  359. clear: function(jq){
  360. return jq.each(function(){
  361. var opts = $(this).slider('options');
  362. setValues(this, opts.range?[opts.min,opts.max]:[opts.min]);
  363. });
  364. },
  365. reset: function(jq){
  366. return jq.each(function(){
  367. var opts = $(this).slider('options');
  368. $(this).slider(opts.range?'setValues':'setValue', opts.originalValue);
  369. });
  370. },
  371. enable: function(jq){
  372. return jq.each(function(){
  373. $.data(this, 'slider').options.disabled = false;
  374. buildSlider(this);
  375. });
  376. },
  377. disable: function(jq){
  378. return jq.each(function(){
  379. $.data(this, 'slider').options.disabled = true;
  380. buildSlider(this);
  381. });
  382. }
  383. };
  384. $.fn.slider.parseOptions = function(target){
  385. var t = $(target);
  386. return $.extend({}, $.parser.parseOptions(target, [
  387. 'width','height','mode',{reversed:'boolean',showTip:'boolean',range:'boolean',min:'number',max:'number',step:'number'}
  388. ]), {
  389. value: (t.val() || undefined),
  390. disabled: (t.attr('disabled') ? true : undefined),
  391. rule: (t.attr('rule') ? eval(t.attr('rule')) : undefined)
  392. });
  393. };
  394. $.fn.slider.defaults = {
  395. width: 'auto',
  396. height: 'auto',
  397. mode: 'h', // 'h'(horizontal) or 'v'(vertical)
  398. reversed: false,
  399. showTip: false,
  400. disabled: false,
  401. range: false,
  402. value: 0,
  403. separator: ',',
  404. min: 0,
  405. max: 100,
  406. step: 1,
  407. rule: [], // [0,'|',100]
  408. tipFormatter: function(value){return value},
  409. converter:{
  410. toPosition:function(value, size){
  411. var opts = $(this).slider('options');
  412. var p = (value-opts.min)/(opts.max-opts.min)*size;
  413. return p;
  414. },
  415. toValue:function(pos, size){
  416. var opts = $(this).slider('options');
  417. var v = opts.min + (opts.max-opts.min)*(pos/size);
  418. return v;
  419. }
  420. },
  421. onChange: function(value, oldValue){},
  422. onSlideStart: function(value){},
  423. onSlideEnd: function(value){},
  424. onComplete: function(value){}
  425. };
  426. })(jQuery);