I'm a bit stuck on how to add in this code if the inputs are empty, to shoot an alert. Would I add another function within the first? Any hints would be appreciated!
function getCandidateNames() {
var inputs = document.getElementsByTagName("input");
var result = [];
for (var i = 0; i < inputs.length; i += 1) {
if (inputs[i].getElementsByTagName("candidate")) {
result.push(inputs[i].value);
}
}
return result;
}
function putCandidateNames(names) {
document.getElementById("candidateName1").innerHTML = names[0];
document.getElementById("candidateName2").innerHTML = names[1];
document.getElementById("candidateName3").innerHTML = names[2];
}
function candidateNames() {
putCandidateNames(getCandidateNames());
}
The HTML
<fieldset id="candidates">
<legend>Candidates</legend>
<div>
<label for="cand1">Candidate 1</label>
<input class="candidate" id="cand1" placeholder="Candidate">
</div>
<div>
<label for="cand2">Candidate 2</label>
<input class="candidate" id="candName" placeholder="Candidate">
</div>
<div>
<label for="cand3">Candidate 3</label>
<input class="candidate" id="candName" placeholder="Candidate">
</div>
</fieldset>
You have many problems in your code that needs to be fixed:
You can't use the same id id="candName" for multiple elements in the page.
This code inputs[i].getElementsByTagName("candidate") is completely wrong here you should use getElementsByClassName("candidate") instead, because you don't have candidate tags you used them as classes.
And instead of getting the inputs nodeList then iterate over it with inputs[i].getElementsByTagName("candidate") you can just use document.getElementsByClassName("candidate").
This is how should be your code:
function getCandidateNames() {
var inputs = document.getElementsByClassName("candidate");
var result = [];
if (Array.prototype.some.call(inputs, function(input) {
return input.value === "";
})) {
alert("Inputs should not be empty!!!");
return false;
}
Array.prototype.forEach.call(inputs, function(input) {
result.push(input.value);
});
return result;
}
Demo:
function getCandidateNames() {
var inputs = document.getElementsByClassName("candidate");
var result = [];
if (Array.prototype.some.call(inputs, function(input) {
return input.value === "";
})) {
alert("Inputs should not be empty!!!");
return false;
}
Array.prototype.forEach.call(inputs, function(input) {
result.push(input.value);
});
console.log(result);
return result;
}
<fieldset id="candidates">
<legend>Candidates</legend>
<div>
<label for="cand1">Candidate 1</label>
<input class="candidate" id="cand1" placeholder="Candidate">
</div>
<div>
<label for="cand2">Candidate 2</label>
<input class="candidate" id="candName" placeholder="Candidate">
</div>
<div>
<label for="cand3">Candidate 3</label>
<input class="candidate" id="candName2" placeholder="Candidate">
</div>
</fieldset>
<button onclick="getCandidateNames()">Validate</button>
Note:
Note the use of Array.prototype.forEach.call and Array.prototype.some.call, which are used to loop over the nodeList borrowing JavaScript Array built-in functions.
Alternative:
This is an alternative using simple syntax:
function getCandidateNames() {
var inputs = document.getElementsByClassName("candidate");
var result = [];
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].value !== "") {
result.push(inputs[i].value);
} else {
alert("Inputs can't be empty !!!");
return false;
}
}
return result;
}
Demo:
function getCandidateNames() {
var inputs = document.getElementsByClassName("candidate");
var result = [];
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].value !== "") {
result.push(inputs[i].value);
} else {
alert("Inputs can't be empty !!!");
return false;
}
}
console.log(result);
return result;
}
<fieldset id="candidates">
<legend>Candidates</legend>
<div>
<label for="cand1">Candidate 1</label>
<input class="candidate" id="cand1" placeholder="Candidate">
</div>
<div>
<label for="cand2">Candidate 2</label>
<input class="candidate" id="candName" placeholder="Candidate">
</div>
<div>
<label for="cand3">Candidate 3</label>
<input class="candidate" id="candName2" placeholder="Candidate">
</div>
</fieldset>
<button onclick="getCandidateNames()">Validate</button>
Related
On h1, the unit should be changed to either celsius or fahrenheit depending on which radio is checked. But how do I change the unit to "celsius" when C radio or "Fahrenheit" when F radio is checked?
const d = document;
const F = d.querySelector("#fahrenheit");
const C = d.querySelector("#celsius");
const checkState = () => {
if (F.checked === true) {
x = "fahrenheit";
return x;
}
if (C.checked === true) {
x = "celsius";
return x;
}
};
const unit = checkState();
const h1 = d.querySelector("h1");
h1.innerHTML = `The current unit is: ${unit}`;
<div class="unit-convert">
<input type="radio" class="unit-input" id="celsius" name="unit" checked="checked">
<label for="celsius" class="unit-label">° C</label>
<input type="radio" class="unit-input" id="fahrenheit" name="unit">
<label for="fahrenheit" class="unit-label">° F</label>
</div>
<h1></h1>
You can make a control function like this
var fahrenheit = 0;
var celsius = 0;
document.getElementById("fahrenheit").addEventListener("click", function(){
fahrenheit = 1;
celsius = 0;
control();
return fahrenheit, celsius
})
document.getElementById("celsius").addEventListener("click", function(){
fahrenheit = 0;
celsius = 1;
control();
return fahrenheit, celsius
})
function control(){
if (fahrenheit == 1) {
document.getElementById("text").innerHTML ="fahrenheit";
}
if (celsius == 1) {
document.getElementById("text").innerHTML ="celsius";
}
}
<h1 id="text"></h1>
<input type="radio" id="fahrenheit">
<input type="radio" id="celsius">
You can use addEventListener to listen for change event which gets fired when value of <input> changes.
const d = document;
const F = d.querySelector("#fahrenheit");
const C = d.querySelector("#celsius");
const checkState = () => {
if (F.checked === true) {
x = "fahrenheit";
return x;
}
if (C.checked === true) {
x = "celsius";
return x;
}
};
function check() {
const unit = checkState();
const h1 = d.querySelector("h1");
h1.innerHTML = `The current unit is: ${unit}`;
}
check();
[F, C].forEach(e => e.addEventListener("change", check));
<div class="unit-convert">
<input type="radio" class="unit-input" id="celsius" name="unit" checked="checked">
<label for="celsius" class="unit-label">° C</label>
<input type="radio" class="unit-input" id="fahrenheit" name="unit">
<label for="fahrenheit" class="unit-label">° F</label>
</div>
<h1></h1>
input elements have a dedicated onchange attribute.
It's essentially a shorther way of adding an event listener for change events.
It will run a callback whenever the input value changes.
Since we already have the name value as the input's id, we can use that to update the h1 text accordingly.
Example:
function onChange(event) {
const selectedUnit = event.id;
updateHeaderText(selectedUnit);
}
function updateHeaderText(selectedUnit = "celsius") {
const header = document.querySelector("h1");
header.innerHTML = `The current unit is: ${selectedUnit}`;
}
updateHeaderText();
<div class="unit-convert">
<input type="radio" class="unit-input" id="celsius" onchange="onChange(this)" name="unit" checked="checked">
<label for="celsius" class="unit-label">° C</label>
<input type="radio" class="unit-input" id="fahrenheit" onchange="onChange(this)" name="unit">
<label for="fahrenheit" class="unit-label">° F</label>
</div>
<h1></h1>
I want to validate my checkboxes to make sure that the user checked at least one, however I keep getting this error:
Uncaught TypeError: Cannot read property 'checked' of undefined.
Here is part of the HTML:
<form name="userSurvey" onsubmit="return validAll()" action="mailto:suvery#worldbook.com" method="post">
Name (Required): <input type="text" name="userName" id="userName" required=""><br> E-Mail (Required): <input type="text" name="mail" id="mail" required=""><br> Phone (Required): <input type="text" name="phone" id="phone" required="" onchange="validNumber()"><br>
<br>
<p>Please choose your favourite types of books.(check all that apply)</p>
<input type="checkbox" name="books" value="Science Fiction">Science Fiction
<input type="checkbox" name="books" value="Travel Guide">Travel Guide
<input type="checkbox" name="books" value="Short Story Collection">Short Story Collection
<input type="checkbox" name="books" value="Other">Other <br>
<textarea></textarea><br>
<input type="submit" name="submit">
<input type="reset" name="reset">
</form>
and part of the JavaScript for the checkboxes:
function validChoice()
{
var bookChoice = document.userSurvey.books.value;
var x= "";
for (i=0;i< 4;i++)
{
if (document.userSurvey['bookChoice'+i].checked)
{
bookChoice = document.userSurvey['bookChoice'+i].value;
x = x +"\n"+ bookChoice;
}
}
if (bookChoice == "")
{
window.alert("You must select at least one book category.");
return false;
}
else
{
var userName = document.userSurvey.userName.value;
var eMail = document.userSurvey.email.value;
var phoneNo = document.userSurvey.phone.value;
return true;
}
}
I am currently learning in JavaScript therefore I would prefer help in JavaScript only.
Full Code on JSFiddle:
https://jsfiddle.net/7qh5segc/
You missed some tag names and missspell them in js function:
<h1>User Survey</h1>
<h2><strong>User Information</strong></h2>
<p>Please enter your details below</p>
<br>
<form name="userSurvey" onsubmit="return validAll()" action="mailto:suvery#worldbook.com" method="post">
Name (Required):
<input type="text" name="userName" id="userName" required="">
<br> E-Mail (Required):
<input type="text" name="email" id="email" required="">
<br> Phone (Required):
<input type="text" name="phone" id="phone" required="" onchange="validNumber()">
<br>
<br>
<p>Please choose your favourite types of books.(check all that apply)</p>
<input type="checkbox" name="books" value="Science Fiction">Science Fiction
<input type="checkbox" name="books" value="Travel Guide">Travel Guide
<input type="checkbox" name="books" value="Short Story Collection">Short Story Collection
<input type="checkbox" name="books" value="Other">Other
<br>
<textarea></textarea>
<br>
<input type="submit" name="submit">
<input type="reset" name="reset">
</form>
and js code goes like this:
function validName() {
var name = document.userSurvey.userName.value;
if (!/^[a-zA-Z]*$/g.test(name)) {
alert("Please enter letters a - z only");
document.userSurvey.userName.focus();
return false;
} else {
return true;
}
}
function validNumber() {
var theNumbersOnly = "";
var theChar = "";
var theInput = document.userSurvey.phone.value;
for (i = 0; i < theInput.length; i++) {
theChar = theInput.substring(i, i + 1);
if (theChar >= "0" && theChar <= "9") {
theNumbersOnly = "" + theNumbersOnly + theChar;
}
}
if (theNumbersOnly.length < 10) {
alert("You must enter 10 numbers.");
document.userSurvey.phone.focus();
} else {
var areacode = theNumbersOnly.substring(0, 3);
var exchange = theNumbersOnly.substring(3, 6);
var extension = theNumbersOnly.substring(6, 10);
var newNumber = "(" + areacode + ") ";
newNumber += exchange + "-" + extension;
document.userSurvey.phone.value = newNumber;
return true;
}
}
function validEmail() {
var email = document.userSurvey.email.value;
var atLoc = email.indexOf("#", 1);
var dotLoc = email.indexOf(".", atLoc + 2);
var len = email.length;
if (atLoc > 0 && dotLoc > 0 && len > dotLoc + 2) {
return true;
} else {
alert("Please enter your e-mail address properly.");
return false;
}
}
function validChoice() {
//var bookChoice = document.userSurvey.books.value;
var bookChoice;
var x = "";
for (var i = 0; i < 4; i++) {
if (document.userSurvey.books[i].checked) {
console.log(document.userSurvey);
bookChoice = document.userSurvey.books[i].value;
x = x + "\n" + bookChoice;
}
}
if (bookChoice == "") {
window.alert("You must select at least one book category.");
return false;
} else {
var userName = document.userSurvey.userName.value;
var eMail = document.userSurvey.email.value;
var phoneNo = document.userSurvey.phone.value;
console.log(userName);
console.log(eMail);
console.log(phoneNo);
return true;
}
}
function validAll() {
if ((validName() == true) && (validEmail() == true) && (validNumber() == true) && (validChoice() == true)) {
return true;
} else {
return false;
}
}
You missed email tag name too. regards
You can fix the checkbox issue using the following code. A sensible way to get all the checkboxes in this case is using their shared "name" attribute. There are other ways if your structure was different - e.g. using a CSS class, or adding some other custom attribute to the elements.
function validChoice() {
var bookChoices = "";
var checkboxes = document.getElementsByName("books"); //get all elements named "books" into an array
for (i = 0; i < checkboxes.length; i++) { //loop the array
if (checkboxes[i].checked) { //if the array item at this index is checked, then add it to the list
bookChoices += "\n" + checkboxes[i].value;
}
}
if (bookChoices == "") {
window.alert("You must select at least one book category.");
return false;
} else {
alert(bookChoices); //just for testing
return true;
}
}
See https://jsfiddle.net/7qh5segc/3/ for a demo using the changed validChoice() function.
I got three textboxes in my Form. My goal is to disable the validate and evaluate textbox if the number in digit textbox is not equal to 0. How do i accomplish this?
Pseudo code
if(digit.Text != 0 )
{
validate.enable = false;
evaluate.enable = false;
}
else
{
validate.enable = true;
evaluate.enable = true;
}
My Attempt
function disableME()
{
var numberTextBox = document.getElementById('number'),
validateTextBox = document.getElementById('validate'),
evaluateTextBox = document.getElementById('evaluate');
if (numberTextBox.value != 0)
{
validateTextBox.disable = true;
evaluateTextBox.disable = true;
}
else
{
validateTextBox.disable = false;
evaluateTextBox.disable = false;
}
}
<form action="welcome.php" method="post" id="myForm">
Number: <input type="number" id="number" onchange="disableME()"><br>
Validate: <input type="text" id="validate" onchange="disableME()"><br>
Evaluate: <input type="text" id="evaluate" onchange="disableME()"><br>
</form>
You should use ELEMENT.disabled instead of ELEMENT.disable.
Here is the change to your code:
function disableME()
{
var numberTextBox = document.getElementById('number'),
validateTextBox = document.getElementById('validate'),
evaluateTextBox = document.getElementById('evaluate');
if (numberTextBox.value != 0)
{
validateTextBox.disabled = true;
evaluateTextBox.disabled = true;
}
else
{
validateTextBox.disabled = false;
evaluateTextBox.disabled = false;
}
}
<form action="welcome.php" method="post" id="myForm">
Number: <input type="number" id="number" onchange="disableME()"><br>
Validate: <input type="text" id="validate" onchange="disableME()"><br>
Evaluate: <input type="text" id="evaluate" onchange="disableME()"><br>
</form>
I am trying to put form content in a JSON dynamically.
It worked before, but after I added a extra layer (arrays in arrays) there seem to be something that I am doing wrong:
aJSON = {};
aJSON['properties'] = [];
aJSON['options'] = [];
aJSON['arrays'] = [];
$('input').each(function () {
if($(this).attr('name') != undefined) {
if($(this).attr('name').indexOf('[]') > -1) {
if(aJSON['arrays'][$(this).attr('name')] == undefined) {
aJSON['arrays'][$(this).attr('name')] = [];
}
if($(this).is(':checked')) {
aJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 1;
} else {
aJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 0;
}
} else {
aJSON['properties'][$(this).attr('name')] = $(this).val();
}
}
});
$('select').each(function () {
if($(this).attr('name') != undefined) {
aJSON['properties'][$(this).attr('name')] = $(this).val();
}
});
var array = getUrlVars();
aJSON['options']['type'] = array['type'];
aJSON['options']['id'] = array['id'];
aJSON['options']['view'] = pageSpecificVariables['view'];
The top 4 lines are just a tryout, I also tried:
aJSON = {'properties':[], 'options':[], 'arrays':[]}
But the only result I am getting is an object with empty arrays of properties, options and arrays.
Before I put all the values directly in aJSON and that worked perfectly.
But for categorizing, I need the 3 categories to exist.
Any idea why my values aren't written to the aJSON?
EDIT
Added JSfiddle here: http://jsfiddle.net/abayob/pob32fs1/
I assume you are trying to serialise a form.
Use jQuery's serializeArray function instead
var myform = $("#myform");
var data = JSON.stringify( myform.serializeArray() );
Update
Because you're trying to use arrays like object-maps
Solution: http://jsfiddle.net/pob32fs1/8/
var oJSON = {
properties: {},
options: {},
arrays: {}
};
$('input[name]').each(function(){
var $el = $(this),
value = $el.attr("value"),
name = $el.attr('name');
if(name.indexOf('[]') >= 0)
{
oJSON.arrays[name] = oJSON.arrays[name] || {};
oJSON.arrays[name][value] = $el.is(':checked') ? 1 : 0;
} else {
oJSON.properties[name] = $el.val();
}
});
$('select[name]').each(function(){
var $el = $(this);
oJSON.properties[$el.attr('name')] = $el.val();
});
oJSON.options['type'] = 'user';
oJSON.options['id'] = 1;
oJSON.options['view'] = 'user-settings';
console.log(oJSON);
Assuming that the name and value attributes of your various inputs are strings, and not just numbers, you should be using nested objects, not nested arrays. You're trying to use associative arrays, which are not available in JavaScript.
var oJSON = {};
$('._save, .btn-success').click(function() {
oJSON = {
properties: {},
options: {},
arrays: {}
};
$('input').each(function() {
if ($(this).attr('name') != undefined) {
if ($(this).attr('name').indexOf('[]') > -1) {
if (oJSON['arrays'][$(this).attr('name')] == undefined) {
oJSON['arrays'][$(this).attr('name')] = {};
}
if ($(this).is(':checked')) {
oJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 1;
} else {
oJSON['arrays'][$(this).attr('name')][$(this).attr('value')] = 0;
}
} else {
oJSON['properties'][$(this).attr('name')] = $(this).val();
}
}
});
$('select').each(function() {
if ($(this).attr('name') != undefined) {
oJSON['properties'][$(this).attr('name')] = $(this).val();
}
});
oJSON['options']['type'] = 'user';
oJSON['options']['id'] = 1;
oJSON['options']['view'] = 'user-settings';
console.log(oJSON);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="tab-content">
<div id="tab-general" class="tab-pane active">
<h4>Gebruikersnaam</h4>
<input type="text" value="John Doe" name="username" class="form-control" required="" placeholder="J. Average">
<h4>E-mailadres</h4>
<input type="email" value="info#info.info" name="mailaddress" class="form-control" required="" placeholder="E-mail#adres.nl">
<div class="row">
<div class="col-md-6">
<input type="password" name="password" minlength="10" class="form-control" placeholder="Nieuw wachtwoord">
</div>
<div class="col-md-6">
<input type="password" name="password_retype" minlength="10" class="form-control" placeholder="Herhaal wachtwoord">
</div>
</div>
<input type="password" name="password_old" class="form-control margin-y-10" placeholder="Huidig Wachtwoord">
</div>
<div id="tab-sites" class="tab-pane">
<h4>Websites</h4>
<div id="site_container">
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="0">
<label>A</label>
</div>
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="1">
<label>B</label>
</div>
<div class="checkbox block">
<input name="sites[]" checked="" type="checkbox" value="2">
<label>C</label>
</div>
</div>
</div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-warning _cancel">Annuleren</button>
<button type="button" class="btn btn-success _save">Opslaan</button>
</div>
Think I'm getting stuck... I'm attempting to take a list of items and create filters based on attributes to the object. I stripped it down into an easier example of books with a cost and year. I currently have a list of books on the page and filters (checkboxes) that can be selected to only show books within a range of cost and/or year. Here is the code I have so far:
<div id="filters">
<h1>FILTERS</h1>
<div class="filter filter_cost">
<input class="target" type="checkbox" min="0" max="9" />Under $10.00<br/>
<input class="target" type="checkbox" min="10" max="19" />$10-$19<br/>
<input class="target" type="checkbox" min="20" max="29" />$20-$29<br/>
<input class="target" type="checkbox" min="30" max="39" />$30-$39<br/>
<input class="target" type="checkbox" min="40" max="1000" />$40 and Over<br/>
</div>
<div class="filter filter_year">
<input class="target" type="checkbox" min="1700" max="1799" />18th Century<br/>
<input class="target" type="checkbox" min="1800" max="1899" />19th Century<br/>
<input class="target" type="checkbox" min="1900" max="1999" />20th Century<br/>
<input class="target" type="checkbox" min="2000" max="2999" />21st Centruy<br/>
</div>
</div>
<div id="books">
<h1>BOOKS</h1>
<div class="book">
<h1>Book 1</h1>
<input type="hidden" name="cost" value="13" />
<input type="hidden" name="year" value="1997" />
</div>
<div class="book">
<h1>Book 2</h1>
<input type="hidden" name="cost" value="22" />
<input type="hidden" name="year" value="1872" />
</div>
</div>
And my jQuery (using 1.6.2):
$(document).ready(function () {
$("input.target").change(function () {
filterResults();
});
});
function filterResults(){
$(".book").each(function () {
var cost = $(this).find("input[name='cost']").val();
var year = $(this).find("input[name='year']").val();
var cover = $(this).find("input[name='cover']").val();
var isHidden = false;
//console.log("Cost in Range: "+filterRange(cost, ".filter_cost"));
//console.log("Year in Range: "+filterRange(year, ".filter_year"));
var filterCost = filterRange(cost, ".filter_cost")?showBook($(this)):hideBook($(this));
var filterYear = filterRange(year, ".filter_year")?showBook($(this)):hideBook($(this));
isHidden?"":filterCost;
isHidden?"":filterYear;
function showBook(obj) {
obj.show();
}
function hideBook(obj) {
isHidden = true;
obj.hide();
}
})
}
function filterRange(amount, elem) {
var checkedInputs = $(elem).find("input:checked").length;
var totalInputs = $(elem).find("input").length;
var inRange = function(){
$(elem).find("input:checked").each(function () {
var min = $(this).attr('min');
var max = $(this).attr('max');
if(amount >= min && amount <= max){
return true;
} else {
return false;
}
});
};
if(checkedInputs == 0 || totalInputs == checkedInputs ){
return true;
}
if(inRange()){
return true;
} else {
return false;
}
}
My issue is that in the filterRange function I'm not sure how to create a range of conditionals based on each input that is checked. So that a price range could be 10-19 and 30-39. My attempt (var inRange) was to go through each checked input, check if the cost was with in the range, then return true, else return false. I think I'm just fundamentally getting off track and unsure if this method would work at all. Any input would be much appreciated.
In the jquery each loop on dom element return statement breaks out of the loop. So your implemenation is wrong. Try this.
function filterRange(amount, elem) {
var checkedInputs = $(elem).find("input:checked").length;
var totalInputs = $(elem).find("input").length;
var returnValue = false;
$(elem).find("input:checked").each(function () {
var min = $(this).attr('min');
var max = $(this).attr('max');
if(amount >= min && amount <= max){
returnValue = true;
return true;
}
});
return (checkedInputs == 0 || totalInputs == checkedInputs || returnValue );
}
Try:
function filterRange(amount, elem) {
var checkedInputs = $(elem).find("input:checked").length;
var totalInputs = $(elem).find("input").length;
var inRange = false;
$(elem).find("input:checked").each(function () {
var min = $(this).attr('min');
var max = $(this).attr('max');
if (amount >= min && amount <= max) {
inRange = true;
return false;
}
});
if (checkedInputs == 0 || totalInputs == checkedInputs) {
return true;
}
if (inRange) {
return true;
} else {
return false;
}
}