Multiple radio buttons with same set of options - javascript

I have four sets of radio buttons, each containing four options as shown in the code below:
<div *ngFor="let index of [0,1,2,3]">
<label *ngFor="let vehicle of vehicles" class="radio">
<input type="radio"
id="radio1"
[value]="vehicle"
(change)="updateValues(vehicles, formArray.value, index)"
name="vehicle" formControlName="vehicle">
{{vehicle.name}} ({{vehicle.total_no}})
</label>
</div>
Each vehicle in the above option set has a name and total number attached to it. On selecting a vehicle, the total number value should update. The option should also be disabled if the total number is zero.
I have written a function that correctly updates the values, but it unfortunately registers changes in the other sets of radio buttons too.
updateValues(vehicles, form, index) {
let x;
let selectedVehicles = form.map(x => x.vehicle);
if (this._prevSelectedVehicles[index] === '') {
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
this.updateTime(form, selectedVehicles);
} else if (
selectedVehicles[index].name !== this._prevSelectedVehicles[index].name
) {
x = vehicles.indexOf(this._prevSelectedVehicles[index]);
vehicles[x].total_no += 1;
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
this.updateTime(form, selectedVehicles);
}
}
How can I make sure that the values selected in the previous divs are not updated? Also attaching a mockup if the question is unclear.

Use an unique ID for each vehicle-object and compare by this. E.g.
...
if(vehicles[x].id === this._prevSelectedVehicles[index].id){
x = vehicles.indexOf(this._prevSelectedVehicles[index]);
vehicles[x].total_no += 1;
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
}
...

Related

How to display total automatically without submit button?

I am very new at JavaScript so a step by step answer would be much appreciated. Right now my code is set up so when you click the submit button it displays the total but instead I would like the total to be updated automatically by just checking the checkboxes and to not have a submit button at all.
function calcTotal()
{
var itemTotal = 0;
var items = document.getElementsByTagName("input");
for (var i = 0; i < 5; i++) {
if (items[i].checked){
itemTotal += parseInt(items[i].value);
}
}
document.getElementById("total").innerHTML = "Your order total is $" + itemTotal +".00";
}
var submitButton = document.getElementById("sButton");
submitButton.addEventListener("click", calcTotal);
Actually you need to bind Checkbox's event change, instead of Form submit button click. That whenever you change checkbox value by checking or unchecking it, It call the function calcTotal() to update the value.
Here is updated Javascript code:
function calcTotal()
{
var itemTotal = 0;
var items = document.getElementsByTagName("input");
for (var i = 0; i < 5; i++) {
if (items[i].checked){
itemTotal += parseInt(items[i].value);
}
}
document.getElementById("total").innerHTML = "Your order total is $" + itemTotal +".00";
}
var checkBoxItems = document.getElementsByTagName("input");
checkBoxItems.addEventListener("change", calcTotal);
Hope it will help you.
Just add a change event to every checkbox. When you toggle the checked state, recalculate the total by grabbing the :checked checkboxes.
Array.from(document.querySelectorAll('input[type="checkbox"]')).forEach(chk => {
chk.addEventListener('change', recalculateTotal);
});
function recalculateTotal() {
let total = Array.from(document.querySelectorAll(':checked')).reduce((sum, chk) => {
return sum + parseInt(chk.value, 10);
}, 0);
document.getElementById('total').innerHTML = '$' + total.toFixed(2);
}
label { display: inline-block; margin-right: 1em; }
div { margin-top: 1em; }
<label>$1 <input type="checkbox" value="1" /></label>
<label>$10 <input type="checkbox" value="10" /></label>
<label>$100 <input type="checkbox" value="100" /></label>
<div>Your order total is: <span id="total">$0.00</span></div>
The key is listening to the input event on the input elements instead of the click event on the button element.
Additional notes, when possible:
Use single quotes in JS, double quotes in HTML
Use let or const instead of var
Don't reinvent .reduce when you need to reduce an array of values into a single value (e.g. compute a sum).
Use template strings (e.g. `y: ${y}`) instead of concatenating strings (e.g. "y: " + y).
let inputs = [...document.querySelectorAll("input")];
let calcTotal = () => {
let sum = inputs.reduce((sum, input) => sum + (input.checked ? parseInt(input.value) : 0), 0);
document.querySelector("#total").textContent = `Your order total is $${sum}.00`;
};
inputs.forEach(input => input.addEventListener('input', calcTotal));
<label><input type="checkbox" value=30>$30 hamburger</label>
<label><input type="checkbox" value=45>$45 french fries</label>
<label><input type="checkbox" value=1>$1 cola</label>
<label><input type="checkbox" value=60>$60 parking</label>
<label><input type="checkbox" value=20>$20 cookie</label>
<label><input type="checkbox" value=290>$290 large cookie</label>
<div id="total"></div>

js crossing two function

I'm beginer in js, please help me.
I have two functions. First function sum all checked input ticket and view sum price, secondary function check discount code and takes into account the new price.
The problem is when I add a discount code and then will choose a ticket. Then it does not calculate the value.
https://jsfiddle.net/wznvfkm3/
$('.participantEventTicket').on('change', function() {
var totalPrice = 0.00;
$('.participantEventTicket:checked').each(function() {
totalPrice += parseFloat($(this).data('price'), 10);
});
$('.participantEventTicketSum').html(totalPrice.toFixed(2));
$('.participantEventTicketDiscountValueTotal').html(totalPrice);
});
$('.participantEventTicketDiscount').on('change', function() {
var code = ($(this).val());
var valueTotal = document.getElementById('participantEventTicketSum').innerHTML;
var value = 0;
var liste = [];
liste[0] = ['ABB'], -5]; liste[1] = ['BBC'], -10];
for (var i = 0, len = liste.length; i < len; i++) {
if (liste[i][0] === code) {
var value = liste[i][1];
}
}
var valueTotalS = parseInt(valueTotal) + parseFloat(value);
$('#participantEventTicketDiscountValue').html(value.toFixed(2));
$('#participantEventTicketDiscountValueTotal').html(valueTotalS);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
ticket 1
<input type="checkbox" name="participantEventTicket[]" value="5" class="participantEventTicket" />
<br/>ticket 2
<input type="checkbox" name="participantEventTicket[]" value="10" class="participantEventTicket" />
<br/>Sume tickets: <span class="participantEventTicketSum" id="participantEventTicketSum">0.00</span>
<br/>Discount coupon
<input type="text" id="participantEventTicketDiscount" class="participantEventTicketDiscount">
<br/>Discount value <span id="participantEventTicketDiscountValue" class="participantEventTicketDiscountValue">0.00</span>
<br/>Discount value sum <span id="participantEventTicketDiscountValueTotal" class="participantEventTicketDiscountValueTotal">0.00</span>
</form>
Slawotu,
Please check this fiddle
You had couple errors:
$('.participantEventTicket:checked').each(function () { totalPrice += parseFloat($(this).val(), 10);});
// you supposed to take $(this).val()
You didn't put calculation of total Price when you entered discount and changed you ticket:
$('.participantEventTicketDiscountValueTotal').html(totalPrice + value);
Forgot but brackets:
liste[0] = [['ABB'], -5];
liste[1] = [['BBC'], -10];
You compared 2 different objects using === instead use ==
if (liste[i][0] == code)
Declare val on top of the file, don't declare inside if statement.
var value = 0;

allow 0 in mm/dd/yyyy format for month at start using javascript

I have one textbox and keypad design to take date of birth by user.
HTML code
Memory = "0"; // initialise memory variable
Current = "0"; // and value of Display ("current" value)
Operation = 0; // Records code for eg * / etc.
MAXLENGTH = 8; // maximum number of digits before decimal!
function format(input, format, sep) {
var output = "";
var idx = 0;
for (var i = 0; i < format.length && idx < input.length; i++) {
output += input.substr(idx, format[i]);
if (idx + format[i] < input.length) output += sep;
idx += format[i];
}
output += input.substr(idx);
return output;
}
function AddDigit(dig) //ADD A DIGIT TO DISPLAY (keep as 'Current')
{ if (Current.indexOf("!") == -1) //if not already an error
{ if ( (eval(Current) == 0)
&& (Current.indexOf(".") == -1)
) { Current = dig;
} else
{ Current = Current + dig;
};
Current = Current.toLowerCase(); //FORCE LOWER CASE
} else
{ Current = "Hint! Press 'Clear'"; //Help out, if error present.
};
if (Current.length > 0) {
Current = Current.replace(/\D/g, "");
Current = format(Current, [2, 2, 4], "/");
}
document.calc.display.value = Current.substring(0, 10);
}
function Clear() //CLEAR ENTRY
{ Current = "0";
document.calc.display.value = Current;
}
<form Name="calc" method="post">
<input class="intxt1" autocomplete="off" id="ptdob" maxlength="6" name="display" type="tel" value="" placeholder="MM/DD/YYYY"><button class="cancel-icon" type="reset" OnClick="Clear()"></button>
<div class="calculator" style="margin: 30px auto;">
<!-- Screen and clear key -->
<div class="keys">
<!-- operators and other keys -->
<span OnClick="AddDigit('1')">1</span>
<span OnClick="AddDigit('2')">2</span>
<span OnClick="AddDigit('3')">3</span>
<span OnClick="AddDigit('4')">4</span>
<span OnClick="AddDigit('5')">5</span>
<span OnClick="AddDigit('6')">6</span>
<span OnClick="AddDigit('7')">7</span>
<span OnClick="AddDigit('8')">8</span>
<span OnClick="AddDigit('9')">9</span>
<span OnClick="AddDigit('0')" style="width: 166px;">0</span>
<span class="clear" OnClick="Clear()">
<div class="xBox">X</div>
</span>
</div>
</div>
</form>
I am taking date in MM/DD/YYYY format. Above code is working fine. It takes digits by automatically adding / in between digits. But when user wants to enter date like 05/11/2016, for month it does not allowing to take 0 at start. when user clicks 0 from keypad and then 5 for example, it coverts 0 to 5. It does not take 0 at the beginning. And it adds next clicked digit to month. e.g. 51/11/2016 like this.
How should I allow 0 at the beginning for month?
NOTE: I have my web page design for above is like below image:
User should not type directly in textbox. Textbox should have inputs from the keypad that I have design. So no use of applying date functionality on textbox like type="date" or using datepicker or any plugins as user is not directly using textbox.
You're quite close, but there are definitely better ways of doing this, as suggested in the comments (DatePicker, moment.js(), etc.).
However, looking at your code, you have a few problems.
Current = "0"; - why are we setting the default value to '0'? It should be Current = "";.
if(eval(Current) == 0) - I have no idea what this is doing. However, if the first digit is '0', then you're doing if(eval(0) == 0). i.e. if(false == false). i.e. if(true).
eval is evil, but if you insist on doing it that way, then you can switch that line to if(eval(Current) === undefined).
Lastly, in Clear, Current = "0"; - same as before. Current = "";.
What you have isn't a bad first attempt at JS, so keep practicing. Some tips:
Lose the Title Case var/function names.
Use var whenever defining variables (unless using ES6 - then use let/const)
Don't recreate the wheel - use libraries that already exist.
Use correct HTML attributes - onClick over OnClick.
Memory = "0"; // initialise memory variable
Current = ""; // and value of Display ("current" value)
Operation = 0; // Records code for eg * / etc.
MAXLENGTH = 8; // maximum number of digits before decimal!
function format(input, format, sep) {
var output = "";
var idx = 0;
for (var i = 0; i < format.length && idx < input.length; i++) {
output += input.substr(idx, format[i]);
if (idx + format[i] < input.length) output += sep;
idx += format[i];
}
output += input.substr(idx);
return output;
}
function AddDigit(dig) //ADD A DIGIT TO DISPLAY (keep as 'Current')
{ if (Current.indexOf("!") == -1) //if not already an error
{ if ( (eval(Current) === undefined)
&& (Current.indexOf(".") == -1)
) { Current = dig;
} else
{ Current = Current + dig;
};
Current = Current.toLowerCase(); //FORCE LOWER CASE
} else
{ Current = "Hint! Press 'Clear'"; //Help out, if error present.
};
if (Current.length > 0) {
Current = Current.replace(/\D/g, "");
Current = format(Current, [2, 2, 4], "/");
}
document.calc.display.value = Current.substring(0, 10);
}
function Clear() //CLEAR ENTRY
{ Current = "";
document.calc.display.value = Current;
}
<form Name="calc" method="post">
<input class="intxt1" autocomplete="off" id="ptdob" maxlength="6" name="display" type="tel" value="" placeholder="MM/DD/YYYY"><button class="cancel-icon" type="reset" OnClick="Clear()"></button>
<div class="calculator" style="margin: 30px auto;">
<!-- Screen and clear key -->
<div class="keys">
<!-- operators and other keys -->
<span OnClick="AddDigit('1')">1</span>
<span OnClick="AddDigit('2')">2</span>
<span OnClick="AddDigit('3')">3</span>
<span OnClick="AddDigit('4')">4</span>
<span OnClick="AddDigit('5')">5</span>
<span OnClick="AddDigit('6')">6</span>
<span OnClick="AddDigit('7')">7</span>
<span OnClick="AddDigit('8')">8</span>
<span OnClick="AddDigit('9')">9</span>
<span OnClick="AddDigit('0')" style="width: 166px;">0</span>
<span class="clear" OnClick="Clear()">
<div class="xBox">X</div>
</span>
</div>
</div>
</form>

balancing two input number fields in jquery

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);
});
});

Javascript Checkbox onClick Addition

I have a form with two check box.
Checkbox A = $1500
Checkbox B = $1500
What I want to do is, when Checkbox A is "checked", I want to display $1500 and add into hidden value. When unchecked, subtract $1500.
When both checkbox checked, I want each other to be performed addition, which means I want to have the value "$3000" in total, when one removed, subtracted accordingly.
Currently with my codes, I can make it work for one checkbox only, which means, when checkbox is checked, it will be $1500 and when one it's removed back, it's substracted. I don't know how to combine Checkbox A & Checkbox B.
Please see my codes and help me out.
HTML
<label>
<input type="checkbox" name="Meeting" onClick="if (this.checked) { onCheck3() } else { onUncheck3() }" value="Pre-Meeting 1" id="Meeting" />
Pre-Meeting 1
</label>
<label>
<input type="checkbox" name="Meeting" onClick="if (this.checked) { onCheck4() } else { onUncheck4() }" value="Pre-Meeting 2" id="Meeting" />
Pre-Meeting 2
</label>
<input type="text" name="PreMeetingAmount" readonly id="PreMeetingAmount" /><input type="hidden" name="PreMeetingAmounthidden" readonly id="PreMeetingAmounthidden" />
Javascript
function onCheck3(){
t = document.form1.PreMeetingAmount.value;
t2 = 0;
if (t == 0) {
document.form1.PreMeetingAmount.value = 1500;
}
}
function onCheck4(){
t = document.form1.PreMeetingAmount.value;
t2 = 0;
if (t == 0) {
document.form1.PreMeetingAmount.value = 1500;
}
}
function onUncheck3(){
t = document.form1.PreMeetingAmount.value;
t = t - 1500;
if (t == 0)
document.form1.PreMeetingAmount.value = document.form1.PreMeetingAmounthidden.value;
else
document.form1.PreMeetingAmount.value = t;
}
function onUncheck4(){
t = document.form1.PreMeetingAmount.value;
t = t - 1500;
if (t == 0)
document.form1.PreMeetingAmount.value = document.form1.PreMeetingAmounthidden.value;
else
document.form1.PreMeetingAmount.value = t;
}
You are always setting the value to 1500. You need to add 1500 rather than set it to 1500. Try changing onCheck3 and onCheck4 similar to this:
function onCheck3() {
t = Number( document.form1.PreMeeting.value );
document.form1.PreMeeting.value = t + 1500;
}

Categories