JQuery Slider, combined values ​​- difficulties with small increments

I developed jQuery Slider Control, which takes a "pool" of points and allows you to distribute them between several sliders. It works very well, except that I am having some problems with very small overflow increments.

In principle, you can make adjustments in large quantities based on the movement of the mouse, and therefore it allows someone to "spend" more on the slider than anticipated. I don’t understand how to deal with this. Below is all my code.

To test it, create a simple HTML page with this code and try copying the first two sliders up to 500, then try a moving third. It will not slip (intended behavior).

Then slide the first or second slider back a little (subtracting) and slide the third forward. You can sometimes go over planned β€œpaid” borders.

For example, you need jQuery UI, the latest version from Google CDN.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script> 

Javascript

 <style type="text/css"> #eq > div { width:300px; } #eq > div .slider { width: 200px; float: left; } #eq > div > span { float: right; } </style> <script type="text/javascript"> $(document).ready(function () { var spendable = 1000; var spent = 0; function spend(quantity) { spent += quantity; $('#attemptedToSpend').text(spent); } function change(previous, current) { var adjustment = (current - previous); $('#change').text(adjustment); return adjustment; } function calculateSpent() { var totalled = 0; $("#eq .slider").each(function () { totalled += parseInt($(this).parent('div:eq(0)').find('.spent').text()); }); $('#spent').text(totalled); } $("#eq .slider").each(function () { var current = 0; var previous = 0; var adjustment = 0; $(this).slider({ range: "min", value: 0, min: 0, max: 500, step: 1, animate: true, orientation: "horizontal", start: function (event, ui) { }, stop: function (event, ui) { }, slide: function (event, ui) { // set the current value to whatever is selected. current = ui.value; // determine the adjustment being made relative to the last // adjustment, instead of just the slider value. adjustment = change(previous, current); if (spent >= spendable) { if (adjustment > 0) return false; } // spend the points, if we are able to. spend(adjustment); // set the previous value previous = current; $(this).parent('div:eq(0)').find('.spent').text(current); calculateSpent(); } }); }); }); </script> 

Html

 <p class="ui-state-default ui-corner-all" style="padding: 4px; margin-top: 4em;"> <span style="float: left; margin: -2px 5px 0 0;"></span>Distribution </p> <strong>Total Points Spendable: </strong><div id="spendable">1000</div> <strong>Total Points Spent (Attempted): </strong><div id="attemptedToSpend">0</div> <strong>Total Points Spent: </strong><div id="spent">0</div> <strong>Change: </strong><div id="change">0</div> <div id="status"></div> <div id="eq"> <div style="margin: 15px;" id="test1">Test1</div> <br /> <div class="slider"></div><span class="spent">0</span> <div style="margin: 15px;" id="test2">Test2</div> <br /> <div class="slider"></div><span class="spent">0</span> <div style="margin: 15px;" id="test3">Test3</div> <br /> <div class="slider"></div><span class="spent">0</span> <div style="margin: 15px;" id="test4">Test4</div> <br /> <div class="slider"></div><span class="spent">0</span> <div style="margin: 15px;" id="test5">Test5</div> <br /> <div class="slider"></div><span class="spent">0</span> </div> 
+4
source share
1 answer

I tried to keep your script intact, but ended up rewriting it. Now it should be solid. Good news: I just changed JS, everything else is intact, although I no longer update all your monitoring fields.

Demo

 $( function() { var maxValueSlider = 500, maxValueTotal = 1000, $sliders = $("#eq .slider"), valueSliders = [], $displaySpentTotal = $('#spent'); function arraySum(arr) { var sum = 0, i; for(i in arr) sum += arr[i]; return sum; } $sliders .each( function(i, slider) { var $slider = $(slider), $spent = $slider.next('.spent'); valueSliders[i] = 0; $slider .slider( { range: 'min', value: 0, min: 0, max: maxValueSlider, step: 1, animate: true, orientation: "horizontal", slide: function(event, ui) { var sumRemainder = arraySum(valueSliders) - valueSliders[i], adjustedValue = Math.min(maxValueTotal - sumRemainder, ui.value); valueSliders[i] = adjustedValue; // display the current total $displaySpentTotal.text(sumRemainder + adjustedValue); // display the current value $spent.text(adjustedValue); // set slider to adjusted value $slider.slider('value', adjustedValue); // stop sliding (return false) if value actually required adjustment return adjustedValue == ui.value; } } ); } ); } ); 
+1
source

All Articles