I have a input type="range"in jquery mobile code. Based on some condition, I want to restrict the slider handle to go further after a certain limit ( but it can go backward )
For example, this is what I want to achieve in jQuery Mobile - http://jsfiddle.net/EL4tf/ ( Total is not exceeding 150 for all the three sliders )
The problem I am facing is that jQuery Mobile converts input type="range" into input type="number" therefore I am not able to put the condition event.preventDefault(); return false on $('.mySlider').bind('change') like they have put in the above fiddle example.
Any help will be appreciated!
From my comment, i prepared a simple solution which calculates the sliders total value and stops them increasing if greater than the total 150.
** Update from #ezanker. using the same process on change event. stops the slider in its tracks
Demo
http://jsfiddle.net/8jddyftc/
Jquery
var tota, totb, totc, alltot, altval, getslider;
var chktot = 150;
var scrore = 151;
//On Change event
$(document).on("change", "#range1, #range2, #range3", function (e) {
// Get the sliders Id
getslider = $(this).attr("id");
//Gather all slider values
tota = parseInt($("input#range1").val());
totb = parseInt($("input#range2").val());
totc = parseInt($("input#range3").val());
alltot = tota + totb + totc;
//check sliders total if greater than 150 and re-update slider
if (alltot > chktot) {
if (getslider == "range1") {
altval = chktot - totb - totc;
$("input#range1").val(altval).slider("refresh");;
}
if (getslider == "range2") {
altval = chktot - tota - totc;
$("input#range2").val(altval).slider("refresh");;
}
if (getslider == "range3") {
altval = chktot - tota - totb;
$("input#range3").val(altval).slider("refresh");;
}
}
//Update Total
if (alltot < scrore) {
$("#total").text(alltot);
}
})
If you want to limit the slider already during dragging, you can modify the CSS of the <a> component that is used to render the slider.
Demo: http://jsfiddle.net/ukaxkej0/2/
Try yourself: the slider will not move further if the sum is already at its limit.
To change the CSS:
var MAX = 150; // maximum allowed sum
var DEFAULT = 50; // slider default
var SMAX = 100; // slider max
var old1=DEFAULT, old2=DEFAULT, old1=DEFAULT;
// sliders trigger number changes; prevent them if sum exceeds maximum
$("input[type='number']").change(function(e){
var val1 = $("#range1").val();
var val2 = $("#range2").val();
var val3 = $("#range3").val();
var sum = parseInt(val1) + parseInt(val2) + parseInt(val3);
if (sum <= MAX) {
$("#total").text(sum);
old1=val1;
old2=val2;
old3=val3;
}
else {
if (val1 != old1) {
$("#range1").val(old1);
$("a[aria-labelledby='range1-label']").css('left', (100*old1/SMAX)+'%');
}
if (val2 != old2) {
$("#range2").val(old2);
$("a[aria-labelledby='range2-label']").css('left', (100*old2/SMAX)+'%');
}
if (val3 != old3) {
$("#range3").val(old3);
$("a[aria-labelledby='range3-label']").css('left', (100*old3/SMAX)+'%');
}
}
});
In addition, you have to prevent slider interaction if the sum exceeds the maximum.
$('.ui-slider-handle').mousemove(function(e){
var val1 = $("#range1").val();
var val2 = $("#range2").val();
var val3 = $("#range3").val();
var sum = parseInt(val1) + parseInt(val2) + parseInt(val3);
if (sum > MAX) {
e.preventDefault();
return false;
}
return true;
});
HTML (as suggested by Tasos):
<div data-role="page">
<input id="range1" type="range" min="0" max="100" value="50" />
<input id="range2" type="range" min="0" max="100" value="50" />
<input id="range3" type="range" min="0" max="100" value="50" />
<div>total: <strong id="total">0</strong>/150</div>
</div>
Related
How to allow user to increase number in input type="number" by 10 via clicking the up down arrow, at the same time also allowing the user to enter random numbers (e.g. 33) instead of just accepting numbers like 30, 40 only?
Note: this input type="number" cannot accept negative numbers, max value is 100.
You can use min, max attribute along with step
<input type="number" step="10" min="0" max="100"/>
Updated with #Navnath Jadhav's suggestion.
You'll need a custom implementation for this.
The below adds an increment and deincrement button next to the input field and hides the default number arrows.
let deincrement = document.getElementById("deincrement");
let increment = document.getElementById("increment");
let number = document.getElementById("number");
let step = 10;
let max = 100;
let min = 0;
number.oninput = () => {
number.value = number.value>max ? max : number.value<min ? min : number.value;
};
increment.addEventListener("click", () => {
if (parseInt(number.value) + step >= max) {
number.value = max;
return;
}
number.value = parseInt(number.value) + step;
})
deincrement.addEventListener("click", () => {
if (parseInt(number.value) - step <= min) {
number.value = min;
return;
}
number.value = parseInt(number.value) - step;
})
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
<button type="button" id="deincrement">-</button>
<input type="number" value="33" id="number" min="0" max="100"/>
<button type="button" id="increment">+</button>
Trying to have script run on page load with value of input on page load. The script runs onchange fine but I also want to run on page load. I have tried onload="calculateAmount(this.value);">
<input type="number" name="tot_pin_requested" id="tot_pin_requested" class="inputbox autowidth" value="{{ PPDEFAULT_VALUE }}" onchange="calculateAmount(this.value);">
<script>
function calculateAmount(val) {
var price = val * 1;
//display the result
var tot_price = price + (price * 0.029 + .30);
tot_price.toFixed(2);
var divobj = document.getElementById('amount');
divobj.value = tot_price;
}
</script>
Don't add it to the element, just have it separate:
<script>calculateAmount(document.querySelector("#tot_pin_requested").value);</script>
If you want to be sure the document is ready just use DOMContentLoaded event.
Also i suggest you use parseFloat on the inputValue so it's correctly changed from type string to type number. ( or parseInt(value, radix) if you will have just int values )
Also i don't know what is the logic behind var price = val * 1....
See below
window.addEventListener('DOMContentLoaded', (event) => {
const inputValue = document.getElementById('tot_pin_requested').value
calculateAmount(parseFloat(inputValue))
})
function calculateAmount(val) {
var price = val * 1;
//display the result
var tot_price = price + (price * 0.029 + .30);
tot_price.toFixed(2);
var divobj = document.getElementById('amount');
divobj.value = tot_price;
}
<input type="number" name="tot_pin_requested" id="tot_pin_requested" class="inputbox autowidth" value="10" onchange="calculateAmount(this.value);">
<input type="number" id="amount">
I should work with two input values that store only Integers when I increase the value of one, the other should decrease. This must stop if the second value hit 0.
The field that contains the value to be decreased is named with ID form_val62_1, and field that can be increased by the user input is called form_val63_1. I'm calling this function onChange() cause I need to pass the ID of the form (that's cause form fields are dynamically generated depending on a PHP array length).
function check(i) {
$("#form_val63_" + i ).change(function () {
var direction = this.defaultValue < this.value;
this.defaultValue = this.value;
var val;
val = parseInt($("#form_val62_" + i).val());
if (direction) {
if (val > 0) {
$('#form_val62_' + i).val(parseInt($(this).val()) - 1);
} else {
var thvar = $(this).val();
$(this).val(thvar - 1);
}
console.log("increase 503");
console.log(val);
} else {
$('#form_val62_' + i).val(parseInt($(this).val()) + 1);
console.log("decrease 503");
console.log(val);
}
});
}
Fiddle
I got many problems here, the first decrease one time, that increase with no reason (I know there is but can't see why).
Using the solution provided by #Ph0b0x i've updated my code as
var v = $("#form_val62_" + i).val(); //Let's say this is the value from PHP....
var preVal = 0;
$("#form_val62_" + i).val(v);
$("#form_val63_" + i).on("change keyup keydown", function(event) {
let currVal = parseInt($("#form_val63_" + i).val());
console.log(preVal);
console.log(currVal);
if (currVal == 0) {
preVal = 0;
$("#form_val62_" + i).val(v);
} else if (currVal <= v) {
$("#form_val62_" + i).val((v - currVal) == 0 ? 0 : (v - currVal));
preVal = currVal;
} else {
$("#form_val63_" + i).val(v);
}
});
Now I can increase the result but when i try decrease the each value remain 0.
I guess, if i understood correctly, i will keep track of the previous value on the second input then i will start decreasing the first one until it reaches 0 and increase it until it reaches 10? Fiddle
HTML
<form>
<input id="form_val62_1" type="number" min="0" value="10" />
<input id="form_val63_1" type="number" min="0" value="0" />
</form>
JS
var v = 13; //Let's say this is the value from PHP....
var preVal = 0;
$("#form_val62_1").val(v);
$("#form_val63_1").on("change keyup keydown", function(event) {
let currVal = parseInt($("#form_val63_1").val());
console.log(preVal);
console.log(currVal);
if (currVal == 0) {
preVal = 0;
$("#form_val62_1").val(v);
} else if (currVal <= v) {
$("#form_val62_1").val((v - currVal) == 0 ? 0 : (v - currVal));
preVal = currVal;
} else {
$("#form_val63_1").val(v);
}
});
Edit: I have updated my code based on your comment. Please see this Fiddle
So bind change event handlers on both elements. I would just use data attributes so you do not have to worry about selecting by ids to bind between both.
$('[data-num-grp]').on('input', function () {
// input that was interacted with
const inp1 = $(this);
// get the group number
const grp = inp1.data('num-grp')
// select the other element with the grp
const inp2 = $('[data-num-grp="' + grp + '"]').not(inp1);
// alter the other element so it's value changes
inp2.val(this.max - this.value)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-num-grp="1" min="0" max="10" value="10"/>
<input type="number" data-num-grp="1" min="0" max="10" value="0"/>
<br/>
<input type="number" data-num-grp="2" min="0" max="10" value="10"/>
<input type="number" data-num-grp="2" min="0" max="10" value="0"/>
I would like to balance two input number fields using jquery based on the max value set for both. for example its like a balance, if one side goes down the other goes up and vice versa. another example if the max value is 20 then if i enter 5 in input field one then 15 would be left in input field two.
Need the help Thanks. Haven't started coding it as yet stuck trying to figure it out.
First you need to attach the input eventhandler on all of the relevant input fields. This event handler will compare the current input value of a input fields to the total/max value variable and find the remainder accordingly. The event handler then finds the other input fields and assigns them with the appropriate remainder values.
Note: This allows you to add as many inputs as you want and it will
balance them all out. Just remember to add the balance class on the
input field.
var total = 20;
$('.balance').on('input', function() {
var value = parseInt(this.value);
if (isNaN(value)) {
this.value = value = 0;
} else if (value > total) {
this.value = value = total;
}/* else if (value < 0) {
this.value = value = 0;
}
* Remove this comment if value shouldn't be negative.
*/
var remainder = total - value;
var otherInputs = $('.balance');
otherInputs.splice($.inArray(this,otherInputs),1);
var remainderDiv = remainder/otherInputs.length;
$.each(otherInputs, function(input) {
otherInputs[input].value = remainderDiv;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="balance">
<input type="number" class="balance">
Update: The two inputs can be less than the max but never higher.
var max = 20;
$('.balance').on('input', function() {
var value = parseInt(this.value);
if (isNaN(value)) {
value = 0;
}
var otherInputs = $('.balance');
var sum = 0;
$.each(otherInputs, function(input) {
sum += parseInt(otherInputs[input].value);
});
if (sum > max)
this.value = max - (sum - value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" class="balance">
<input type="number" class="balance">
here's a fiddle to get you started (and maybe finished):
https://jsfiddle.net/ahmadabdul3/xwyrrw53/1/
html:
<input type='number' id='first' class='balancable'/>
<input type='number' id='second' class='balancable'/>
js:
$(function() {
var max = 20;
var balanceOpposite = {
'first': 'second',
'second': 'first',
}
$('.balancable').on('input', function() {
var id = $(this).attr('id');
var thisVal = $(this).val();
$('#' + balanceOpposite[id]).val(20 - thisVal);
});
});
Below is my textbox:
<input type="number" id="payement-textbox'+index+'" name="payment-textbox" min="0" max="100000" step="any" maxlength="9" class="payment" placeholder="--" value=""/>;
There are two validation on my number type textbox. First is user cannot enter value bigger than 99999.99 which I applied successfully.
The other one is that user cannot enter more than two digits after decimal which is not working.
Here is my jQuery code:
$('input.payment').on("change paste keyup", function(event) {
var max = parseFloat($(this).attr('max'));
var num = parseFloat($(this).val());
if ( num >= max)
{
$(this).val("99999.99");
}
if( ($(this).val().indexOf('.') != -1) && ($(this).val().substring($(this).val().indexOf('.')).length > 2))
{
event.preventDefault();
}
});
Could you please tell me where I am going wrong?
Try:
$("#yourinput").keyup(function(){
var num = parseFloat($(this).val());
if ( num >= 99999.99)
{
$(this).val("99999.99");
}
var number = ($(this).val().split('.'));
if (number[1] && number[1].length > 2)
{
var salary = parseFloat($("#yourinput").val());
$("#yourinput").val( salary.toFixed(2));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<input id="yourinput" pattern="\d+">
<span id=bad style="display:none;color:red">BAD</span>
You need to use the keypress event so it will trigger before the input is entered.
This will work:
$('input.payment').on("keypress paste keyup", function(event){
//Your code
})