I am working on html file. I have two two labels(say L1 and L2). Each label has two radio buttons. I want to hide L2 and it's radio buttons if a user selects any radio button from L1.
I know this can be done using java script but how to capture the selection of radio buttons on which i can execute my java script.
I have prepared a version based on your question. Is this what you meant?
[HTML]
<div id="container" class="container">
<div id="first-radio">
<label for="L1">L1</label>
<div class="radio-box">
<input type="radio" name="L1" /> L1-first
</div>
<div style="margin-bottom: 15px" class="radio-box">
<input type="radio" name="L1" /> L1-second
</div>
</div>
<div id="second-radio">
<label for="L2">L2</label>
<div class="radio-box">
<input type="radio" name="L2" /> L2-first
</div>
<div class="radio-box">
<input type="radio" name="L2" /> L2-second
</div>
</div>
[Javascript]
const container = document.getElementById("container");
const firstRadio = document.getElementById("first-radio");
const secondRadio = document.getElementById("second-radio");
const L1_Radio1 = container.children[0].children[1];
const L1_Radio2 = container.children[0].children[2];
const L2_Radio1 = container.children[1].children[1];
const L2_Radio2 = container.children[1].children[2];
const array1 = [L1_Radio1, L1_Radio2];
const array2 = [L2_Radio1, L2_Radio2];
function hideRadio() {
array1.forEach(item => {
item.addEventListener("change", () => {
secondRadio.style.visibility = "hidden";
});
});
array2.forEach(item => {
item.addEventListener("change", () => {
firstRadio.style.visibility = "hidden";
});
});
}
hideRadio();
You can watch it in action here: https://jsfiddle.net/s4onh9qk/6/
Related
I want to implement a dropdown similar to the one on Booking.com in terms of functionality (I attach a screenshot), but I am encountering some issues and I can't figure out where I'm going wrong. Do you have any suggestions?
HTML
<div class="dropdown">
<input type="text" id="droptxt" class="list" readonly placeholder="Number of guests">
<div id="content" class="content">
<div class="list">
<input type="checkbox" id="rooms" class="list" value="Choose how many rooms" />
<label for="Choose how many rooms" class="list">Choose how many rooms </label>
<input type="hidden" class="list quantity" min="1" value="1" />
</div>
<div class="list">
<input type="checkbox" id="adults" class="list" value="Choose the number of adults" />
<label for="Choose the number of adults" class="list">Choose the number of adults </label>
<input type="hidden" class="list quantity" min="1" value="1" />
</div>
<div class="list">
<input type="checkbox" id="children" class="list" value="Choose the number of children" />
<label for="Choose the number of children" class="list">Choose the number of children </label>
<input type="hidden" class="list quantity" min="1" value="1" />
</div>
</div>
</div>
JavaScript
const txt = document.getElementById('droptxt');
console.log(txt);
const content = document.getElementById('content');
console.log(content);
const checkboxes = document.querySelectorAll('.list input[type="checkbox"]');
const quantity = document.querySelectorAll('.list input[type="number"]');
txt.addEventListener('click', function() {
content.classList.toggle('show');
});
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.list')) {
if (content.classList.contains('show')) content.classList.remove('show');
}
};
checkboxes.forEach(function(checkbox, index) {
checkbox.addEventListener('click', function() {
quantity[index].type = (checkbox.checked) ? 'number' : 'hidden';
calc();
});
});
quantity.forEach(function(input) {
input.addEventListener('input', calc);
});
function calc() {
let arr = [];
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
arr.push(quantity[i].value + ' x ' + checkboxes[i].value);
}
}
txt.value = arr.join(', ');
}
const quantity = document.querySelectorAll('.list input[type="number"]');
in this line you are selecting input[type="number"] but in your html there is no input which type is number. use this
const quantity = document.querySelectorAll('.list input[type="hidden"]');
it will solve your problem
I have three different inputs inside a modal that represents three different "stock" items. if a user adds a value in the input related to that specific item with a minimum of the value stipulated I want to add that input value to the total amount. but I'm stuck with looping over the buttons and calling the addAmount function to get the correct input.
I might be overcomplicating things as I'm quite new to this.
any guidance would be appreciated
const btns = document.querySelectorAll('.add-stock');
const inputs = document.querySelectorAll('[data-stock-amount]');
let totalAmount = document.querySelector('.total-amount');
totalValue = 5000;
const addAmount = (e) => {
inputs.forEach(input => {
let setAmount = input.value;
let inputData = input.dataset.stockAmount;
if (inputData === "stock25") {
totalValue = parseFloat(totalValue) + parseFloat(setAmount);
totalAmount.innerHTML = totalValue;
}
if (inputData === "stock50") {
totalValue = parseFloat(totalValue) + parseFloat(setAmount);
totalAmount.innerHTML = totalValue;
}
if (inputData === "stock100") {
totalValue = parseFloat(totalValue) + parseFloat(setAmount);
totalAmount.innerHTML = totalValue;
}
});
}
btns.forEach(btn => {
btn.addEventListener('click', (e) => {
let btnData = e.target.dataset.addStock;
if (btnData === inputData) {
addAmount(e);
}
});
});
<div class="total">$ <span class="total-amount">5000</span></div>
<div class="modal">
<div class="card">
<input type="number" name="stock1" id="stock1" value="25" data-stock-amount="stock25">
<label for="stock1">Stock1</label>
<button class="add-stock" data-add-stock="stock25">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock2" id="stock2" value="50" data-stock-amount="stock50">
<label for="stock2">Stock2</label>
<button class="add-stock" data-add-stock="stock50">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock3" id="stock3" value="100" data-stock-amount="stock100">
<label for="stock3">Stock3</label>
<button class="add-stock" data-add-stock="stock100">Add Stock</button>
</div>
</div>
Your code is significantly longer and more complicated than it needs to be. Here's a way to get you started:
const btns = document.querySelectorAll(".add-stock");
const totalAmount = document.querySelector(".total-amount");
/* Increment the total amount by the given amount. */
const addAmount = amount => {
// The '+' before the variable casts the value to a number.
totalAmount.innerHTML = +totalAmount.innerHTML + +amount;
}
btns.forEach(btn => {
btn.addEventListener("click", e => {
/* Cache the stock amount of the clicked button. */
let btnData = e.target.dataset.addStock;
/* Use the above value to find the related input. */
let input = document.querySelector("[data-stock-amount = '" + btnData + "']");
/* Parse the stock amount to find the default value. */
let defaultValue = +btnData.replace("stock", "");
/* If the current value exceeds or equals the default, add it. */
if (input.value >= defaultValue) addAmount(input.value);
/* Otherwise, print a warning on the console. */
else console.log(input.value + " is less than the default of " + defaultValue);
});
});
<div class="total">$ <span class="total-amount">5000</span></div>
<div class="modal">
<div class="card"><input type="number" name="stock1" id="stock1" value="25" data-stock-amount="stock25"><label for="stock1">Stock1</label>
<button class="add-stock" data-add-stock="stock25">Add Stock</button>
</div>
<div class="card"><input type="number" name="stock2" id="stock2" value="50" data-stock-amount="stock50"><label for="stock2">Stock2</label>
<button class="add-stock" data-add-stock="stock50">Add Stock</button>
</div>
<div class="card"><input type="number" name="stock3" id="stock3" value="100" data-stock-amount="stock100"><label for="stock3">Stock3</label>
<button class="add-stock" data-add-stock="stock100">Add Stock</button>
</div>
</div>
I believe this code meets your requirements, please see the code comments for details. This approach requires only 1 event listener to be added to a single parent element of the buttons we want to listener to click events for - this technique is called event delegation and is a cleaner approach than adding many event listeners:
const inputEls = document.querySelectorAll('[data-stock-amount]');
const totalAmountEl = document.querySelector('.total-amount');
// Get the initial values and store them as minimums
const minimumStockValues = Array.from(inputEls).reduce((map, stock) => {
map.set(stock.name, stock.value);
return map;
}, new Map());
// Add an event listener on the modal for button clicks
document.querySelector('.modal').addEventListener('click', event => {
if (event.target.tagName === 'BUTTON') {
// Get the input that corresponds to the button that was clicked
const inputEl = document.querySelector(`[data-stock-amount='${event.target.dataset.addStock}']`);
// Compare the value in the input with the allowable minimum amount and take some action
if (inputEl.value >= minimumStockValues.get(inputEl.name)) {
totalAmountEl.innerHTML = parseInt(totalAmountEl.textContent) + parseInt(inputEl.value);
} else {
console.error(`Minimum amount allowed for ${inputEl.name} is $${minimumStockValues.get(inputEl.name)}`);
}
}
});
<div class="total">$<span class="total-amount">5000</span></div>
<div class="modal">
<div class="card">
<input type="number" name="stock1" id="stock1" value="25" data-stock-amount="stock25">
<label for="stock1">Stock1</label>
<button class="add-stock" data-add-stock="stock25">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock2" id="stock2" value="50" data-stock-amount="stock50">
<label for="stock2">Stock2</label>
<button class="add-stock" data-add-stock="stock50">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock3" id="stock3" value="100" data-stock-amount="stock100">
<label for="stock3">Stock3</label>
<button class="add-stock" data-add-stock="stock100">Add Stock</button>
</div>
</div>
You are overcomplicating the logic. Just grab the input value and default value and get the max of it and add it to totalAmount.
const btns = document.querySelectorAll(".add-stock");
const inputs = document.querySelectorAll("[data-stock-amount]");
let totalAmount = document.querySelector(".total-amount");
btns.forEach((btn) => {
btn.addEventListener("click", (e) => {
const minValue = e.target.dataset.addStock.match(/[\d]+/g)[0];
const inputValue = e.target.parentNode.querySelector("input").value;
let totalAmountData = +totalAmount.textContent;
totalAmount.textContent = totalAmountData + Math.max(minValue, inputValue);
});
});
<div class="total">$ <span class="total-amount">5000</span></div>
<div class="modal">
<div class="card">
<input type="number" name="stock1" id="stock1" value="25" data-stock-amount="stock25">
<label for="stock1">Stock1</label>
<button class="add-stock" data-add-stock="stock25">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock2" id="stock2" value="50" data-stock-amount="stock50">
<label for="stock2">Stock2</label>
<button class="add-stock" data-add-stock="stock50">Add Stock</button>
</div>
<div class="card">
<input type="number" name="stock3" id="stock3" value="100" data-stock-amount="stock100">
<label for="stock3">Stock3</label>
<button class="add-stock" data-add-stock="stock100">Add Stock</button>
</div>
</div>
I'm trying to create a form with a list. The button is responsible for adding a new element to the list in the form. HTML:
<form id="newBrand">
<fieldset>
<ul id="formCars">
<li>
<legend>Car 1</legend>
<label>Name
<input type="text" name="carName1" />
</label>
</li>
</ul>
</fieldset>
<button type="button" id="addCar">+</button>
</form>
And there is my JS code:
const form = document.getElementById('newBrand');
const formCars = document.getElementById('formCars');
const addCarBtn = document.getElementById('addCar');
addCarBtn.addEventListener('click', () => formCars.appendChild(createBrandCar));
function createBrandCar() {
const result = document.createElement('li');
let size = formCars.getElementsByTagName('li').length;
result.innerHTML = `
<legend>Car ${size}</legend>
<label>Name
<input type="text" name="carName${size}" />
</label>`;
return result
}
My application renders fine, but when I click the button then I get this error:
Uncaught TypeError: Node.appendChild: Argument 1 does not implement interface Node.
This error points to a line that contains this code:
addCarBtn.addEventListener('click', () => formCars.appendChild(createBrandCar));
What can i do to prevent this error from occurring ?
You should invoke the function by specifying the parenthesis after the function name:
addCarBtn.addEventListener('click', () => formCars.appendChild(createBrandCar()));
Also, since you have already one list item on page load you should increment the size by 1:
let size = ++formCars.getElementsByTagName('li').length;
Demo:
const form = document.getElementById('newBrand');
const formCars = document.getElementById('formCars');
const addCarBtn = document.getElementById('addCar');
addCarBtn.addEventListener('click', () => formCars.appendChild(createBrandCar()));
function createBrandCar() {
const result = document.createElement('li');
let size = ++formCars.getElementsByTagName('li').length;
result.innerHTML = `
<legend>Car ${size}</legend>
<label>Name
<input type="text" name="carName${size}" />
</label>`;
return result
}
<form id="newBrand">
<fieldset>
<ul id="formCars">
<li>
<legend>Car 1</legend>
<label>Name
<input type="text" name="carName1" />
</label>
</li>
</ul>
</fieldset>
<button type="button" id="addCar">+</button>
</form>
I am trying to create an input field where I can add in custom tags as well as tags from a suggestion list. How do I add a click event listener to one of the suggestions to select it and create the tag as this is something that is dynamically created in javascript?
const stackSuggestionDiv = document.querySelector('.stack-suggestion-div');
const stackSuggestion = document.querySelector('.stack-suggestion');
const searchStack = document.querySelector('#search-stack');
searchStack.addEventListener('input', function(stackTag) {
const input = searchStack.value;
stackSuggestionDiv.innerHTML = '';
const suggestions = stackTags.filter(function(stackTag) {
return stackTag.toLowerCase().includes(input);
});
suggestions.forEach(function(suggestion) {
const suggestionDiv = document.createElement('div');
suggestionDiv.setAttribute('class', 'stack-suggestion');
suggestionDiv.innerHTML = suggestion;
stackSuggestionDiv.appendChild(suggestionDiv);
input.value = '';
});
if (input === '') {
stackSuggestionDiv.innerHTML = '';
}
});
<div class="tech-stack-input-suggestion">
<div class="tech-stack-bar">
<div class="tech-stacks-input">
<!-- <div class="stack-tag">
<span>Ruby on Rails</span>
<i class="material-icons">close</i>
</div> -->
</div>
<input type="text" id="search-stack" class="create-stack-input" placeholder="Enter Teck Stack" autocomplete="off"/>
<i id="arrow-down-btn" class="material-icons">keyboard_arrow_down</i>
</div>
<div class="stack-suggestion-div">
<!-- <div class="stack-suggestion">React.Js</div>
<div class="stack-suggestion">React.Js</div> -->
</div>
</div>
I have this task that has to been done soon, I have been trying to figure it out for the past couple of days but unfortunately, I have failed every time. I need to create a filter, where the user can click on a radio button to get those specific courses, after that or even before, he can click on checkboxes to filter even further.
I have managed to go through the "first" part of the filtering with radio buttons, the biggest issue is that I can't filter with checkboxes because for example -> you can't choose 2 options from the checkboxes.
Here is HTML
By subject:<br>
<form action="">
<input type="radio" name="name" value="Computing & IT">Computing & IT</input><br>
<input type="radio" name="name" value="Psychology & Sociology">Psychology & Sociology</input><br>
<input type="radio" name="name" value="Business & Management">Business & Management</input><br>
<input type="radio" name="name" value="Law & Criminology">Law & Criminology</input><br>
<input type="radio" name="name" value="Data Analytics">Data Analytics</input><br>
<input type="radio" name="name" value="Finance">Finance</input><br>
<input type="radio" name="name" value="Human Resource Management">Human Resource Management</input><br>
<!-- <input type="submit" value="Submit"> -->
</form>
<hr>
<h4> By Award:</h4>
<form action="">
<input type="checkbox" value="Postgraduate">Postgraduate</input><br>
<input type="checkbox" value="Undergraduate">Undergraduate</input><br>
<input type="checkbox" value="Top-Up">Top-Up</input><br>
</form>
and here is JS
fetch("https://api.myjson.com/bins/1axsrs")
.then(response => response.json())
.then(data => {
let api_array = data.name;
let radio = document.querySelectorAll('input[type=radio]');
let checkboxes = document.querySelectorAll('input[type=checkbox]')
api_array.map(item => {
document.getElementById('app').innerHTML +=
`<div class="card">
<h6>${item.vertical}</h6>
<h4>${item.program}</h4>
<p>${item.level}</p>
<button class="myButton">Enquire Now</button>
`
})
for(let select of radio) {
select.addEventListener('click',() => {
document.getElementById('app').innerHTML = "";
let api_array = data.name.filter(e => e.vertical === select.value)
api_array.map(item => {
document.getElementById('app').innerHTML +=
`<div class="card">
<h6>${item.vertical}</h6>
<h4>${item.program}</h4>
<p>${item.level}</p>
<button class="myButton">Enquire Now</button>
`
})
for(let check of checkboxes) {
check.addEventListener('change',() => {
document.getElementById('app').innerHTML = "";
if(check.checked) {
let chosen = api_array.filter(c => c.level === check.value)
chosen.map(item => {
document.getElementById('app').innerHTML +=
`<div class="card">
<h6>${item.vertical}</h6>
<h4>${item.program}</h4>
<p>${item.level}</p>
<button class="myButton">Enquire Now</button>
`
})
} else {
}
})
}
})
}
})