I have a block. When I click on plus, 4 subblocks are created.I have to add when I click on any of the subblocks plus buton (rooms-guests-plus
class) , they increase from 0 to 5 and when click minus button (rooms-guests-minus
class) decrease the same way.
const room = document.querySelector('.room-guests-count');
const form = document.querySelector('.form-open');
const adultsChildren = document.querySelector('.adults-children');
const adultsChildrenWrapper = document.querySelector('.adults-children-wrapper');
const toggleRoom = () => {
const addRoomButton = document.querySelector('#add-room');
const removeRoomButton = document.querySelector('#remove-room');
const countRoom = document.querySelector('.form-text');
const addSection = () => {
const wrapper = document.createElement("div");
wrapper.className = "adults-children-wrapper";
wrapper.innerHTML = adultsChildrenWrapper.innerHTML;
adultsChildren.appendChild(wrapper).querySelector(".room-count").innerText = countRoom.value;
}
const removeSection = () => {
adultsChildren.lastChild.remove();
}
addRoomButton.onclick = () => {
if(countRoom.value == 4) return;
countRoom.value++;
addSection();
}
removeRoomButton.onclick = () => {
if(countRoom.value == 1) return;
countRoom.value--;
removeSection();
}
}
toggleRoom();
body {
background:#000;
}
/*ROOM GUESTS COUNT*/
.room-guests-count {
width: 32.2%;
cursor: pointer;
margin-right: 4%;
background: #fff;
float: left;
height: 66px;
margin-right: 149px;
}
.form-open {
display: block;
position: absolute;
z-index: -1;
top: 85px;
background-color: #fff;
height: auto;
width: 348px;
}
.form-open:after {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: 10px solid #fff;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
right: 300px;
top: -10px;
}
.room-guests-content {
padding-top: 23px;
padding-left: 15px;
}
.click_hidden_text {
position: absolute;
z-index: 1;
left: 163px;
top: 56px;
opacity: 0.8;
}
.form-search {
padding: 0;
margin: 10px 10px 5px 10px;
}
.form-item {
padding: 10px 5px;
clear: both;
height: 14px;
}
.edit-rooms {
font-weight: normal;
font-size: 13px;
float: left;
color: #000;
margin-right: 5px;
}
.rooms-guests-plus, #add-room {
float: right;
color: #fff;
background:#ccc;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
top: -6px;
position: relative;
font-size: 18px;
cursor: pointer;
}
.form-text {
text-align: center;
width: 6%;
width: 20px !important;
text-decoration: center;
float: right;
border:0;
padding: 0;
height: auto;
outline: 0;
vertical-align: middle;
}
.textfield label {
margin-right: 2.5px;
display: inline;
font-size: 13px;
}
.children-1 label {
display: inline;
font-size: 13px;
}
.rooms-guests-minus, #remove-room {
float: right;
color: #fff;
background:#e7e7e7;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
top: -6px;
position: relative;
font-size: 18px;
cursor:auto;
}
.adults-children {
clear: both;
}
.rooms-id {
line-height: 40px;
float: left;
padding:5px 0 0 15px;
color: #000;
}
.already-min {
float: right;
margin: -16px 0px 2px 6px;
padding: 0;
background: #fff;
}
.already-min-search {
float: right;
margin: 5px 10px 5px 2px;
}
.adults-children-wrapper {
clear: both;
}
.children-1 {
padding: 10px 5px;
clear: both;
height: 14px;
}
.edit-children {
font-weight: normal;
font-size: 13px;
float: left;
color: #000;
margin-right: 5px;
}
.textfield {
clear: both;
height: 14px;
margin: 0;
position: relative;
margin-top: 32px;
}
<script src=".1.1/jquery.min.js"></script>
<div class="room-guests-count">
<div class="room-guests-content">
Adult
<span>2</span>
, Child
<span>0</span>
</div>
</div>
<div class="form-open">
<div class="form-search">
<div class="form-item">
<label class="edit-rooms">Amount of number</label>
<div id="add-room">+</div>
<input class="form-text" value="1">
<div id="remove-room">-</div>
</div>
</div>
<div class="adults-children">
<div class="adults-children-wrapper">
<div class="rooms-id">Number <span class="room-count">1</span>:</div>
<div class="already-min-search">
<div class="children-1">
<label for="edit-children">Child</label>
<div class="rooms-guests-plus">+</div>
<input type="text" value="0" class="form-text">
<div class="rooms-guests-minus">-</div>
</div>
</div>
<div class="already-min">
<div class="textfield">
<label for="edit">Adult</label>
<div class="rooms-guests-plus">+</div>
<input type="text" value="0" class="form-text">
<div class="rooms-guests-minus">-</div>
</div>
</div>
</div>
</div>
</div>
I have a block. When I click on plus, 4 subblocks are created.I have to add when I click on any of the subblocks plus buton (rooms-guests-plus
class) , they increase from 0 to 5 and when click minus button (rooms-guests-minus
class) decrease the same way.
const room = document.querySelector('.room-guests-count');
const form = document.querySelector('.form-open');
const adultsChildren = document.querySelector('.adults-children');
const adultsChildrenWrapper = document.querySelector('.adults-children-wrapper');
const toggleRoom = () => {
const addRoomButton = document.querySelector('#add-room');
const removeRoomButton = document.querySelector('#remove-room');
const countRoom = document.querySelector('.form-text');
const addSection = () => {
const wrapper = document.createElement("div");
wrapper.className = "adults-children-wrapper";
wrapper.innerHTML = adultsChildrenWrapper.innerHTML;
adultsChildren.appendChild(wrapper).querySelector(".room-count").innerText = countRoom.value;
}
const removeSection = () => {
adultsChildren.lastChild.remove();
}
addRoomButton.onclick = () => {
if(countRoom.value == 4) return;
countRoom.value++;
addSection();
}
removeRoomButton.onclick = () => {
if(countRoom.value == 1) return;
countRoom.value--;
removeSection();
}
}
toggleRoom();
body {
background:#000;
}
/*ROOM GUESTS COUNT*/
.room-guests-count {
width: 32.2%;
cursor: pointer;
margin-right: 4%;
background: #fff;
float: left;
height: 66px;
margin-right: 149px;
}
.form-open {
display: block;
position: absolute;
z-index: -1;
top: 85px;
background-color: #fff;
height: auto;
width: 348px;
}
.form-open:after {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: 10px solid #fff;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
right: 300px;
top: -10px;
}
.room-guests-content {
padding-top: 23px;
padding-left: 15px;
}
.click_hidden_text {
position: absolute;
z-index: 1;
left: 163px;
top: 56px;
opacity: 0.8;
}
.form-search {
padding: 0;
margin: 10px 10px 5px 10px;
}
.form-item {
padding: 10px 5px;
clear: both;
height: 14px;
}
.edit-rooms {
font-weight: normal;
font-size: 13px;
float: left;
color: #000;
margin-right: 5px;
}
.rooms-guests-plus, #add-room {
float: right;
color: #fff;
background:#ccc;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
top: -6px;
position: relative;
font-size: 18px;
cursor: pointer;
}
.form-text {
text-align: center;
width: 6%;
width: 20px !important;
text-decoration: center;
float: right;
border:0;
padding: 0;
height: auto;
outline: 0;
vertical-align: middle;
}
.textfield label {
margin-right: 2.5px;
display: inline;
font-size: 13px;
}
.children-1 label {
display: inline;
font-size: 13px;
}
.rooms-guests-minus, #remove-room {
float: right;
color: #fff;
background:#e7e7e7;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
top: -6px;
position: relative;
font-size: 18px;
cursor:auto;
}
.adults-children {
clear: both;
}
.rooms-id {
line-height: 40px;
float: left;
padding:5px 0 0 15px;
color: #000;
}
.already-min {
float: right;
margin: -16px 0px 2px 6px;
padding: 0;
background: #fff;
}
.already-min-search {
float: right;
margin: 5px 10px 5px 2px;
}
.adults-children-wrapper {
clear: both;
}
.children-1 {
padding: 10px 5px;
clear: both;
height: 14px;
}
.edit-children {
font-weight: normal;
font-size: 13px;
float: left;
color: #000;
margin-right: 5px;
}
.textfield {
clear: both;
height: 14px;
margin: 0;
position: relative;
margin-top: 32px;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="room-guests-count">
<div class="room-guests-content">
Adult
<span>2</span>
, Child
<span>0</span>
</div>
</div>
<div class="form-open">
<div class="form-search">
<div class="form-item">
<label class="edit-rooms">Amount of number</label>
<div id="add-room">+</div>
<input class="form-text" value="1">
<div id="remove-room">-</div>
</div>
</div>
<div class="adults-children">
<div class="adults-children-wrapper">
<div class="rooms-id">Number <span class="room-count">1</span>:</div>
<div class="already-min-search">
<div class="children-1">
<label for="edit-children">Child</label>
<div class="rooms-guests-plus">+</div>
<input type="text" value="0" class="form-text">
<div class="rooms-guests-minus">-</div>
</div>
</div>
<div class="already-min">
<div class="textfield">
<label for="edit">Adult</label>
<div class="rooms-guests-plus">+</div>
<input type="text" value="0" class="form-text">
<div class="rooms-guests-minus">-</div>
</div>
</div>
</div>
</div>
</div>
I wrote the if
block in addSection function
which the loop goes through all the elements (classes .rooms-child-plus
) it works but the loop shows the error Can not read property 'addEventListener' of undefined
.
if (adultsChildren.appendChild(wrapper)) {
for(let i = 0;i < 4;i++){
var roomsChildPlus = document.querySelectorAll(".rooms-child-plus");
roomsChildPlus[i].addEventListener("click", function(){
alert("hi");
})
}
}
The question is why such an error is output and on the correct path I am? and HOW to take all the elements with querySelectorAll
and then use the addEventListener
as an array also in the same way
Share
Improve this question
asked Jan 9, 2018 at 14:40
RandallRandall
2,8686 gold badges42 silver badges75 bronze badges
5
-
You have to parse the collection (NodeList) that
querySelectorAll
returns, and assign the event listener to each element individually. – Reinstate Monica Cellio Commented Jan 9, 2018 at 14:42 - @Archer yup thank u.Already did.I use Array.from change nodelist to array but this didn't work. – Randall Commented Jan 9, 2018 at 14:43
- ... or just spare yourself the hassle of having to loop through a set of elements to attach an event handler to each one individually altogether ... and use event delegation instead. – C3roe Commented Jan 9, 2018 at 14:45
-
I think this is simple flow -->
querySelectorAll
will return array then using for loop add event listener to each element. – Tushar Acharekar Commented Jan 9, 2018 at 14:45 -
I think you're getting a bit mixed up. You create a for loop and then inside that you create a node list using
querySelectorAll()
, and then use the loop value to index it. That makes no sense. Create the node list then create the loop and access the node list elements inside that loop. – Reinstate Monica Cellio Commented Jan 9, 2018 at 14:49
2 Answers
Reset to default 5You should loop through your roomsChildPlus
instead of a hard coded length of 4.
var roomsChildPlus = document.querySelectorAll(".rooms-child-plus");
for(let j=0; j<roomsChildPlus.length; j++){
roomsChildPlus[j].addEventListener("click", function(){
alert("hi");
});
}
Try like this:
document.querySelectorAll('.rooms-child-plus').forEach(el =>
el.addEventListener('click',()=> {
alert('hi');
//or your action
}))
There are a better way, to do this: use event delegation good example, you will have only one event listener on many DOM elements.
document.addEventListener('click',(event) => {
if(event.target.classList.contain('.rooms-child-plus')){
//do something :)
}
})