I was making a password generator while learning javascript. Is there a way to call the checked radio button using a value or do I switch to getElementbyId while calling.
My HTML body-
<div class="container">
<p>Please select the type of Password you want to generate:</p>
<form id="new-form">
<input type="radio" id="wp" name="radio" class="redio" value="0" />
<label for="wp">Weak Password</label><br />
<input type="radio" id="sp" name="radio" class="redio" value="1" />
<label for="sp">Strong Password</label><br />
<input type="radio" id="ssp" name="radio" class="redio" value="2" />
<label for="ssp">Super Strong Password</label>
<br />
<input type="submit" id="btn" value="Generate Password" />
</form>
<div id="display" type="text" readonly="true"></div>
</div>
My javascript-
class password{
constructor(){
this.ucl="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
this.lcl="abcdefghijklmnopqrstuvwxyz"
this.num="1234567890"
this.spc = "!##$%^&*()"
}
weakpassword(){
let arr = [this.ucl, this.lcl]
let pass = ""
for(let i=0;i<8;i++){
let random1= Math.floor(Math.random()*arr.length)
let random2= Math.floor(Math.random()*arr[random1].length)
pass= pass + arr[random1][random2]
}
return pass
}
strongpassword(){
let arr = [this.ucl, this.lcl, this.num]
let pass = ""
for(let i=0;i<14;i++){
let random1= Math.floor(Math.random()*arr.length)
let random2= Math.floor(Math.random()*arr[random1].length)
pass= pass + arr[random1][random2]
}
return pass
}
superstrongpassword(){
let arr = [this.ucl, this.lcl, this.num, this.spc]
let pass = ""
for(let i=0;i<20;i++){
let random1= Math.floor(Math.random()*arr.length)
let random2= Math.floor(Math.random()*arr[random1].length)
pass= pass + arr[random1][random2]
}
return pass
}
}
let display = document.getElementById("display");
let btn = document.getElementById("btn");
let radio = document.getElementsByClassName("redio");
let a = new password()
btn.addEventListener("click",()=>{
let b;
// if(document.getElementById('wp').checked){
// b= a.weakpassword()
// }
if(radio[0].checked){
b= a.weakpassword()
}
else if(radio[1].checked){
b= a.strongpassword()
}
else if(radio[2].checked){
b= a.superstrongpassword()
}
display.value= b
})
Here, I am getting an error-
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
I'm trying to call the checked radio option value but getting an error 'Cannot read properties of null'.
Related
I want to make a Calculator in JS. I'm new to JS and I don't get it why it isn't working. In the Browser Console I get undefined if I call add().
getInputAsNumber(...) should retrieves the input value from the field with the ID passed as Parameter
writeResult() writes the calculated result to the output field and is used in all operations
"use strict";
function add() {
let operator1;
let operator2;
getInputAsNumber(operator1, operator2);
let summe = operator1 + operator2;
writeResult(summe);
}
function getInputAsNumber(op1, op2) {
op1 = document.getElementById("op1").value;
op2 = document.getElementById("op2").value;
}
function writeResult(result) {
let outputElement = document.getElementById("output1");
outputElement.innerHTML = Number.result;
}
<form>
<h1>Calculator with Buttons</h1>
<label>Operand 1:</label>
<input id="op1" type="number">
<br>
<br>
<label>Operand 2:</label>
<input id="op2" type="number">
<br>
<br>
<label>Operators: </label>
<button>+</button>
<button>-</button>
<button>*</button>
<button>/</button>
<br>
<br>
<div id="result">
<label>Result: </label>
<output id="output1"></output>
</div>
</form>
You are passing op1 and op2 as a referenced parameter, but they are actually called by value (which means, that they aren't changed when changing inside of the function). You get undefined because operator1 and operator2 are only declared (not initialized!).
You can modify your function so that it returns both operators (instead of passing them):
function add() {
let {operator1, operator2} = getInputAsNumber();
let summe = operator1 + operator2;
writeResult(summe);
}
function getInputAsNumber() {
const op1 = document.getElementById("op1").value;
const op2 = document.getElementById("op2").value;
return {operator1: parseFloat(op1), operator2: parseFloat(op2)};
}
function writeResult(result) {
let outputElement = document.getElementById("output1");
outputElement.innerHTML = result;
}
<h1>Calculator with Buttons</h1>
<label>Operand 1:</label>
<input id="op1" type="number">
<br>
<br>
<label>Operand 2:</label>
<input id="op2" type="number">
<br>
<br>
<label>Operators: </label>
<button onClick="add()">+</button>
<button>-</button>
<button>*</button>
<button>/</button>
<br>
<br>
<div id="result">
<label>Result: </label>
<output id="output1"></output>
</div>
This function returns an object consisting of operator1 and 2 and using the object unwrapping (left side of the getInputAsNumber call) you can easily fetch the two values.
Additionally: just reading the values of the input field (.value) retrieves a string (!), adding two strings in JavaScript means concatination ("2" + "2" = "22"), so you need to parse them first.
The main issues I can see with your code is that:
you need to either pass op1 and op2 more directly, or [as below] set them globally so that they don't need to be passed at all
you can just use result, not Number.result [why the Number. in the first place?]
you might need to parse the inputs from string to number using parseInt
Then, if you add onclick attributes to your buttons or use enventListener, you can make the calculator work fully
"use strict";
var operator1;
var operator2;
function calcOp(operator) {
getInputAsNumber();
var op;
if (operator == 'add') {
writeResult(operator1 + operator2);
} else if (operator == 'sub') {
writeResult(operator1 - operator2);
} else if (operator == 'mul') {
writeResult(operator1 * operator2);
} else if (operator == 'div') {
writeResult(operator1 / operator2);
}
}
function getInputAsNumber() {
operator1 = parseInt(document.getElementById("op1").value);
operator2 = parseInt(document.getElementById("op2").value);
}
function writeResult(result) {
let outputElement = document.getElementById("output1x");
outputElement.value = result;
}
<h1>Calculator with Buttons</h1>
<label>Operand 1:</label>
<input id="op1" type="number">
<br>
<br>
<label>Operand 2:</label>
<input id="op2" type="number">
<br>
<br>
<label>Operators: </label>
<button onclick="calcOp('add');">+</button>
<button onclick="calcOp('sub');">-</button>
<button onclick="calcOp('mul');">*</button>
<button onclick="calcOp('div');">/</button>
<br>
<br>
<div id="result"><label>Result: </label><output id="output1x"></output></div>
I changed your add function to calcOp because all the operations would have very similar, but if you just wanted to have add :
function add() {
getInputAsNumber();
let summe = operator1 + operator2;
writeResult(summe);
}
[Also, as one of the comments mentioned, if you wrap it as a form the way you did, it will likely disappear after any operation. Just div will look the same and not disappear]
I would like my program to automatically select all checkboxes (Specifically "Side 1, Side 2, Side 3 and Side 4") if the wall_amount input is above 3. How would this be done?
I have tried this on javascript lines 10-12. Thanks
HTML
<label for="wall_amount">Number of Walls</label>
<input type="number" value="1" min="1" max="4" step="1" id="wall_amount" name="wall_amount"></input>
<div>
Please choose where you want the walls placed
<label for="wall_side1">Side 1</label>
<input type="checkbox" id="wall_side1" name="wall_side1"></input>
<div style="display: inlineblock;">
<label for="wall_side2">Side 2</label>
<input type="checkbox" id="wall_side2" name="wall_side2"></input>
<img class="img2" src="images/reference.png" alt="Bouncy Castle">
<label for="wall_side3">Side 3</label>
<input type="checkbox" id="wall_side3" name="wall_side3"></input>
</div>
<label for="wall_side4">Side 4</label>
<input type="checkbox" id="wall_side4" name="wall_side4"></input>
</div>
Javascript
var base_length = Number(document.getElementById("base_length").value);
var base_width = Number(document.getElementById("base_width").value);
var walltype = Number(document.getElementById("walltype").value);
var checkbox_side1 = document.getElementById("wall_side1");
var checkbox_side2 = document.getElementById("wall_side2");
var checkbox_side3 = document.getElementById("wall_side3");
var checkbox_side4 = document.getElementById("wall_side4");
var wall_amount = Number(document.getElementById("wall_amount").value);
$("input:checkbox").click(function() {
let max = $("#wall_amount").val();
var bol = $("input:checkbox:checked").length >= max;
$("input:checkbox").not(":checked").attr("disabled", bol);
});
$("wall_amount").on('keyup', function () {
$('checkbox_side1').prop('checked', +$(this).val() > 3);
});
You can use the function setAttribute to check checkboxes. For example, this code (based on your example) will check your element with the id wall_side1.
checkbox_side1.setAttribute("checked", true)
Anyway, try adding this to your code as a function. Then add a conditional statement that runs the function every time your variable exceeds a certain amount.
I am still relatively new at answering questions so I hope this helps!
const checkboxes = [
"wall_side1",
"wall_side2",
"wall_side3",
"wall_side4"
].map((id) => document.getElementById(id));
const amountInput = document.getElementById("wall_amount");
amountInput.addEventListener("change", (event) => {
const value = parseInt(event.target.value || 0);
if (value === 4) {
checkboxes.forEach(
checkbox => {
checkbox.disabled = true;
checkbox.checked = true;
}
);
} else {
checkboxes.forEach(
checkbox => {
checkbox.disabled = false;
}
);
}
});
is that possible to populate attributes name, value, type from :input or something like jQuery serialize for all kinds of input, and combine the value if there is have multiple name like checkbox and radio choices
the concept like this :
$(this).attr('name');
$(this).attr('type');
$(this).attr('value'); // <--- combine this value when the type is checkbox or radio
i try to populate the attributes using each function :
it work but i still don't know how to combine type
$('.submit').click(function(){
var tipe = {}
var form = {}
$('input[type=text], textarea', '.register').each(function(){
const name = $(this).attr('name');
const value = $(this).val();
const type = $(this).attr('type');
form[name] = value;
tipe[name] = type;
});
$('input[type=checkbox], input[type=radio]', '.register').each(function(){
const name = $(this).attr('name');
const value = $(this).val();
const type = $(this).attr('type');
if(form[name] === undefined) {
form[name] = [value];
tipe[name] = [type];
} else {
form[name].push(value);
}
});
console.log(form);
//console.log(tipe);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="register">
<input type="text" name="full_name">
<textarea name="address"></textarea>
<input type="radio" name="sex" value="male">
<input type="radio" name="sex" value="female">
<input type="checkbox" name="hobies" value="foodball">
<input type="checkbox" name="hobies" value="basketball">
</div>
<input type="button" class="submit" value="Submit">
you can use below logic where you can create one map to store value of each input and append values if input type is of type radio or checkbox
$('.submit').click(function(e){
var formValues = {};
$('.register :input').each(function(){
var name = $(this).attr('name');
var type = $(this).attr('type');
var value = $(this).val();
var inputElement = {};
var valid = true;
if(type == 'radio' || type == 'checkbox') {
valid = $(this).is(':checked');
if(valid) {
if(formValues[name]) {
inputElement = formValues[name];
var preVal = inputElement['value'];
value = preVal + ',' + value;
}
}
}
if(valid) {
inputElement['name'] = name;
inputElement['type'] = type;
inputElement['value'] = value;
formValues[name] = inputElement;
}
});
console.log(formValues);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="register">
<input type="text" name="full_name">
<textarea name="address"></textarea>
<input type="radio" name="sex" value="male">
<input type="radio" name="sex" value="female">
<input type="checkbox" name="hobies" value="foodball">
<input type="checkbox" name="hobies" value="basketball">
</div>
<input type="button" class="submit" value="Submit">
I've got an HTML form that consists of a series of units like this:
<input name="categoryColor[]" />
<input name="categoryName[]" />
Using this jQuery code, I can capture this data and return it in an object like this:
{categoryColor: [array of values],
categoryName: [array of values]}
Here's an example of the code in action:
const getFormDataFromElem = function($elem, options) {
options = options || {};
const vis = options.onlyVisible ? ":visible" : "";
const formInputs = $elem.find(`:input${vis}, [contenteditable=true]${vis}`);
const data = {};
formInputs.each(function() {
const $this = $(this)
const type = $this.attr('type');
const val = type === "checkbox" ? (this.checked ? "1" : "0") :
($this.is('[contenteditable=true]') ? $this.text() : this.value);
const name0 = $this.attr('name');
const doArray = name0 && name0.slice(-2) === "[]";
const name = doArray ? name0.slice(0, -2) : name0;
if (!name || (!options.saveEmpty && !doArray && val === "")) {
return;
}
if (doArray) {
if (data.hasOwnProperty(name)) {
data[name].push(val);
return
}
data[name] = [val];
return;
}
data[name] = val;
});
return data;
};
const data = getFormDataFromElem($('.input'));
$('.output').text(JSON.stringify(data, null, 2));
.output {
font-family: monospace;
white-space: pre;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>Input</h2>
<div class="input">
<input name="categoryName[]" value="phase1"/>
<input name="categoryColor[]" value="red"/>
<input name="categoryName[]" value="phase2"/>
<input name="categoryColor[]" value="green"/>
<input name="categoryName[]" value="phase3"/>
<input name="categoryColor[]" value="blue"/>
</div>
<h2>Output</h2>
<div class="output"></div>
BUT I'd like to be able to write the HTML form units like this
<input name="categories[].color" />
<input name="categories[].name" />
since I really need this data in this form:
{categories: [array of objects],
}
where the objects have the form {name: '<name of category>', color: '<color string>'}.
How would I rewrite my general-purpose form-capturing routine to produce values that are arbitrary arrays and objects?
Following assumes you are able to group each set of inputs that make up one object. Then rather than having to parse names use data attributes on the group container for the main object property name.
Still a bit unclear if this is what you are after but can also modify to suit more specific needs. I realize the names are not unique and not sure if that is an issue or not
const data = {};
$('.input').each(function(i){
const $cont = $(this),
{struct, prop} = $cont.data(),
inputs = $cont.find('input').toArray();
if(struct === 'obj'){
data[prop] = data[prop] || [];
const obj = inputs.reduce((a,c)=>({...a, [c.name]:c.value}),{})
data[prop].push(obj);
}
})
console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="input" data-struct="obj" data-prop="otherCat">
<input name="name" value="phase1" />
<input name="color" value="red" />
</div>
<div class="input" data-struct="obj" data-prop="categories">
<input name="name" value="phase2" />
<input name="color" value="green" />
</div>
<div class="input" data-struct="obj" data-prop="categories">
<input name="name" value="phase3" />
<input name="color" value="blue" />
</div>
i am geting undefined for ans . why? what is wrong?
function submitAnswer()
{
var myForm = document.getElementById('quiz');
var ansVal = myForm.ans.value;
var qnoVal = myForm.qno.value;
alert ("ans=" + ansVal);
alert ("qno = " +qnoVal);
return;
}
<form nam="quiz" id="quiz" >
Yes:
<input type="radio" id="ans" name="ans" value="1" />
<br />No:
<input type="radio" id="ans" name="ans" value="0" />
<input id="qno" type="text" name="qno " value="qqq" />
<input type="button" value="" onClick="submitAnswer(); " />
</form>
Using theForm.inputElement is not standard and can't be guaranteed to work. Instead, you should use document.getElementById, or some other DOM mechanism, to find the input element you want. theForm.elements[name] also works.
You'll also need to fix your element IDs before you can do that - you have two <input type="radio" /> elements with an ID "ans", which is incorrect. IDs must be unique:
<input type="radio" id="ans1" name="ans" value="1" />
<input type="radio" id="ans2" name="ans" value="0" />
<script type="text/javascript">
var ans1 = document.getElementById('ans1');
var ans1value = ans1.value;
</script>
Or, get the radio button group as a single element using elements:
<script type="text/javascript">
var theForm = document.getElementById('quiz');
var ansValue = theForm.elements['ans'].value;
</script>
You have two elements with the same ID, causing a name conflict. They're also the same as the name attribute on the same element, which could cause some confusion down the road.
Try:
var ansVal = myForm.ans.checked;
This will work:
function submitAnswer() {
var myForm = document.getElementById('quiz');
// Set a default value, in case no radio button is selected
var ansVal = 'default value here';
var qnoVal = myForm.qno.value;
// Loop through radio buttons, getting the value of the
// one that is checked (selected).
var radioButtons = myForm.ans;
for (var i = 0; i < radioButtons.length; i++) {
if (radioButtons[i].checked) {
ansVal = radioButtons[i].value;
}
}
alert ("ans=" + ansVal);
alert ("qno = " +qnoVal);
return;
}
this will work too
function submitAnswer()
{
var myForm = document.getElementById('quiz');
var qnoVal = myForm.qno.value;
var ansVal = 'none';
for( i = 0; i < myForm.ans.length; i++ )
{
if( myForm.ans[i].checked == true )
{
ansVal = myForm.ans[i].value;
break;
}
}
alert ("ans=" + ansVal);
alert ("qno = " +qnoVal);
return;
}
This will work
<html>
<form name="form">
Which one is good?<br>
<input type="radio" name="food" value="Spud"
checked="checked"> Spud<br>
<input type="radio" name="food" value="Carrot"> Carrot<br>
<input type="submit" onclick="get_radio_value()">
</form>
<script type="text/javascript>
<!--
function get_radio_value()
{
for (var i=0; i < document.form.food.length; i++)
{
if (document.form.food[i].checked)
{
var rad_val = document.form.food[i].value;
alert(rad_val);
}
}
}
//-->
</script>
</html>