HTML/Javascript Forms Checkbox Value Not Displaying - javascript

Pretty Straight forward problem.
When the user hits the "add" button and the checkmark is checked I would like the value to say "Smoker" in the class="household".
When the checkmark is not checked I would like the value to say "Non-smoker"
Currently, my "if else" statement isn't firing. Been looking everywhere to fix this. Can anyone help?
Side Note: No jQuery, Cannot edit the HTML. Only Pure Javascript.
HTML
<ol class="household"></ol>
<form>
<div>
<label>Age
<input type="text" name="age">
</label>
</div>
<div>
<label>Relationship
<select name="rel">
<option value="">---</option>
<option value="self">Self</option>
<option value="spouse">Spouse</option>
<option value="child">Child</option>
<option value="parent">Parent</option>
<option value="grandparent">Grandparent</option>
<option value="other">Other</option>
</select>
</label>
</div>
<div>
<label>Smoker?
<input type="checkbox" name="smoker">
</label>
</div>
<div>
<button class="add">add</button>
</div>
<div>
<button type="submit">submit</button>
</div>
</form>
JS
function validate(form) {
fail = validateAge(form.age.value)
fail += validateRel(form.rel.value)
if (fail == "") return true
else {
alert(fail);
return false
}
}
function validateAge(field) {
if (isNaN(field)) return "No age was entered. \n"
else if (field < 1 || field > 200)
return "Age must be greater than 0. \n"
return ""
}
function validateRel(field) {
if (field == "") return "Please select a relationship \n"
return ""
}
document.querySelector("form").onsubmit = function() {
return validate(this)
}
document.querySelector(".add").onclick = function(event) {
event.preventDefault();
createinput()
}
count = 0;
function createinput() {
field_area = document.querySelector('.household')
var li = document.createElement("li");
var p1 = document.createElement("p");
var p2 = document.createElement("p");
var p3 = document.createElement("p");
var x = document.getElementsByName("age")[0].value;
var y = document.getElementsByName("rel")[0].value;
var z = document.getElementsByName("smoker")[0].value.checked;
if( z === undefined) {
return ("Non smoker \n")
}
else {
return ("Smoker \n")
}
p1.innerHTML = x;
p2.innerHTML = y;
p3.innerHTML = z;
li.appendChild(p1);
li.appendChild(p2);
li.appendChild(p3);
field_area.appendChild(li);
//removal link
var removalLink = document.createElement('a');
removalLink.onclick = function() {
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode('Remove Field');
removalLink.appendChild(removalText);
li.appendChild(removalLink);
count++
}

The first problem is you are not getting the checkbox status right way. It should be document.getElementsByName("smoker")[0].checked instead of document.getElementsByName("smoker")[0].value.checked.
The second problem is you used return in if else. If you use return then the following codes of the function will not execute.
Change
var z = document.getElementsByName("smoker")[0].value.checked;
if( z === undefined) {
return ("Non smoker \n")
}
else {
return ("Smoker \n")
}
to
var z = document.getElementsByName("smoker")[0].checked;
if (!z) {
z = "Non smoker \n";
} else {
z = "Smoker \n";
}

Because you have only one "household" element you can add the following handler:
document.querySelectorAll('[name="smoker"]')[0].onclick = function() {
document.getElementsByClassName('household')[0].textContent =
this.checked ? 'Smoker' : 'Non-smoker';
}
The example:
function validate(form) {
fail = validateAge(form.age.value)
fail += validateRel(form.rel.value)
if (fail == "") return true
else {
alert(fail);
return false
}
}
function validateAge(field) {
if (isNaN(field)) return "No age was entered. \n"
else if (field < 1 || field > 200)
return "Age must be greater than 0. \n"
return ""
}
function validateRel(field) {
if (field == "") return "Please select a relationship \n"
return ""
}
count = 0;
function createinput() {
field_area = document.querySelector('.household')
var li = document.createElement("li");
var p1 = document.createElement("p");
var p2 = document.createElement("p");
var p3 = document.createElement("p");
var x = document.getElementsByName("age")[0].value;
var y = document.getElementsByName("rel")[0].value;
var z = document.getElementsByName("smoker")[0].checked;
if( !z ) {
z = "Non smoker";
}
else {
z = "Smoker";
}
p1.innerHTML = x;
p2.innerHTML = y;
p3.innerHTML = z;
li.appendChild(p1);
li.appendChild(p2);
li.appendChild(p3);
field_area.appendChild(li);
//removal link
var removalLink = document.createElement('a');
removalLink.onclick = function() {
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode('Remove Field');
removalLink.appendChild(removalText);
li.appendChild(removalLink);
count++
}
document.querySelector("form").onsubmit = function() {
return validate(this)
}
document.querySelector(".add").onclick = function(event) {
event.preventDefault();
createinput()
}
document.querySelectorAll('[name="smoker"]')[0].onclick = function() {
document.getElementsByClassName('household')[0].textContent = this.checked ? 'Smoker' : 'Non-smoker'
}
<ol class="household"></ol>
<form>
<div>
<label>Age
<input type="text" name="age">
</label>
</div>
<div>
<label>Relationship
<select name="rel">
<option value="">---</option>
<option value="self">Self</option>
<option value="spouse">Spouse</option>
<option value="child">Child</option>
<option value="parent">Parent</option>
<option value="grandparent">Grandparent</option>
<option value="other">Other</option>
</select>
</label>
</div>
<div>
<label>Smoker?
<input type="checkbox" name="smoker">
</label>
</div>
<div>
<button class="add">add</button>
</div>
<div>
<button type="submit">submit</button>
</div>
</form>

Related

calculator does not work properly on mobile devices

I've been trying to solve this for hours and I can't.
The problem is when you try to erase the numbers entered.
You have to first select the two fields and enter the dollar amount in the third field. Then enter a value in the first field.
On the computer it works normally, but on some cell phones it is not working properly.
On some iphone using safary in the latest version it works. Already on some android devices with Google no. I didn't check the browser version, but I tried it on newer and older phones. Some new ones give a problem and some don't, as well as old ones.
This code was not developed by me, it is a little old and uses a template language called Freemarker. Don't care too much about this language, it's used to get data from the form and insert it into the html code.
There's a link for you to access and test. This page contains two calculators, it is the first one that is giving problems. I'll post a print of it.
URL: https://www.smiles.com.br/p123kby0ocxqaelzcgszc9x6hsmwt59wbrftzbr5ovtgngq7cy
Print:
Code:
<#assign
moduloSimulador = simulador_cobranded_separator
itemSimulador = moduloSimulador.getChild("item_simulador_separator").getSiblings()
>
<#list itemSimulador as cur_item>
<#assign
imagemItem = cur_item.getChild("imagem_item").getData()
textoImportanteItem = cur_item.getChild("texto_importante_item").getData()
>
<div data-simulador-mod021 class="canta-mod021-simulador">
<div>
<div>
<#if imagemItem?has_content>
<img src="${imagemItem}" alt="Imagem Simulador" />
</#if>
</div>
<div>
<div class="content-input">
<label for="lblSeg">Assinante Clube Smiles</label>
<select data-mod021-assinante id="lblSeg">
<option value="">Escolha</option>
<option value="sim">Sim</option>
<option value="nao">Não</option>
</select>
</div>
</div>
<div>
<div class="content-input">
<label for="lblCart">Tipo de Cartão</label>
<select data-mod021-cartao id="lblCart">
<option value="">Escolha</option>
<option value="infinite">Infinite</option>
<option value="platinum">Platinum</option>
<option value="gold">Gold</option>
<option value="inter">Inter</option>
</select>
</div>
</div>
<div class="break-sm"></div>
<div>
<div class="content-input rs">
<label for="lblValorGasto">Valor gasto no cartão</label>
<input value="0" min="1" maxlength="12" data-mod021-valor class="style2" type="text" id="lblValorGasto" placeholder="0" />
</div>
</div>
<div>
<div class="content-input">
<label for="lblConversor">Conversor</label>
<input data-mod021-conversor readonly class="style2" type="text" id="lblConversor" placeholder="0" />
</div>
</div>
<div>
<div class="content-input rs">
<label for="lblDolar">Cotação do Dólar</label>
<input value="0" min="1" maxlength="5" data-mod021-cotacao class="style2" type="text" id="lblDolar" placeholder="0" />
</div>
</div>
<div class="sep">=</div>
<div>
<div class="content-input">
<label for="lblAcumulo">Acúmulo</label>
<input data-mod021-acumulo readonly class="style2" type="text" id="lblAcumulo" placeholder="0" />
</div>
</div>
</div>
<p class="p-jur">
${textoImportanteItem}
</p>
</div>
</#list>
<script>
(function(window) {
"use strict";
let $items = document.querySelectorAll("[data-simulador-mod021]");
if ($items.length > 0) {
for (let a = 0; a < $items.length; a++) {
engine($items[a]);
}
}
function isValidKey(key) {
if (
(key >= 49 && key <= 57) ||
(key >= 97 && key <= 105) ||
key == 8 ||
((key == 48 || key == 96) &&
milesInput.value !== '' &&
milesInput.value !== '0')
) {
return true;
}
}
//mascara de valor
function mascaraValor(valor) {
valor = valor.toString().replace(/\D/g, "");
valor = valor.toString().replace(/(\d)(\d{9})$/, "$1.$2");
valor = valor.toString().replace(/(\d)(\d{6})$/, "$1.$2");
valor = valor.toString().replace(/(\d)(\d{3})$/, "$1.$2");
return valor;
}
function getValorMoneyBr(valor) {
let value = valor
.toFixed(2)
.toString()
.split(".");
let formatFirstPart = mascaraValor(value[0]);
let formatSecondPart = "," + value[1];
let formatedValue = formatFirstPart + formatSecondPart;
return formatedValue.toString();
}
//mascara de mordas
function moeda(v) {
v = v.toString().replace(/\D/g, ""); //permite digitar apenas números
v = v.toString().replace(/[0-9]{12}/, "inválido"); //limita pra máximo 999.999.999,99
//v = v.toString().replace(/(\d{1})(\d{8})$/, "$1.$2"); //coloca ponto antes dos últimos 8 digitos
//v = v.toString().replace(/(\d{1})(\d{1,2})$/, "$1.$2"); //coloca ponto antes dos últimos 5 digitos
v = v.toString().replace(/(\d{1})(\d{1,2})$/g, "$1,$2"); //coloca virgula antes dos últimos 2 digitos
return v.toString();
}
//define o valor do conversor
function changeConversor(c, a) {
let valueConversor = "";
let cartao = c.value;
let assinante = a.value;
if (cartao && assinante) {
if (cartao === "infinite") {
if (assinante === "sim") {
valueConversor = 4;
} else {
valueConversor = 2.2;
}
} else if (cartao === "platinum") {
if (assinante === "sim") {
valueConversor = 3;
} else {
valueConversor = 2;
}
} else if (cartao === "gold") {
if (assinante === "sim") {
valueConversor = 2.5;
} else {
valueConversor = 1.5;
}
} else {
if (assinante === "sim") {
valueConversor = 2;
} else {
valueConversor = 1.35;
}
}
return valueConversor;
} else return "";
}
function engine(item) {
let assinante = item.querySelector("[data-mod021-assinante]");
let cartao = item.querySelector("[data-mod021-cartao]");
let valor = item.querySelector("[data-mod021-valor]");
let conversor = item.querySelector("[data-mod021-conversor]");
let cotacao = item.querySelector("[data-mod021-cotacao]");
let acumulo = item.querySelector("[data-mod021-acumulo]");
let conversorValor = "";
function calc() {
let nValor = valor.value.toString().replace(/(\D)/g, "");
let nCotacao = moeda(cotacao.value);
nCotacao = nCotacao.replace(",", ".");
nCotacao = parseFloat(nCotacao);
let nConversor = parseFloat(conversor.value.toString().replace(",", "."));
if (nValor <= 0 || nCotacao <= 0) {
valor.value = "";
cotacao.value = "";
acumulo.value = "";
} else {
let v = (nValor / nCotacao) * nConversor;
// acumulo.value = getValorMoneyBr(v);
acumulo.value = Math.round(v);
}
}
valor.addEventListener("keyup", function(event) {
if(!event.keyCode) return;
let v = this.value;
valor.value = mascaraValor(v);
if (valor.value && conversor.value && cotacao.value) {
calc();
}
});
cotacao.addEventListener("keyup", function() {
if(!(event.keyCode)) return;
if (valor.value && conversor.value && cotacao.value) {
calc();
}
});
cotacao.addEventListener("keyup", function() {
if(!event.keyCode) return;
let v = this.value;
cotacao.value = moeda(v);
});
//define valor conversor
if (assinante && cartao) {
cartao.addEventListener("change", function() {
conversorValor = changeConversor(cartao, assinante);
conversor.value = conversorValor.toString().replace(".", ",");
valor.value = "";
cotacao.value = "";
acumulo.value = "";
});
assinante.addEventListener("change", function() {
conversorValor = changeConversor(cartao, assinante);
conversor.value = conversorValor.toString().replace(".", ",");
valor.value = "";
cotacao.value = "";
acumulo.value = "";
});
}
}
})(window);
</script>

Using Conditionals in JavaScript to print a message in HTML

I created a calculator using HTML and JavaScipt. The calculator works, so that is fine. However, I would like to write a message in the html that lets the user know they have to enter a variable, if the result is NaN. While I know I need to use a conditional statement, I am not sure how to code it.
Here is my code:
function calc(){
var n1 = parseFloat(document.getElementById("n1").value);
var n2 = parseFloat(document.getElementById("n2").value);
var oper = document.getElementById("operators").value;
if( oper === "+"){
document.getElementById("result").value = n1+n2;
}
if( oper === "-"){
document.getElementById("result").value = n1-n2;
}
if( oper === "*"){
document.getElementById("result").value = n1*n2;
}
if( oper === "/"){
document.getElementById("result").value = n1/n2;
}
if( oper === NaN ){
document.getElementById("Comments").innerHTML= "Write something in the boxes, you silly ass." ;
}
}
<input type="text" id="n1"/><br/><br/>
<input type="text" id="n2"/><br/><br>
<select id="operators">
<option value="+">+</option>
<option value="-">-</option>
<option value="X">X</option>
<option value="/">/</option>
</select>
<input type="text" id="result"/>
<button onclick="calc();">=</button>
<p id="Comments"></p>
To improve your code you can add else if and isNaN, like this:
function calc(){
var n1 = parseFloat(document.getElementById("n1").value);
var n2 = parseFloat(document.getElementById("n2").value);
var oper = document.getElementById("operators").value;
if( oper === "+"){
document.getElementById("result").value = n1+n2;
} else if( oper === "-"){
document.getElementById("result").value = n1-n2;
} else if( oper === "*"){
document.getElementById("result").value = n1*n2;
} else if( oper === "/"){
document.getElementById("result").value = n1/n2;
} else if( isNaN(oper) ){
document.getElementById("Comments").innerHTML= "Write something in the boxes, you silly ass." ;
}
}
<input type="text" id="n1"/><br/><br/>
<input type="text" id="n2"/><br/><br>
<select id="operators">
<option value="+">+</option>
<option value="-">-</option>
<option value="X">X</option>
<option value="/">/</option>
</select>
<input type="text" id="result"/>
<button onclick="calc();">=</button>
<p id="Comments"></p>
Use the isNaN function to check for it
function calc(){
var n1 = parseFloat(document.getElementById("n1").value);
var n2 = parseFloat(document.getElementById("n2").value);
var oper = document.getElementById("operators").value;
if( oper === "+"){
document.getElementById("result").value = n1+n2;
}
if( oper === "-"){
document.getElementById("result").value = n1-n2;
}
if( oper === "*"){
document.getElementById("result").value = n1*n2;
}
if( oper === "/"){
document.getElementById("result").value = n1/n2;
}
if( isNaN(oper) ){
document.getElementById("Comments").innerHTML= "Write something in the boxes, you silly ass." ;
}
}
<input type="text" id="n1"/><br/><br/>
<input type="text" id="n2"/><br/><br>
<select id="operators">
<option value="+">+</option>
<option value="-">-</option>
<option value="X">X</option>
<option value="/">/</option>
</select>
<input type="text" id="result"/>
<button onclick="calc();">=</button>
<p id="Comments"></p>
I'll provide this as a more concise version. There's no reason to select an element more than once if you plan on altering it later. Using the object as a container for your options allows you to validate and execute a bit easier.
const options = {
'+'(a, b) { return a + b },
'-'(a, b) { return a - b },
'*'(a, b) { return a * b },
'/'(a, b) { return a / b }
};
function calc(){
var n1 = parseFloat(document.getElementById("n1").value);
var n2 = parseFloat(document.getElementById("n2").value);
var oper = document.getElementById("operators").value;
const resEl = document.getElementById("result");
resEl.value = '';
const comEl = document.getElementById("Comments");
comEl.innerHTML = '';
let result;
let targetEl;
if (isNaN(n1) || isNaN(n2)) {
targetEl = comEl;
result = "Write something valid in the boxes, silly.";
}
else if (options[oper]) {
target = resEl;
result = options[oper](n1, n2);
}
else {
targetEl = comEl;
result = "Pick an operation." ;
}
let prop = typeof result === 'string' ? 'innerHTML' : 'value';
targetEl[prop] = result;
}

If else statement with string JavaScript

I am designing a page where can display score when the users make their choices.
However, this code seems not working and does not show any result in the 'score' field.
My Html code:
<tr>
<td>
<div>
<input list="typeList" name="type" id="type">
<datalist id="typeList">
<option value="basketball">
<option value="soccer">
<option value="table tenis">
</datalist>
</div>
</td>
<td><input type="text" id="score" name="score" autocomplete="off"></td>
</tr>
My Script is below:
var type = document.getElementById("type");
var score = document.getElementById("score");
if (type === 0) {
score.value = 0;
} else if (type === 'basketball') {
score.value = 1;
} else if (type === 'soccer') {
score.value = 2;
} else if (type === 'table tenis') {
score.value = 3;
}
I have used Jquery in this, The mistake you made is, there is no watch for the event.
$('#type').on('input',function(e){
var type = document.getElementById("type").value;
var score = document.getElementById("score");
if (type === 0) { score.value = 0; }
else if (type === 'basketball') { score.value = 1; }
else if (type === 'soccer') { score.value = 2; }
else if (type === 'table tenis') { score.value = 3; }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td>
<div>
<input list="typeList" name="type" id="type">
<datalist id="typeList">
<option value="basketball">
<option value="soccer">
<option value="table tenis">
</datalist>
</div>
</td>
<td><input type="text" id="score" name="score" autocomplete="off"></td>
</tr>
Hope this helps
var type = document.getElementById("type");
//...
here should be var type = document.getElementById("type").value;
and also
if (type === 0) {
to
if (type === "0") {
You were able to access the element. You just need to use the value attribute of the element. You need to add the event change with dropdown so that it can bind the data in the score textbox when index is changed.
var type = document.getElementById("type");
var score = document.getElementById("score");
type.addEventListener('change', function() {
if (type.value === 0) {
score.value = 0;
} else if (type.value === 'basketball') {
score.value = 1;
} else if (type.value === 'soccer') {
score.value = 2;
} else if (type.value === 'table tennis') {
score.value = 3;
}
});
<tr>
<td>
<div>
<input list="typeList" name="type" id="type">
<datalist id="typeList">
<option value="basketball">
<option value="soccer">
<option value="table tennis">
</datalist>
</div>
</td>
<td><input type="text" id="score" name="score" autocomplete="off" ></td>
</tr>
You need to add a event listener (or two, one for change and one for input) and then wrap your code in a function:
var type = document.getElementById("type");
var score = document.getElementById("score");
type.addEventListener("change", function() {
myFunction(type.value);
});
type.addEventListener("input", function() {
myFunction(type.value);
});
var myFunction = function(type) {
if (type === 0) {
score.value = 0;
} else if (type === 'basketball') {
score.value = 1;
} else if (type === 'soccer') {
score.value = 2;
} else if (type === 'table tenis') {
score.value = 3;
}
}
<tr>
<td>
<div>
<input list="typeList" name="type" id="type">
<datalist id="typeList">
<option value="basketball">
<option value="soccer">
<option value="table tenis">
</datalist>
</div>
</td>
<td><input type="text" id="score" name="score" autocomplete="off"></td>
</tr>
in your if it should be
type.value
to get the value of the input box. Also when are you running the script?
// you forgot to attach the value property of the type element
var typeValue = document.getElementById("type").value;
// the result for typeValue is allways a string or undefined
var scoreElement = document.getElementById("score");
// a swtich case is more efficient here
swtich(typeValue){
case 'basketball':
scoreElement.value = 1;
break;
case 'soccer':
scoreElement.value = 2:
break;
case 'table tenis'
scoreElement.value = 3;
break;
default:
sourceElement.value = 0;
}
Here you go with pure JavaScript along with jsfiddle https://jsfiddle.net/4oyrw61w/
document.getElementById('type').addEventListener('input', function () {
var type = document.getElementById("type").value;
var score = document.getElementById("score");
if (type === '0') {
score.value = 0;
} else if (type === 'basketball') {
score.value = 1;
} else if (type === 'soccer') {
score.value = 2;
} else if (type === 'table tenis') {
score.value = 3;
}
});

HTML/Javascript Form How do I serialize form data as JSON and displayed in a class?

Pretty straight forward.
When a user clicks "submit", I need the form serialized and the JSON data displayed in the class"debug".
How do I do this with my current Javascript?
Cannot use jQuery. Cannot edit HTML. Only pure Javascript.
Thanks!
HTML
<ol class="household"></ol>
<form>
<div>
<label>Age
<input type="text" name="age">
</label>
</div>
<div>
<label>Relationship
<select name="rel">
<option value="">---</option>
<option value="self">Self</option>
<option value="spouse">Spouse</option>
<option value="child">Child</option>
<option value="parent">Parent</option>
<option value="grandparent">Grandparent</option>
<option value="other">Other</option>
</select>
</label>
</div>
<div>
<label>Smoker?
<input type="checkbox" name="smoker">
</label>
</div>
<div>
<button class="add">add</button>
</div>
<div>
<button type="submit">submit</button>
</div>
</form>
</div>
<pre class="debug"></pre>
JS
function validate(form) {
fail = validateAge(form.age.value)
fail += validateRel(form.rel.value)
if (fail == "") return true
else {
alert(fail);
return false
}
}
function validateAge(field) {
if (isNaN(field)) return "No age was entered. \n"
else if (field < 1 || field > 200)
return "Age must be greater than 0. \n"
return ""
}
function validateRel(field) {
if (field == "") return "Please select a relationship \n"
return ""
}
document.querySelector("form").onsubmit = function() {
return validate(this)
}
document.querySelector(".add").onclick = function(event) {
event.preventDefault();
createinput()
}
count = 0;
function createinput() {
field_area = document.querySelector('.household')
var li = document.createElement("li");
var p1 = document.createElement("p");
var p2 = document.createElement("p");
var p3 = document.createElement("p");
var x = document.getElementsByName("age")[0].value;
var y = document.getElementsByName("rel")[0].value;
var z = document.getElementsByName("smoker")[0].checked;
if (!z) {
z = "Non smoker \n";
} else {
z = "Smoker \n";
}
p1.innerHTML = x;
p2.innerHTML = y;
p3.innerHTML = z;
li.appendChild(p1);
li.appendChild(p2);
li.appendChild(p3);
field_area.appendChild(li);
//removal link
var removalLink = document.createElement('a');
removalLink.onclick = function() {
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode('Remove Field');
removalLink.appendChild(removalText);
li.appendChild(removalLink);
count++
}
// serialize form
var data = {};
var inputs = [].slice.call(e.target.querySelector('form'));
inputs.forEach(input => {
data[input.name] = input.value;
});
The shortest possible solution (pure javascript):
var form = document.querySelector('form');
var data = new FormData(form);
docs: https://developer.mozilla.org/en-US/docs/Web/API/FormData
I know this form very well as I applied for same job position.It is an interesting task. Here is your answer with pure js!
var peopleList = [];
var addButton = document.querySelector('button.add');
var submitButton = document.querySelector('button[type=submit]');
var debug = document.querySelector('pre.debug');
var mainForm = document.forms[0];
var ageFormField = mainForm.age;
var relationshipFormField = mainForm.rel;
var smokerFormField = mainForm.smoker;
var positionFormField=mainForm.position;
//Taken from https://www.inventpartners.com/open-source/free-web-software/javascript_is_int
function is_int(value) {
if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
return true;
} else {
return false;
}
}
function formIsValid() {
return ageFormField.value != '' && is_int(ageFormField.value) && relationshipFormField.selectedIndex != 0 && positionFormField.value !='';
}
function updateDebug() {
if (peopleList.length != 0) {
debug.innerText = JSON.stringify(peopleList);
debug.setAttribute('style', 'display: block');
submitButton.disabled = false;
} else {
debug.innerText = '';
debug.removeAttribute('style');
submitButton.disabled = true;
}
}
function addEventClick(event) {
event.preventDefault();
if (formIsValid()) {
peopleList.push({
'age': ageFormField.value,
'position':positionFormField.value,
'relationship': relationshipFormField.options[relationshipFormField.selectedIndex].value,
'isSmoker': smokerFormField.checked,
});
updateDebug();
ageFormField.value = '';
positionFormField.value='';
relationshipFormField.selectedIndex = 0;
smokerFormField.checked = false;
} else {
var errors = '';
if (ageFormField.value == '') {
errors += 'Please enter your age!';
} else if (!is_int(ageFormField.value)) {
errors += 'Age must be a numeric value!';
}
if (relationshipFormField.selectedIndex == 0) {
if (errors != '') {
errors += '\n';
}
errors += 'Please select your relationship status!';
}
if (positionFormField.value == '') {
if (errors != '') {
errors += '\n';
}
errors += 'Please enter your position!';
}
if (errors != '') {
alert(errors);
errors = '';
}
else if (
errors != '') {
alert(errors);
errors = '';
}
}
}
function submitEventClick(event) {
event.preventDefault();
if (peopleList.length != 0) {
var http = new XMLHttpRequest();
var url = "savePeopleList.php";
http.open('POST', url, true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {
if (http.readyState == 4) {
if (http.status == 200) {
peopleList = [];
updateDebug();
alert('All of the changes were saved to the server!');
} else {
alert('An error occured while sending the data to the server!');
}
}
};
http.send(JSON.stringify(peopleList));
}
}
addButton.addEventListener('click', addEventClick, false);
submitButton.addEventListener('click', submitEventClick, false);
updateDebug();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Household builder</title>
<style>
.debug {
font-family: monospace;
border: 1px solid black;
padding: 10px;
display: none;
}
</style>
</head>
<body>
<h1>Household builder</h1>
<div class="builder">
<ol class="household"></ol>
<form>
<div>
<label>Age
<input type="text" name="age">
</label>
</div>
<div>
<label>Position
<input type="text" name="position">
</label>
</div>
<div>
<label>Relationship
<select name="rel">
<option value="">---</option>
<option value="self">Self</option>
<option value="spouse">Spouse</option>
<option value="child">Child</option>
<option value="parent">Parent</option>
<option value="grandparent">Grandparent</option>
<option value="other">Other</option>
</select>
</label>
</div>
<div>
<label>Smoker?
<input type="checkbox" name="smoker">
</label>
</div>
<div>
<button class="add">add</button>
</div>
<div>
<button type="submit">submit</button>
</div>
</form>
</div>
<pre class="debug"></pre>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>
Iterate through the form, grabbing the various elements and creating new objects for each one, then setting the properties for each object and pushing to the final array would solve your problem fairly easily.
Then you can simply use querySelectorAll to match .debug and use JSON.stringify() to convert your array to a string and innerText to set the contents.
Example:
function go() {
var debug_class = document.querySelectorAll(".debug");
for (var i = 0; i < debug_class.length; i++) {
var element = debug_class[i];
element.innerText = JSON.stringify(serializeArray(document.querySelector("form")));
}
}
function serializeArray(form) {
var field, l, s = [];
if (typeof form == 'object' && form.nodeName == "FORM") {
var len = form.elements.length;
for (i = 0; i < len; i++) {
field = form.elements[i];
if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
if (field.type == 'select-multiple') {
l = form.elements[i].options.length;
for (j = 0; j < l; j++) {
if (field.options[j].selected)
s[s.length] = {
name: field.name,
value: field.options[j].value
};
}
} else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
s[s.length] = {
name: field.name,
value: field.value
};
}
}
}
}
return s;
}
<form id="blah">
<input type="text" name="input1" value="a"></input>
<input type="text" name="input2" value="b"></input>
<input type="text" name="input3" value="c"></input>
<input type="text" name="input4" value="d"></input>
</form>
<button onclick="go()">Serialize!</button>
<div class="debug"></div>
EDIT
In your particular case, after including the above code, you would have to call go() at some point to generate the serialized data.
Here's how to do it after clicking on add
document.querySelector(".add").onclick = function(event) {
go(); // display in .debug
event.preventDefault();
createinput()
}
FULL SNIPPET
function go() {
var debug_class = document.querySelectorAll(".debug");
for (var i = 0; i < debug_class.length; i++) {
var element = debug_class[i];
element.innerText = JSON.stringify(serializeArray(document.querySelector("form")));
}
}
function serializeArray(form) {
var field, l, s = [];
if (typeof form == 'object' && form.nodeName == "FORM") {
var len = form.elements.length;
for (i = 0; i < len; i++) {
field = form.elements[i];
if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
if (field.type == 'select-multiple') {
l = form.elements[i].options.length;
for (j = 0; j < l; j++) {
if (field.options[j].selected)
s[s.length] = {
name: field.name,
value: field.options[j].value
};
}
} else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
s[s.length] = {
name: field.name,
value: field.value
};
}
}
}
}
return s;
}
function validate(form) {
fail = validateAge(form.age.value)
fail += validateRel(form.rel.value)
if (fail == "") return true
else {
alert(fail);
return false
}
go();
}
function validateAge(field) {
if (isNaN(field)) return "No age was entered. \n"
else if (field < 1 || field > 200)
return "Age must be greater than 0. \n"
return ""
}
function validateRel(field) {
if (field == "") return "Please select a relationship \n"
return ""
}
document.querySelector("form").onsubmit = function() {
return validate(this)
}
document.querySelector(".add").onclick = function(event) {
go();
event.preventDefault();
createinput()
}
count = 0;
function createinput() {
field_area = document.querySelector('.household')
var li = document.createElement("li");
var p1 = document.createElement("p");
var p2 = document.createElement("p");
var p3 = document.createElement("p");
var x = document.getElementsByName("age")[0].value;
var y = document.getElementsByName("rel")[0].value;
var z = document.getElementsByName("smoker")[0].checked;
if (!z) {
z = "Non smoker \n";
} else {
z = "Smoker \n";
}
p1.innerHTML = x;
p2.innerHTML = y;
p3.innerHTML = z;
li.appendChild(p1);
li.appendChild(p2);
li.appendChild(p3);
field_area.appendChild(li);
//removal link
var removalLink = document.createElement('a');
removalLink.onclick = function() {
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode('Remove Field');
removalLink.appendChild(removalText);
li.appendChild(removalLink);
count++
}
// serialize form
var data = {};
var inputs = [].slice.call(e.target.querySelector('form'));
inputs.forEach(input => {
data[input.name] = input.value;
});
<ol class="household"></ol>
<form>
<div>
<label>Age
<input type="text" name="age">
</label>
</div>
<div>
<label>Relationship
<select name="rel">
<option value="">---</option>
<option value="self">Self</option>
<option value="spouse">Spouse</option>
<option value="child">Child</option>
<option value="parent">Parent</option>
<option value="grandparent">Grandparent</option>
<option value="other">Other</option>
</select>
</label>
</div>
<div>
<label>Smoker?
<input type="checkbox" name="smoker">
</label>
</div>
<div>
<button class="add">add</button>
</div>
<div>
<button type="submit">submit</button>
</div>
</form>
</div>
<pre class="debug"></pre>

Need guidance with javascript error UnCaught TypeError

I am having trouble with javascript I am using for a register form, I get the UnCaught TypeError: Cannot read property 'value' of null after this line of my javascript:
tf.value = tf.value.replace(rx, "");
and also after this line of javascript:
var m = _("mobileNumber").value.length;
Here is my javascript and form:
<script>
function restrict(elem){
var tf = _(elem);
var rx = new RegExp;
if(elem === "email"){
rx = /[' "]/gi;
} else if(elem === "username"){
rx = /^[a-z0-9]i*$/;
} else if(elem === "mobileNumber"){
rx = /^[0-9]*$/;
}
tf.value = tf.value.replace(rx, "");
}
function emptyElement(x){
_(x).innerHTML = "";
}
function checkusername(){
var u = _("username").value;
if(u !== ""){
("unamestatus").innerHTML = 'checking ...';
var ajax = ajaxObj("POST", "signup.php");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) === true) {
("unamestatus").innerHTML = ajax.responseText;
}
};
ajax.send("usernamecheck="+u);
}
}
function signup(){
var u = _("username").value;
var e = _("email").value;
var m = _("mobileNumber").value.length;
var p1 = _("pass1").value;
var p2 = _("pass2").value;
var ci = _("city").value;
var pc = _("postcode").value;
var c = _("country").value;
var d = _("dateOfBirth").value;
var g = _("gender").value;
var status = _("status");
if(u === "" || e === "" || p1 === "" || p2 === "" || c === ""
|| g === "" || m === "" || ci === "" || pc === "" || d === "" ){
status.innerHTML = "Fill out required fields";
} else if(p1 !== p2){
status.innerHTML = "Your password fields do not match";
}else if(m !== 11 && !IsNumeric(m)){
status.innerHTML = "Please enter valid mobile number";
}else if(d === "dd/mm/yyyy"){
status.innerHTML = "Please enter your date of birth";
} else {
//ajax to send form data to php
//hides sign button
_("signupbtn").style.display = "none";
status.innerHTML = 'please wait ...';
//wait until php verifies data
var ajax = ajaxObj("POST", "signup.php");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) === true) {
//if sign not succesful unhide button
if(ajax.responseText !== "signup_success"){
status.innerHTML = ajax.responseText;
_("signupbtn").style.display = "block";
} else {
FUNCTION
function _(x){
return document.getElementById(x);
}
FORM
<form name="signupform" id="signupform" onsubmit="return false;">
<div>Username: </div>
<input id="username" type="text" onblur="checkusername()" onkeyup="restrict('username')" maxlength="16">
<span id="unamestatus"></span>
<div>Email Address:</div>
<input id="email" type="email" onfocus="emptyElement('status')" onkeyup="restrict('email')" maxlength="88">
<div>Create Password:</div>
<input id="pass1" type="password" onfocus="emptyElement('status')" maxlength="16">
<div>Confirm Password:</div>
<input id="pass2" type="password" onfocus="emptyElement('status')" maxlength="16">
<div>First name:</div>
<input id="firstName" type="text" /><br />
<div>Last name:</div>
<input id="lastName" type="text" /><br />
<div>Mobile number*:</div>
<input name="mobileNumber" onfocus="emptyElement('status')" onkeyup="restrict('mobileNumber')" maxlength="16">
<div>Gender:</div>
<select id="gender" onfocus="emptyElement('status')">
<option value=""></option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
<div>Country:</div>
<select id="country" onfocus="emptyElement('status')">
<?php include_once("country_list.php"); ?>
</select>
<div>City:</div>
<input id="city" onfocus="emptyElement('status')">
<div>Postcode:</div>
<input id="postcode" onfocus="emptyElement('status')">
<div>Relationship Status*:</div>
<select id="relationshipStatus" >
<option value=""></option>
<option value="Single">Single</option>
<option value="Taken">Taken</option>
</select>
<div>Date of Birth*:</div>
<input id="dateOfBirth" type="date" onfocus="emptyElement('status')">
<button id="signupbtn" onclick="signup()">Create Account</button>
<span id="status"></span>
</form>
In the first case, tf variable is null. Since you set the variable only when declaring it, it means that _(elem) return null.
In the second case, the function call _("mobileNumber") return null.
It's to possible to tell more if you don't post the _ function

Categories

Resources