Reputation: 207
I am a javascript noob. I am currently learning how to check if the checkboxes are checked. This is the code:
<!doctype>
<html>
<head>
<title>Javascript form - input text Field</title>
<script>
var outputt = "";
var i = 0;
function output(frm){
for(i = 0; i < frm.fruits.length; i++){
if(frm.fruits[i].checked){
outputt =+ fruits[i].text;
}
}
alert(outputt);
}
</script>
</head>
<body>
<form>
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry">Strawberry</input>
<input type="checkbox" name="fruits" value="banana">banana</input>
<input type="checkbox" name="fruits" value="apple">apple</input>
<input type="checkbox" name="fruits" value="kiwi">kiwi</input>
<input type="button" name="validate" value="validate" onClick="output(this.form)">
<input type="reset">
</form>
</body>
</html>
What I am trying to do is when the user clicks on the 'validate' button, the output function gets called which passes the form as a reference. in the function, it takes the checkboxes as arrays and then loops through each of the checkboxes checking if they are ticked. If any of the boxes are ticked, then the value is concatinated to the outputt string.
EDIT: I managed to fix the problem although I don't quite understand the solution. So in the below code, the function ouput() takes a parameter of checkBoxArray and this reference comes from the button 'validate'. What if there were 2 checkbox inputs in my form (i.e. one for favourite drinks and one for favourite fruits). How would the browser know which checkbox to check?
<!doctype>
<html>
<head>
<title>Javascript form - input text Field</title>
<script>
var outputt = "";
var i = 0;
function output(checkBoxArray){
for(i = 0; i < checkBoxArray.length; i++){
if(checkBoxArray[i].checked){
outputt += checkBoxArray[i].value;
}
}
alert(outputt);
}
</script>
</head>
<body>
<form>
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry">Strawberry</input>
<input type="checkbox" name="fruits" value="banana">banana</input>
<input type="checkbox" name="fruits" value="apple">apple</input>
<input type="checkbox" name="fruits" value="kiwi">kiwi</input>
<input type="button" name="validate" value="validate" onClick="output(this.form)">
<input type="reset">
</form>
</body>
</html>
Upvotes: 0
Views: 98
Reputation: 253506
What I am trying to do is when the user clicks on the 'validate' button, the output function gets called which passes the form as a reference. [In] the function, it takes the checkboxes as arrays…
No, it doesn't; it accesses the HTMLInputElement
nodes — which happen to be check-boxes — and iterates through them using a loop. This doesn't make them an 'array', they're not even a NodeList, it's just that the browser uses the incrementation of the i
variable to retrieve, and access, each <input />
element in turn within the loop.
…and then loops through each of the checkboxes checking if they are
ticked[checked]. If any of the boxes are ticked, then the value is concatenated to theoutputt
string.
First, I'll tidy up the code you've posted and explain why (in comments, in the code itself):
// this is a matter of taste, but I've changed the variable's name from
// 'frm' to 'form' to be more clear of its contents:
function output(form) {
// this isn't used outside the function, and global variables
// can lead to (unanticipated) mistakes; here we initialise the
// variable within the function in which it's used:
var outputt = '';
// initialising the 'i' variable within the loop itself (since
// that's where it's being used), and caching the number of
// elements returned by 'form.fruits.length' (to avoid having
// to re-check it on every iteration):
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
// your updated excerpt showed that you'd realised the
// concatenation operator should be '+=' and not '=+',
// but obviously I corrected that here; also your code had
// 'fruits[i].value' omitting the 'form', so you were
// trying to access an element from an
// uninitialised/undeclared variable:
outputt += form.fruits[i].value;
}
}
// a matter of taste (again), but using 'console.log()' in place
// of Window.alert() reduces interruptions/work-flow:
console.log(outputt);
}
function output(form) {
var outputt = '';
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
outputt += form.fruits[i].value;
}
}
console.log(outputt);
}
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" onClick="output(this.form)" />
<input type="reset" />
</form>
Now, you'll notice that the string is concatenated together without whitespace, there's a couple of ways to avoid that; the first uses a conditional ('ternary') operator to assess whether the length of the outputt
string is truthy (not zero) or falsey (0):
outputt += (outputt.length > 0 ? ' ' : '') + form.fruits[i].value;
function output(form) {
var outputt = '';
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
outputt += (outputt.length > 0 ? ' ' : '') + form.fruits[i].value;
}
}
console.log(outputt);
}
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" onClick="output(this.form)" />
<input type="reset" />
</form>
An alternative approach is to use an Array to story the values of the checked check-boxes:
function output(form) {
// initialising an empty array, using an array
// literal (the '[]' part):
var outputt = [];
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
// adding each of the checked-<input> element's
// value to that array:
outputt.push(form.fruits[i].value);
}
}
// Using Array.prototype.join() to join the array-elements
// together, with the specified character, to form a string:
console.log(outputt.join(' '));
}
function output(form) {
var outputt = [];
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
outputt.push(form.fruits[i].value);
}
}
console.log(outputt.join(' '));
}
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" onClick="output(this.form)" />
<input type="reset" />
</form>
Further, I'd suggest removing the in-line event-handler from the HTML - taking the onClick
attribute out of the HTML, and replacing it with a JavaScript-added event-handler:
function output() {
// 'this' is passed in automagically from the
// addEventListener() method, the form-node is
// found exactly the same way as in your own code:
var form = this.form,
outputt = [];
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
outputt.push(form.fruits[i].value);
}
}
console.log(outputt.join(' '));
}
// finding all elements whose 'name' property is 'validate':
var validator = document.getElementsByName('validate');
validator[0].addEventListener('click', output);
function output() {
var form = this.form,
outputt = [];
for (var i = 0, len = form.fruits.length; i < len; i++) {
if (form.fruits[i].checked) {
outputt.push(form.fruits[i].value);
}
}
console.log(outputt.join(' '));
}
var validator = document.getElementsByName('validate');
validator[0].addEventListener('click', output);
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" />
<input type="reset" />
</form>
Now, having tidied that up I'd like to go a little further, and actually create, and use, arrays to solve this problem and use some more up-to-date methods to find the relevant elements:
function output() {
// using Array.prototype.map(), in conjunction with
// Function.prototype.call(), to apply an array-method to
// the array-like nodeList (this.form.fruits):
var outputt = Array.prototype.map.call(this.form.fruits, function(fruit) {
// the first argument to the callback function (here 'fruit') is
// the element of the array (here it's an <input /> element),
// if it's checked:
if (fruit.checked) {
// we store the value ('apple', 'banana' etc) in
// the array:
return fruit.value;
}
});
console.log(outputt.join(' '));
}
// using document.querySelector() to retrieve the first (if any)
// element in the document that matches the given CSS selector,
// here we're looking for an input element whose type is equal to 'button'
// and whose name is equal to 'validate':
var validator = document.querySelector('input[type=button][name=validate]');
validator.addEventListener('click', output);
function output() {
var outputt = Array.prototype.map.call(this.form.fruits, function(fruit) {
if (fruit.checked) {
return fruit.value;
}
});
console.log(outputt.join(' '));
}
var validator = document.querySelector('input[type=button][name=validate]');
validator.addEventListener('click', output);
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" />
<input type="reset" />
</form>
Also, it'd make sense to avoid checking inside the loop for whether the <input>
elements are checked
or otherwise, and just select those that are checked
:
function output() {
// here we're using the querySelectorAll() method to retrieve
// only those <input> elements within the form that are checked:
var outputt = Array.prototype.map.call(this.form.querySelectorAll('input:checked'), function(fruit) {
return fruit.value;
});
console.log(outputt.join(' '));
}
function output() {
var outputt = Array.prototype.map.call(this.form.querySelectorAll('input:checked'), function(fruit) {
return fruit.value;
});
console.log(outputt.join(' '));
}
var validator = document.querySelector('input[type=button][name=validate]');
validator.addEventListener('click', output);
<form action="#" method="post">
<p>Click on your favourite fruits</p>
<input type="checkbox" name="fruits" value="strawberry" />Strawberry
<input type="checkbox" name="fruits" value="banana" />banana
<input type="checkbox" name="fruits" value="apple" />apple
<input type="checkbox" name="fruits" value="kiwi" />kiwi
<input type="button" name="validate" value="validate" />
<input type="reset" />
</form>
References:
Upvotes: 1
Reputation: 806
Since you are new to JavaScript, I would suggest familiarizing yourself with the Developer Tools(accessed using F12 in Chrome and IE), particularly the debugger, that come along with your browser. There you can set breakpoints and see what values you can access.
Also, as Morten has suggested, I would look into jQuery(a popular and free JavaScript library); it makes things much easier.
The following post may answer your question:
How to set up groups of checkboxes which affect each other
I think the first step though is to familiarize yourself with the debugger as there are syntax errors in your code.
Upvotes: 0