jquery toggle depending on value of textbox - javascript

This must be very simple, but I just got stuck with this... I have a list of products with an input field for the quantity and next to it a column with the prices. The prices are displaying two values. One of them is hidden. If the value of the input field goes over a certain value, it should hide the other price.
Example:
(input: [], show price1price2 )
input: [2], show <span class=one>price1</span>
input: [5], show <span class=one>price1</span>
input: [8], show <span class=two>price2</span>
input: [9], show <span class=two>price2</span>
My code so far (example, since I show just 2 products):
<form name="formname" action="formaction" method="post">
prod 1<input type="text" value="" class="class1" size="3"><span class="one">$1.00</span><span class="two">$2.00</span>
prod 2<input type="text" value="" class="class1" size="3"><span class="one">$4.00</span><span class="two">$6.00</span>
</form>
And at the bottom in script tags:
$(document).ready(function() {
if($('input.class1').val() > 5) {
$('.one').show();
$('.two').hide();
}
});
What am I missing? The form name perhaps?
This is just the first part...
My other question would be.. how can I make it so that if the sum of all the input fields (with class1 as class) is more than 5, do the same. (So now depending on the sum of the input fields, rather than each individual one)

var inputs = $('input[class^=class]'); // get inputs which class name
// start with "class" eg: class1, class2..
// fire blur event
// you may use keyup or something else
inputs.on('blur', function(e) {
var val = 0;
// adding all inputs value
// of all inputs with class = blured input class
$('input.' + this.className).each(function() {
val += parseInt( this.value, 10);
});
// checking for condition
if (val > 5) {
$(this).next('.one').show().next('.two').hide();
} else {
$(this).next('.one').hide().next('.two').show();
}
});
Demo with blur
Demo with keyup
Note
Place you all jQuery codes within $(document).ready().
According to comment
See this update
Code
if (val > 5) {
$('.one').show();
$('.two').hide();
} else {
$('.one').hide();
$('.two').show();
}
Update after last comment
Just change
val += parseInt( this.value, 10);
to
val += parseInt( this.value || 0, 10); // default 0, if no value given
According to comment
How to implement above code for select box?
var selects = $('select[class^=class]'); // get selects which class name
// start with "class" eg: class1, class2..
// fire change event
selects.on('change', function(e) {
var val = 0;
// adding all selects value
$('select.' + this.className).each(function() {
val += parseInt( this.value, 10);
});
// checking for condition
if (val > 5) {
$(this).next('.one').show().next('.two').hide();
} else {
$(this).next('.one').hide().next('.two').show();
}
});

You are calling this on page load, you need to run it each time the value of the input fields is changed.
Consider wrapping your if block in this:
$('input.class1').blur(function() {
if($('input.class1').val() > 5) {
$('.one').show();
$('.two').hide();
}
});
Or something to that effect, consider using $.on().
If you want to sum them, assign each input a common class, and use $.each():
$('.common-class').each(function() {
sum = sum + $(this).val()
});
Hope this helps.

Related

How do I prevent this function from modifying the variable more than once?

I wrote this function to modify the text of my HTML tag when a checkbox is marked.
var price = 15
function checkPrice() {
let extraCheese = document.getElementById("extraCheese");
if (extraCheese.checked = true) {
price += 5;
// console.log(price)
document.getElementById('pizzaPrice').innerHTML = `Current Price: $${price}.00`
}
}
<input type="checkbox" value="extraCheese" onclick="checkPrice(this);" id="extraCheese" />
<label for="extraCheese"> Extra Cheese </label>
<h3 id="pizzaPrice"> Base Price: $15.00 </h3>
It works as intended and adds 5 to the current price, but the checkbox stays checked and each time it is clicked the value adds by five again. What should I do to let the user uncheck the box and reduce the value to what it originally was?
Use else to reduce the price.
There's also no need to call getElementById(), since you pass the element to the function with checkPrice(this)
checked is a boolean property, you don't need to compare it (and you had a typo using = instead of == to compare).
function checkPrice(extraCheese) {
if (extraCheese.checked) {
price += 5;
} else {
price -= 5;
}
// console.log(price)
document.getElementById('pizzaPrice').innerHTML = `Current Price: $${price}.00`
}
you can assign an extra property to your element to check if it's already been increased or not
function checkPrice(extraCheese) {
var price = 15;
function checkPrice() {
let extraCheese = document.getElementById("extraCheese");
if (
(extraCheese.checked && (typeof extraCheese.inc == "undefined" || extraCheese.inc == false))
) {
price += 5;
extraCheese.inc = true;
// console.log(price)
document.getElementById("pizzaPrice").innerHTML = `Current Price: $${price}.00`;
}
}
}
You should be watching for the change event of the checkbox, rather than the click event. Then, from the event itself, you can get a handle to the element, and use that to check whether the element is currently checked or not.
Additionally, I recommend keeping your interaction and presentation logic separate. I.e., don't declare event handlers in your HTML, and don't include too much string formatting stuff in your javascript. Keep it surgical, just modify the specific part of the HTML that needs to change -- it will help to wrap the price number in a <span> tag so that you can change the number without having to repeat the 'Base Price: ' part in your javascript. This attention to detail can help keep things clean when your code gets larger.
var currentPriceElement = document.getElementById('currentPrice');
function getCurrentPrice() {
return Number(currentPriceElement.textContent);
}
function setCurrentPrice(price) {
currentPriceElement.textContent = price.toFixed(2);
}
function onExtraCheeseChange(event) {
var target = event.target;
var price = getCurrentPrice();
if (target.checked) {
price += 5;
}
else {
price -= 5;
}
setCurrentPrice(price);
}
document.getElementById('extraCheese').addEventListener('change', onExtraCheeseChange);
<input type="checkbox" value="extraCheese" id="extraCheese" />
<label for="extraCheese"> Extra Cheese </label>
<h3 id="pizzaPrice"> Base Price: $<span id="currentPrice">15.00</span> </h3>

How can I undo input value by rolling back the previous valid value in Kendo UI

I have an input component as the following:
<input type="number" value="0" name="weight" format="0" min="50" max="100">
What I expect:
input a number between 50 and 100, for example 70;
focus other component then focus back on this input;
input a number which is lower than 50 or greater than 100, for example 20;
focus other component
I expect the box rolling back to 70 instead of populating 50, the min attribute.
Thank you for your help
You can do something like:
var ntb = $("#num").kendoNumericTextBox({
min : 50,
max : 100
}).data("kendoNumericTextBox");
var oldvalue = undefined;
$("#num").on("focusin", function(e) {
oldvalue = $("#num").val();
});
$("#num").on("focusout", function(e) {
var value = $("#num").val();
if (value < ntb.options.min || value > ntb.options.max) {
$("#num").val(oldvalue);
}
});
Basically you intercept the focusin event and save previous value and in focusout you check that are inside the limits, if not, you restore the old saved value.
EDIT If you need to do the same for many input fields in the page, what you can do is:
// Save old value in the numeric text box by adding an oldvalue property to it
$("[data-role='numerictextbox']").on("focusin", function(e) {
var me = $(this).data("kendoNumericTextBox");
me.oldvalue = $(this).val();
});
// Restore saved old value if value is not in range
$("[data-role='numerictextbox']").on("focusout", function(e) {
var value = $(this).val();
var me = $(this).data("kendoNumericTextBox");
if (value < me.options.min || value > me.options.max) {
$(this).val(me.oldvalue);
}
});
See it running here : http://jsfiddle.net/OnaBai/yYX7m
There is a field named "_old" in the KendoNumericTextBox object; this is useful for this purpose, at least when handling a NumericTextBoxSpinEvent, viz.:
function spinEventHandler(e) {
alert("delta from spin is: " + (+e.sender._value - e.sender._old));
}

How do I remove last character from input field on click?

I have a form that when buttons are clicked, it enters a value into an input field. I want to add another button that deletes the last character added. How would I accomplish this using jQuery
<script>
function addTextTag(txt)
{
document.getElementById("text_tag_input").value+=txt;
}
function removeTextTag()
{
var strng=document.getElementById("text_tag_input").value;
document.getElementById("text_tag_input").value=strng.substring(0,strng.length-1)
}
</script>
<input id="text_tag_input" type="text" name="tags" />
<div class="tags_select">
1
2
3
delete
</div>​
Used a modified version of your code itself try
the simple answer is, if you are using jquery, to do something like this:
//select the button, add a click event
$('#myButtonId').on('click',function () {
//get the input's value
var textVal = $('#myInputId').val();
//set the input's value
$('#myInputId').val(textVal.substring(0,textVal.length - 1));
});
var lastChar = function (x) {
"use strict";
var a = document.getElementById(x),
b = a.value;
a.value = b.substring(0, b.length - 1);
};
No jQuery required. The x variable is the id of the input you want to mutilate.

jQuery validate dynamic percentage field

I'm using the jQuery validate plugin. I'm trying to calculate the sum of all inputs fields using the class .percent. If the sum of the .percent fields isn't equal to 100%, throw validation error.
The percent rows are a part of a dynamic grid and can very in number. You'll see a sample of what I've been working on below. I'm finding the addMethod is called for every input.percent rather than a single time. I'd also like to say it's being called before submit is called.
the code.
html
<div class="row">
<input value="" class="percent"/>
</div>
<div class="row">
<input value="" class="percent"/>
</div>
js
$.validator.addClassRules({
percent: {percent:true}
});
$.validator.addMethod("percent",
function cals(value, element) {
// all the fields that start with 'coeff'
var percent = element;
var total = 0;
for (var i = 0; i < percent.length; i++) {
total += Number(percent[i].value);
}
return total == 100;
}, $.format("Percentage fields most total up to 100%"));
$("form").validate({
});
Updates
I've tried the following code with minor success
$("#modify-funding .percent").rules('add', {sum: 100});
$.validator.addMethod("sum", function (value, element, params) {
var sumOfVals = 0;
$("#modify-funding .percent").each(function () {
sumOfVals = sumOfVals + parseInt($(this).val().length ? $(this).val() : 0);
});
if (sumOfVals == params) return true;
return false;
},
$.format("Percentage fields most total up to 100%")
);
when passing the class into rules it's only passing in a single element which doesn't enable me to query for the additional percent fields. The other issue is it only adds the error class to the first .percent element and the additional elements will not release the error once the 100% criteria has been met.
Update 2
This is the closest I've come to getting percent validation working. It isn't very efficient code since it needs to loop through all the percent fields every time you loop the rules. The code still validates before a submit action has taken place plus does not clear all the percent errors on keyup when the percent has been corrected to equal 100.
$("#modify-funding .percent").each(function() {
$(this).rules('add', {sum: [".percent"]});
})
$.validator.addMethod("sum", function (value, element, params) {
var sumOfVals = 0;
$(params[0]).each(function() {
sumOfVals += parseFloat($(this).val().length ? $(this).val() : 0);
});
if (sumOfVals == 100) return true;
return false;
},
$.format("Percentage fields most total up to 100%")
);
Don't use jquery for such a simple validation. I don't really understand what all the hype is about jquery. It just makes your code look all ugly.
function validate() {
var ret = false;
var total = 0;
var elems = document.getElementsByTagName('*'), i;
for (i in elems)
if (elems[i].className == "percent")
total += parseFloat( elems[i].value);
if (total == 100)
ret = true;
return ret;
}

Sum a list of text boxes in jQuery

I have a form in which there are textbox(s) added dynamically using jquery.
The textbox ids is formed as an array, i.e. Quantity[0], Quantity[1], Quantity[2] ...
I want to add the numbers in these textbox(s) and display the value in another textbox named "total_quantity" preferably when the focus is shifted out of the array textbox.
How can I do it? I dont mind using jQuery or plain javascript, which ever is easier.
I would suggest giving a common class to your quantity fields such that:
<input type="text" class="quantity" onblur="calculateTotal();" />
Then you would be able to define the following function with jQuery:
function calculateTotal() {
var total = 0;
$(".quantity").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
total += parseFloat(this.value);
}
});
$("#total_quantity").val(total);
}
The onblur event will fire each time the focus is shifted from the quantity fields. In turn, this will call the calculateTotal() function.
If you prefer not to add a common class, you can use the $("input[id^='Quantity[']") selector, as Felix suggest in the comment below. This will match all the text boxes that have an id starting with: Quantity[
var Total = 0;
$("input[id^='Quantity[']").each(function() { Total += $(this).val()|0; });
$("#total_quantity").val(Total);
Use the following function, if one can't use document.getElementsByName(), as some MVC frameworks such as Struts and Spring MVC use the name attribute of a text to bind the element to a backend object.
function getInputTypesWithId(idValue) {
var inputs = document.getElementsByTagName("input");
var resultArray = new Array();
for ( var i = 0; i < inputs.length; i++) {
if(inputs[i].getAttribute("id") == idValue) {
resultArray.push(inputs[i]);
}
}
return resultArray;
}

Categories

Resources