Get the current class from HTML in Javascript - javascript

I'm trying to get a "check all" checkbox working and I can't seem to find a way.
Edit: the issue is that in my case; the class names are all "checkButtonLot (current lot number)" as they're generated through a "for" loop in the twig. What I don't get is how to pass that current lot number as a variable to the Js; so that when I click on the 1st lot number checkbox; the 1st lot number sub-products are all checked; but the rest of the lot numbers are not.
Here's the Twig for the checkbox that should check the rest:
<div class="custom-control custom-checkbox">
<input id="checkButtonLot{{ currentProduct.lotNumber }}" type="checkbox"
class="custom-control-input js-checkBoxLot{{ currentProduct.lotNumber }} js-checkable"
name="checkButtonLot{{ currentProduct.lotNumber }}" value="{{ currentProduct.lotNumber }}">
<label class="custom-control-label" for="checkButtonLot{{ currentProduct.lotNumber }}"></label>
</div>
Here's the twig for the other checkboxes:
<div class="custom-control custom-checkbox">
<input id="checkButtonLotsub_product{{ sub_product.rankId }}_{{currentProduct.lotNumber}}" type="checkbox"
class="custom-control-input js-checkBoxLotsub_product{{ sub_product.rankId }}_{{currentProduct.lotNumber}} js-checkable"
name="checkButtonLotsub_product{{ sub_product.rankId }}_{{currentProduct.lotNumber}}"
value="{{ sub_product.id }}_{{ sub_product.rankId }}_{{currentProduct.lotNumber}}">
<label class="custom-control-label"
for="checkButtonLotsub_product{{ sub_product.rankId}}_{{currentProduct.lotNumber}}"></label>
</div>
Here's the Js script that's supposed to make it work:
var checkBoxSelectAllOneLot = Array.prototype.slice.call(
document.getElementsByClassName(classCheckboxesLots)
);
addEventAllOneLot(checkBoxSelectAllOneLot);
function addEventAllOneLot(checkboxAll) {
var checkboxAll = checkBoxSelectAllOneLot;
checkboxAll.map(function (btnElement) {
console.log(btnElement);
btnElement.addEventListener("click", selectAllOneLot);
});
}
function selectAllOneLot() {
var separator = "_";
var lotNumber = this.value.split([separator[1]]);
var checkboxAllOneLot = Array.prototype.slice.call(
document.getElementsByClassName(classCheckboxesLotWafer)
);
console.log(checkboxAllOneLot);
if (this.checked == true) {
checkboxAllOneLot.map(function (checkbox) {
checkbox.checked = true;
checkbox.classList.toggle("checked");
});
} else {
checkboxAllOneLot.map(function (checkbox) {
checkbox.checked = false;
});
}
deselectButtonAll();
}
EDITED: the display language isn't HTML its indeed Twig.
Any one would have any insight on this, I'd appreciate greatly.
Have a good one

Your code is pretty convoluted, so I'm not going to weed through it (no offense), but here's a very simple method I'm sure you can adapt for your situation:
document.getElementById("check-all").addEventListener('change', changeHandler)
function changeHandler(event) {
for (const checkbox of document.querySelectorAll('.group')) {
checkbox.checked = event.target.checked
}
}
<input type="checkbox" id="check-all"> <label for="check-all">check all</label>
<br>
<input type="checkbox" class="group">
<input type="checkbox" class="group">
<input type="checkbox" class="group">
<input type="checkbox" class="group">

Related

I want to catch all labels of checked checkbox in javascript

Is there a way to catch all the label texts of a checked checkbox in Javascript (not JQuery).
My HTML is:
<div class="wpgu-onboarding-answer-container">
<div class="wpgu-onboarding-answer" data-bc-answer-post="Firstitem">
<input id="post-3-0" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="670" checked="checked">
<label for="post-3-0" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">Firstitem</span>
</label>
</div>
<div class="wpgu-onboarding-answer" data-bc-answer-post="SecondItem">
<input id="post-3-8" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="681">
<label for="post-3-8" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">SecondItem</span>
</label>
</div>
</div>
I want to catch the label of the checked checkbox in Javascript in order to use it as Javascript Variable in Google Tagmanager.
Currently I've got this code (from www.simoahava.com) to catch the values of the checked checkboxes.
function () {
var inputs = document.querySelectorAll('.wpgu-onboarding-answer-containter input'),
selectedCheckboxes = [];
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type === "checkbox" && inputs[i].checked) {
selectedCheckboxes.push(inputs[i].value);
}
}
return selectedCheckboxes;
}
This script gives me all the values, but these are none-descriptive values. But I want the descriptive labels.
Is there a way to catch the text within the span with class .wpgu-onboarding-answer-title of all checked checkboxes ?
Thanks in Advance
Erik.
Apart from the previous solution, would like to share one more simple solution based on the code mentioned in the question. The solution can be as simple as fetching all the labels with class as wpgu-onboarding-answer-title and based on which input element is selected, fetch the respective label index and use it.
Please note that I have added an extra button for testing the function easily.
function abc() {
var labels = document.querySelectorAll('.wpgu-onboarding-answer-title');
var inputs = document.querySelectorAll('.wpgu-onboarding-answer-container input'),
selectedCheckboxes = [];
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type === "checkbox" && inputs[i].checked) {
selectedCheckboxes.push(labels[i].textContent);
//selectedCheckboxes.push(inputs[i].value);
}
}
console.log(selectedCheckboxes);
return selectedCheckboxes;
}
<div class="wpgu-onboarding-answer-container">
<div class="wpgu-onboarding-answer" data-bc-answer-post="Firstitem">
<input id="post-3-0" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="670" checked="checked">
<label for="post-3-0" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">Firstitem</span>
</label>
</div>
<div class="wpgu-onboarding-answer" data-bc-answer-post="SecondItem">
<input id="post-3-8" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="681">
<label for="post-3-8" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">SecondItem</span>
</label>
</div>
</div>
<button onclick="abc()">
Fetch All Chkbox Values
</button>
Please note that this solution would only work if you have wpgu-onboarding-answer-title class being used for only this purpose and not anywhere else in the page before.
Based on this answer using jQuery, you can use an attribute selector and the ID of the element you want to get the label for, e.g. document.querySelector('label[for=' + button.id + ']'), then get its textContent to get the actual label:
document.querySelectorAll('input.wpgu-onboarding-answer-checkbox').forEach(input => {
console.log(input.id + ' ' +
document.querySelector('label[for=' + input.id + ']').textContent.trim() + ' ' +
(input.checked? '' : 'not ') + 'checked'
)
});
<div class="wpgu-onboarding-answer-container">
<div class="wpgu-onboarding-answer" data-bc-answer-post="Firstitem">
<input id="post-3-0" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="670" checked="checked">
<label for="post-3-0" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">Firstitem</span>
</label>
</div>
<div class="wpgu-onboarding-answer" data-bc-answer-post="SecondItem">
<input id="post-3-8" class="wpgu-onboarding-answer-checkbox" type="checkbox" name="posts_stijlen[]" value="681">
<label for="post-3-8" class="wpgu-onboarding-answer-label">
<span class="wpgu-onboarding-answer-title">SecondItem</span>
</label>
</div>
</div>
This could help you.
var inputs = document.querySelectorAll(".wpgu-onboarding-answer-container input:checked+label>span");
var checkbox = [];
inputs.forEach(input=>{
checkbox.push(input.textContent);
console.log(input.textContent)
});
Good lucky!

HTML input checkbox always returns false

I know this has been already asked. I checked all the previous question about this topic but I can't find a solution.
This is the problem: I have two input, one is a checkbox and the other one is a radio with three possible choices. Inside a function I have to see firstly if the first checkbox is checked, if yes I will check some other things with an if else statement, otherwise the function will proceed. The radio input will appear later inside the same function. This one will check which of the three choices had been checked previously and will set a variable equal to the value of the checked one. To see if the checkbox is checked I use jQuery with .is(':checked'), but it every returns false, even if I checked them. Any idea?
Sorry if I haven't properly used Stack Overflow, but this is my first question.
This is the HTML, the input is #geoloc_waypoint_active and the radio is #locomotion_radio
<div id="create_route_modal_content" class="modal-body">
<div id="geo_switch">
<div id="geoSwitchDiv">
<label for="geoloc_waypoint_active">
Usa la tua posizione
</label>
<label class="switch">
<input id="geoloc_waypoint_active" class="form-check form-check-inline" type="checkbox">
<span class="slider round"></span>
</label>
</div>
<br>
<div id="locomotion_radio">
<label><input class="locomInput" type="radio" name="locomotion" value="walking" checked><img class='locomotionImg' src='immagini/walking.png'></label>
<label><input class="locomInput" type="radio" name="locomotion" value="cycling"><img class='locomotionImg' src='immagini/cycling.png'></label>
<label><input class="locomInput" type="radio" name="locomotion" value="driving"><img class='locomotionImg' src='immagini/driving.png'></label>
</div>
DrawOnMap() {
let formattedCoord = "";
let geoposition = $('#geoloc_waypoint_active').is(':checked');
console.log(geoposition)
if (geoposition) {
var geoL = $('#geo_Locator .mapboxgl-ctrl .mapboxgl-ctrl-icon');
if (!map.getLayer('points') && geoL.attr('aria-pressed') === 'false') {
alert("L'utente non ha una posizione attualmente attiva.");
return;
} else {
this.waypoints.unshift(window.userPosition);
}
}
if (this.waypoints.length < 2) {
alert("Devi inserire almeno due punti di interesse.");
return;
}
this.waypoints.forEach((waypoint, index, source) => {
formattedCoord += waypoint[0] + "," + waypoint[1];
if (index < source.length - 1) {
formattedCoord += ";";
}
});
let locomotion = $('input[name=locomotion]:checked').val();
let geoposition = $('#geoloc_waypoint_active').is(':checked'); is always false and so It never enter the if
Same thing with let locomotion = $('input[name=locomotion]:checked').val(); It can't find the checked one and set locomotion
have you tried this $("#geoloc_waypoint_active")[0].checked it will give you control right value.
$(document).ready(function(){
console.log($("#geoloc_waypoint_active")[0].checked)
$('#check').on('click',function(){
console.log($("#geoloc_waypoint_active")[0].checked)
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input value='checkVakue' type='button' id='check'/>
<div id="create_route_modal_content" class="modal-body">
<div id="geo_switch">
<div id="geoSwitchDiv">
<label for="geoloc_waypoint_active">
Usa la tua posizione
</label>
<label class="switch">
<input id="geoloc_waypoint_active" class="form-check form-check-inline" type="checkbox">
<span class="slider round"></span>
</label>
</div>
<br>
<div id="locomotion_radio">
<label><input class="locomInput" type="radio" name="locomotion" value="walking" checked><img class='locomotionImg' src='immagini/walking.png'></label>
<label><input class="locomInput" type="radio" name="locomotion" value="cycling"><img class='locomotionImg' src='immagini/cycling.png'></label>
<label><input class="locomInput" type="radio" name="locomotion" value="driving"><img class='locomotionImg' src='immagini/driving.png'></label>
</div>

Creating a textarea when user clicks button

I was wondering what the best way to approach this next feature is.
Right now, when user selects "no" an alert appears. However, I would like for a text area box to appear, instead. Any help or leads on how to tackle this? My first thought is that my if statement will have to change, correct? Any leads are appreciated. I provided a snippet for you to view of what I have so far.
let button = document.querySelector("input.button");
button.addEventListener("click", question1);
function question1() {
var selection = document.querySelector("input[name='groupOfDefaultRadios']:checked");
if (selection.value == 'yes') {
alert("Thank you for your kindness");
} else {
alert("We are sorry! Please write to us telling us what was wrong");
}
}
<div class="clienthelp-card">
<form id="myForm">
<h4> Was this helpful?</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
Here are a few ways you can give a user something to enter text into and then handle it as you see fit.
The first way is to insert a textarea element and add a callback so that when the user selects OK, you can do what you want with the text.
The second way is to use prompt as called called out in other comments
function okButtonCallback(evt) {
const textArea = document.getElementById('textarea1');
alert(`Text Area Text: ${textArea.value}`);
}
const btnTextArea = document.getElementById('textarea');
const btnPrompt = document.getElementById('prompt');
// Use a Text Area to get text and
// add a callback to handle the text
// when the user selects ok
btnTextArea.addEventListener('click', e => {
const container = document.getElementById('myContainer');
const textArea = document.createElement('textarea');
textArea.id = 'textarea1';
const okButton = document.createElement('button');
okButton.innerText = 'OK';
okButton.onclick = okButtonCallback;
container.appendChild(textArea);
container.appendChild(okButton);
});
// Use a prompt to get the text
btnPrompt.addEventListener('click', e => {
const enteredText = prompt('Some sort of message');
alert(`Prompt Text: ${enteredText}`);
});
<button id="textarea">Show Text Area</button>
<button id="prompt">Show Prompt</button>
<div id="myContainer"></div>
The built in alert function cannot be used to get user input.
You can add a hidden div which replaces the alert and where you can also add HTML elements.
Please find slightly modified version of your code to get the idea below:
<div class="clienthelp-card">
<form id="myForm">
<h4> Was this helpful?</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
<div id="result" style="display:none"></div>
<script>
let button = document.querySelector("input.button");
button.addEventListener("click", question1);
function question1() {
var selection = document.querySelector("input[name='groupOfDefaultRadios']:checked");
var result = document.getElementById("result");
if (selection.value == 'yes') {
result.innerHTML = "Thank you for your kindness";
result.style.display = "block";
} else {
var output = "";
output += "We are sorry! Please write to us telling us what was wrong:<br />";
output += "<textarea style='width: 100px; height 100px;'></textarea><br />";
output += "<button>Submit</button>";
result.innerHTML = output;
result.style.display = "block";
}
}
</script>
I think you can create a <textarea id="whatever_you_want" hidden> and you add in the else document.getElementById("whatever_you_want").removeAttribute("hidden")
You can toggle a hidden text field, based on the selection of the radio button.
In the example below, a class is added to the text field to hide it. When the choice is changed to "yes", the class is added; if it is changed to "no", the class is added back.
let submitButton = document.querySelector('input.button');
let radioButtons = document.querySelectorAll('input[type="radio"]');
let hiddenTextArea = document.querySelector('.custom-textarea textarea');
// Add listeners
Array.from(radioButtons).forEach(radio => {
radio.addEventListener('change', (e) => {
let hiddenWrapper = hiddenTextArea.parentElement;
hiddenWrapper.classList.toggle('hidden-field', e.target.value !== 'no');
});
});
submitButton.addEventListener('click', question1);
function question1() {
var selection = document.querySelector("input[name='groupOfDefaultRadios']:checked");
if (selection.value == 'yes') {
alert("Thank you for your kindness");
} else {
alert("We are sorry! Please write to us telling us what was wrong");
}
}
.hidden-field {
display: none;
}
<div class="clienthelp-card">
<form id="myForm">
<h4> Was this helpful?</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<!-- Here -->
<div class="custom-control custom-textarea hidden-field">
<textarea name="feedback"></textarea>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
Another approach is to createElement when the user mark the "NO". I put notes inside this general demo:
let radioI = document.querySelectorAll("input[name='groupOfDefaultRadios']"); // get radio in order to attach eventListener:
radioI.forEach((item) => { item.addEventListener("change", question1)}); // add change event that will trigger this function:
function question1() {
var selection = document.querySelector('input[name="groupOfDefaultRadios"]:checked'); // this is your lines
if (selection.value == 'yes') {
alert('Thank you for your kindness');
// and/or submit the form progrematically using submit() etc... and/or redirect the user etc..
} else {
// create textarea element and display the submit button:
var textA = document.createElement('textarea');
textA.setAttribute('name', 'notHelpNote');
textA.setAttribute('required', 'true');
textA.placeholder = 'We are sorry! Please write to us telling us what was wrong';
document.querySelector('#myForm').appendChild(textA);
document.querySelector('#myForm input[type="submit"]').style.display = 'block';
}
}
<div class="clienthelp-card">
<form id="myForm">
<h4> Was this helpful?</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<input class="button" type="submit" name="groupOfDefaultRadios" value="Submit" style="display: none;">
</form>
</div>
I guess you can create a:
<input type="hidden" name="message" id="myAwesomeHiddenMessageField">
in your form and replacing your second alert by a prompt displaying the question like this :
let promptMessage = prompt("We are sorry! Please write to us telling us what was wrong");
And on submit or whatever :
document.querySelector('#myAwesomeHiddenMessageField').val(promptMessage);
Or you could use document.createElement to append a textearea to your form when "no" is selected. But I'm to lazy to help you more with this. And if you wan't to do this you gonna have to hide the generated textarea if the user choose "yes" in the end. Not sure if it's the best UX choose to make.
Cheers.

Allow only one checked checkbox, Angular best practice.

Im using angular.
I have Three checkboxes in a Group and i want to make sure only one of them can be checked. So if one is checked the other two has to bee unchacked. I can Think of doing this several ways with native JS or jQuery but i want to know if there is a typical Angular way of doing it.
Here is Plunker with a set up of the checkboxes and angular controll.
http://plnkr.co/edit/IZmGwktrCaYNyrWjfSqf?p=preview
<body ng-controller="MainCtrl">
<div>
{{vm.Output}}
<br>
<br>
<br>
<label>
<input type="checkbox" name="groupA" ng-model="vm.a1" ng-change="vm.changeGroupA()"> A1 </label>
<label>
<input type="checkbox" name="groupA" ng-model="vm.a2" ng-change="vm.changeGroupA()"> A2 </label>
<label>
<input type="checkbox" name="groupA" ng-model="vm.a3" ng-change="vm.changeGroupA()"> A3 </label>
<br>
<br>
<br> {{vm.Output}}
</body>
Since you can't use radio buttons, I've made this plnkr when you check one the others are deselected:
http://plnkr.co/edit/apSE3cIXA7DIvulBfNGX?p=preview
<label> <input type="checkbox" name="groupA" ng-model="vm.a1" ng-change="vm.a2 = false; vm.a3 = false; vm.changeGroupA()" > A1 </label>
<label> <input type="checkbox" name="groupA" ng-model="vm.a2" ng-change="vm.a1 = false; vm.a3 = false; vm.changeGroupA()" > A2 </label>
<label> <input type="checkbox" name="groupA" ng-model="vm.a3" ng-change="vm.a2 = false; vm.a1 = false; vm.changeGroupA()" > A3 </label>
Hope it helps =)
Edit: You can probably change the state of the other checkboxes in the controller for best practice, made in the html just to demonstrate more quickly..
Another way to do it would be: http://plnkr.co/edit/kH12pYkXfY6t6enrlSns
<br><br><br>
<label> <input type="checkbox" name="groupA" ng-model="vm.groupA[0]" ng-change="vm.changeGroupA(0)" > A1 </label>
<label> <input type="checkbox" name="groupA" ng-model="vm.groupA[1]" ng-change="vm.changeGroupA(1)" > A2 </label>
<label> <input type="checkbox" name="groupA" ng-model="vm.groupA[2]" ng-change="vm.changeGroupA(2)" > A3 </label>
<br><br><br>
The controller would look like this:
$scope.vm = {
groupA: [false, true, false],
count : 0,
changeGroupA : function (index)
{
for (i = 0, len = this.groupA.length; i < len; ++i) {
this.groupA[i] = ((1 << index) & (1 << i)) > 0;
}
this.Output = '(' + this.count + ')' + this.Output;
this.count ++;
},
Output : 'Here we go'
}
You might want to do it the hard way out. http://plnkr.co/edit/A53w4IJMRXQmvRsxa8JA and it should work
changeGroupA : function (x)
{
if (x === 'A1'){
$scope.vm.a1 = true;
$scope.vm.a2 = false;
$scope.vm.a3 = false;
}
else if (x === 'A2') {
$scope.vm.a2 = true;
$scope.vm.a1 = false;
$scope.vm.a3 = false;
}
else if (x === 'A3') {
$scope.vm.a3 = true;
$scope.vm.a1 = false;
$scope.vm.a2 = false;
}
this.Output = '(' + this.count + ')' + this.Output;
this.count ++;
},
This works perfectly fine for angular 6 or 8
HTML:
<div class="custom-control custom-checkbox custom-control-inline">
<input type="checkbox" class="custom-control-input" id="check1id"
[(ngModel)]="check1" (change)="onlyOneValue($event)"/>
<label for="check1id" class="custom-control-label">Checkbox 1</label>
</div>
<div class="custom-control custom-checkbox custom-control-inline">
<input type="checkbox" class="custom-control-input" id="check2id"
[(ngModel)]="check2" (change)="onlyOneValue($event)" />
<label for="check2id" class="custom-control-label"> Checkbox 2 </label>
</div>
.ts code:
check1=false;
check2=false;
onlyOneValue(e)
{
if (e.target.id == "Check1id") {
this.Check1= true;
this.Check2 = false;
}
else if (e.target.id == "Check1id") {
this.Check1= true;
this.Check2 = false;
}
}
Why don't you just use a radio button?
<label>
<input type="radio" name="groupA" ng-model="vm.a1" ng-change="vm.changeGroupA()"> A1 </label>
<label>
<input type="radio" name="groupA" ng-model="vm.a2" ng-change="vm.changeGroupA()"> A2 </label>
<label>
<input type="radio" name="groupA" ng-model="vm.a3" ng-change="vm.changeGroupA()"> A3 </label>

Automatically populate input field with data on clicking radio buttons

When the user selects a radio button in the 2 categories Plan details and Plan Duration the input field should populate with the relevant data through JavaScript.
Please check the html markup and JavaScript below and suggest corrections or an alternate method that would work.
<h3 class="fltClear">Plan Details</h3>
<div id="spryradio1">
<dt>Plan Type: <span class="required">*</span></dt>
<dd>
<label>
<input type="radio" name="RadioGroup1" value="Silver" id="RadioGroup1_0" onClick="changeplanprice();" class="RadioGroup1" />
Silver</label>
<br>
<label>
<input type="radio" name="RadioGroup1" value="Gold" id="RadioGroup1_1" onClick="changeplanprice();" class="RadioGroup1" />
Gold</label>
<br>
<label>
<input type="radio" name="RadioGroup1" value="Platinum" id="RadioGroup1_2" onClick="changeplanprice();" class="RadioGroup1" />
Platinum</label>
<br>
<label>
<input type="radio" name="RadioGroup1" value="All-in-one" id="RadioGroup1_3" onClick="changeplanprice();" class="RadioGroup1" />
All-in-one</label>
<br>
<span class="radioRequiredMsg">Please make a selection.<span class="hint-pointer"> </span></span>
</dd>
</div>
<!--Plan Duration-->
<div id="spryradio2">
<dt>Plan Duration: <span class="required">*</span></dt>
<dd>
<label>
<input type="radio" name="RadioGroup2" value="Yearly" id="RadioGroup2_0" onClick="changeplanprice();" class="RadioGroup2" />
Yearly</label>
<br>
<label>
<input type="radio" name="RadioGroup2" value="Quaterly" id="RadioGroup2_1" onClick="changeplanprice();" class="RadioGroup2" />
Quaterly</label>
<br>
<label>
<input type="radio" name="RadioGroup2" value="Monthly" id="RadioGroup2_2" onClick="changeplanprice();" class="RadioGroup2" />
Monthly</label>
<br>
<label>
<input type="radio" name="RadioGroup2" value="Other" id="RadioGroup2_3" onClick="changeplanprice();" class="RadioGroup2" />
Other</label>
<br>
<span class="radioRequiredMsg">Please make a selection.<span class="hint-pointer"> </span></span>
</dd>
</div>
<!--Plan Price-->
<div>
<script>
function changeplanprice() {
var plantype=document.getElementByClassName('RadioGroup1').value;
var planduration=document.getElementByClassName('RadioGroup2').value;
if(plantype=="Silver") {
if(planduration=="Monthly") {
document.getElementById('Price').value='£ 39.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Quaterly") {
document.getElementById('Price').value='£ 79.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Yearly") {
document.getElementById('Price').value='£ 124.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Other") {
document.getElementById('Price').value='';
document.getElementById('Price').readOnly=false;
}
}
else if(plantype=="Gold") {
if(planduration=="Monthly") {
document.getElementById('Price').value='£ 49.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Quaterly") {
document.getElementById('Price').value='£ 99.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Yearly") {
document.getElementById('Price').value='£ 179.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Other") {
document.getElementById('Price').value='';
document.getElementById('Price').readOnly=false;
}
}
else if(plantype=="Platinum") {
if(planduration=="Monthly") {
document.getElementById('Price').value='£ 59.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Quaterly") {
document.getElementById('Price').value='£ 199.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Yearly") {
document.getElementById('Price').value='£ 279.98';
document.getElementById('Price').readOnly=true;
}
else if(planduration=="Other") {
document.getElementById('Price').value='';
document.getElementById('Price').readOnly=false;
}
} }
</script>
<div>
<dt><label for="Price">Plan Price:</label></dt>
<dd class="bg"><input type="text" name="Price" id="Price" size="80" class="input" readonly="readonly" />
</dd>
</div>
First suggestion that I will give is to have single
document.getElementById('Price').readOnly=true;
This will make your code more readable.
Second suggestion is that you can have 2 arrays one for plantype and other for planduration, and the radio-buttons instead of text, have array index as value.
This will not only make your code more readable, but also more manageable.
Suppose if you have to add one planduration, you will have to add the same condition for all plantypes, where there is a possibility of missing out one case.
Your function could use a little bit of cleanup, but there is one problem that I see. You are using document.getElementByClassName(' ... ').value;. This isn't correct. The function is actually document.getElementsByClassName (note Elements is plural). This function returns an array of all elements with that class name. So you cannot call .value directly on that. You would need to loop through the array of elements to find which element is checked and take the value of that.
Given that all the radio buttons of one group have the same name, and there is another function, document.getElementsByName, there is no reason to use getElementsByClassName.
I would change your function. This is tested and works, and is more easily scalable, in case you come up with new pricing options. All you would have to do is add on to the prices object:
function changeplanprice() {
var plantype;
var plantypes = document.getElementsByName('RadioGroup1');
for (var i=0; i < plantypes.length; i++) {
if (plantypes[i].checked)
plantype = plantypes[i].value;
}
var planduration;
var plandurations = document.getElementsByName('RadioGroup2');
for (i = 0; i < plandurations.length; i++) {
if (plandurations[i].checked)
planduration = plandurations[i].value;
}
if (plantype === undefined || planduration === undefined)
return;
document.getElementById('Price').readOnly = (planduration != "Other");
var prices = {
"Silver":{
"Monthly":"£ 39.98",
"Quarterly":"£ 79.98",
"Yearly":"£ 124.98",
"Other":""
},
"Gold":{
"Monthly":"£ 49.98",
"Quarterly":"£ 99.98",
"Yearly":"£ 179.98",
"Other":""
},
"Platinum":{
"Monthly":"£ 59.98",
"Quarterly":"£ 199.98",
"Yearly":"£ 279.98",
"Other":""
},
"All-in-one":{
"Monthly":"...", /* prices weren't provided for All-in-one in the example */
"Quarterly":"...",
"Yearly":"...",
"Other":""
}
};
document.getElementById('Price').value = prices[plantype][planduration];
}

Categories