JQuery UI Slider - combined max for several sliders that also have individual maximum values

- Solved -
I know that they exist, but I have not found a slider that can easily satisfy some basic needs, and I am sure that I am not the only one who is disappointed with this problem. This is what I still have. Am I heading in the right direction?

What am I trying to do:

Using the jQuery UI slider, I need several sliders per page. Each slider will have a minimum of 0, dynamic max and dynamic default value. I set these values ​​in an input field with html elements min, max, value and retrieve them later through javascript / jquery.

In addition to their individual maximum values, there should also be a total maximum value, which the sum of all sliders cannot exceed. Finally, I also need accessibility to update the slider from the input window (as well as the slider itself).

What I have so far:

After exploring a number of sliders, I settled on using the JQuery UI slider and eventually came across this post, which made me start by achieving my goals: Combined summary for several jQuery-UI Sliders

I changed the code to (1) Use a hidden input field to get the total maximum value; (2) fills the input text field instead of the range with the current value; (3) set the initial maximum value of an individual slider from the attribute max =; (4) set the slider to disabled: true if the initial max is 0; and (5) listen to the changes in the text box and move the slider according to the entered number, if it does not exceed the maximum value.

Current code (JSFiddle): (see jsfiddle in the answer)

(Slider # 1 Starting max is 0 - disabled // Other sliders have a maximum of 500 // general table max 1000)

What the slider works:

  • It is highly customizable and is under full maximum limit.
  • Correctly sets the initial individual max and total maximum
  • Sets and remains disabled if max is 0
  • The slides are correct when you change the text box

I need help / fix ideas:

  • Changing the sliders tends to change the individual slider max = total maximum
  • Changing the text field correctly displays the current strip, but does not update other sliders so that they do not go to the total maximum
  • I am currently using the .focusout () event in text fields because .change () makes it go crazy b / c, the slider also changes the text box.

Let me know what you think.

UPDATE:

I was sad not to hear any answers, but I think I hacked it. You need to limit the reliability of this source code and basically rewrite it. I will post my solution as an answer below. Please try and let me know what you think. It was quite a process, so hopefully someone finds this useful :)

+4
source share
2 answers

JSFiddle: http://jsfiddle.net/mikecruz/bAntY/

Javascript / jQuery:

var sliders = $("#sliders .slider"); sliders.each(function() { var max = document.getElementById("sliderMax").value; var value = Number($(this).text(), 10), availableTotal = max; $(this).empty().slider({ value: 0, min: 0, max: $(this).siblings().attr("max"), range: "max", step: 1, animate: 100, disabled: (function(curMax) { if (curMax < 1) { return 1; } return 0; })($(this).siblings().attr("max")), stop: function(event, ui) { // Update text box to current value and call .change() $(this).siblings().attr("value", ui.value); $(this).siblings().trigger('change'); } }); }); $(".value").change(function() { var thisAmount = Number($(this).prop("value")); var totalMax = Number(document.getElementById("sliderMax").value); var indMin = Number($(this).attr("min")); var indMax = Number($(this).attr("max")); var total = 0; //Get the values of all other text boxes $('.value').not(this).each(function() { total += Number($(this).prop("value")); }); //Find the remaining from our total sliders max var remaining = totalMax - total; if(remaining < 0) { remaining = 0; } //if we are under our minimums, go for it! Otherwise, reduce the number. if (thisAmount >= indMin && thisAmount < indMax && thisAmount < totalMax && thisAmount < remaining) { $(this).siblings(".slider").slider("option", "value", thisAmount); //total += thisAmount; } else { //var setMax = ((indMax + totalMax) - Math.abs(indMax - totalMax)) / 2; var setMax = Math.min(indMax, totalMax, remaining); $(this).siblings(".slider").slider("option", "value", setMax); $(this).prop("value", setMax); //total += (thisAmount - setMax); } //above was getting buggy, so lets just reset total and get it again total = 0; //Get the values of all text boxes $('.value').each(function() { total += Number($(this).prop("value")); }); //Find our new remaining number after updating total for this value remaining = totalMax - total; if(remaining < 0) { remaining = 0; } //Set each slider to the current point and update their max values. $('.value').each(function() { var sliderVal = Number($(this).prop("value")); var sliderMin = Number($(this).attr("min")); var sliderMax = Number($(this).attr("max")); var setNewMax = (((sliderMax + totalMax) - Math.abs(sliderMax - totalMax)) / 2); var newMax = sliderVal + remaining; $(this).prop("max", newMax); if(newMax < setNewMax) { $(this).siblings('.slider').slider("option", "max", newMax); $(this).siblings('span').text('/' + (newMax)); } else { $(this).siblings('.slider').slider("option", "max", setNewMax); $(this).siblings('span').text('/' + (setNewMax)); } $(this).siblings(".slider").slider("option", "value", sliderVal); }); $('#sliderTotal').attr("value", total); }); 

HTML:
For each slider you need li You can use CSS for additional style of different parts. For instance. give slide bg background image.
You might want to hide the summary fields and, of course, you can script the maximum value.

 <form> <ul id="sliders"> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider1" value="0" min="0" max="0"/> <span>0</span></span> </li> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider2" value="0" min="0" max="500" /> <span>0</span></span> </li> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider3" value="0" min="0" max="500" /> <span>0</span></span> </li> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider4" value="0" min="0" max="500"/> <span>0</span></span> </li> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider5" value="0" min="0" max="500"/> <span>0</span></span> </li> <li> <span class="slideBG"><div class="slider"></div> <input type="text" class="value" name="slider6" value="0" min="0" max="500"/> <span>0</span></span> </li> </ul> <br><label for="sliderMax">Total Max:</label> <input type="text" id="sliderMax" name="sliderMax" value="1000"/> <br><br><label for="sliderTotal">Slider Totals:</label> <input type="text" id="sliderTotal" name="sliderTotal" value="0" /> </form> 

EDIT:

You might want to add this to prevent people from using the text box if the slider is disabled:

 $(".slider").each(function() { var disabled = Number($(this).slider("option", "disabled")); if(disabled == 1) { $(this).siblings('.value').attr('disabled', 'disabled'); } }); 
+5
source

Hi, I just tried something similar, but implemented it differently. I have several sliders with one max. All the sliders values ​​together cannot be more than the total. Ex. 3 sliders with a total of 100%. Sliders can be 10%, 50%, 40%.

This does not answer all that you want, but may be useful for other users who are looking for something like that.

 var sliders = $('.slider'); sliders.each(function(i) { var slider = $(sliders[i]); var input = $('#' + slider.attr('datanamespace')); slider.slider({ value: slider.attr('datatotal'), min: 0, max: max, step: 1, slide: function( event, ui ) { if (ui.value < slider.attr('datavalue')) { return false; } var inputs = $('.slideInput'); var total = ui.value; for (var i = 0; i < inputs.length; i++) { var inp = $(inputs[i]); if (inp.attr('id') != input.attr('id')) { total = total + parseInt(inp.val()); } } if (total > max) { return false; } input.val(ui.value); } }); input.val(slider.slider("value")); }); 
+2
source

Source: https://habr.com/ru/post/1397416/


All Articles