Nested events triggered multiple times - javascript

I have a question about a code like the following:
$(function() {
var checkboxCnt = 1;
var checkboxHtml =
`<br><input type="checkbox" id="checkbox${checkboxCnt}">` +
`<label for="checkbox${checkboxCnt}">Checkbox 1</label>`;
// ******************************************
$('div :checkbox').change(function(e) {
checkboxChanged(e);
});
// ******************************************
$('#btn').click(function() {
checkboxCnt++;
checkboxHtml = checkboxHtml.replaceAll(checkboxCnt - 1, checkboxCnt);
$(this).before($(checkboxHtml));
// ******************************************
$('div :checkbox').change(function(e) {
checkboxChanged(e);
});
// ******************************************
});
function checkboxChanged(e) {
var checkboxID = '#' + e.target.id;
if ($(checkboxID).is(':checked')) {
console.log(checkboxID + ' is checked');
} else {
console.log(checkboxID + ' is unchecked');
}
}
});
#btn {
width: 100px;
height: 100px;
background-color: yellow;
display: block;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.js"></script>
<div>
<input type="checkbox" id="checkbox1">
<label for="checkbox1">Checkbox 1</label>
<button type="button" id="btn">Click Me!</button>
</div>
Sample can be found on https://jsfiddle.net/da7wLukz/.
This is just a simplified version of the code I'm currently editing, and it adds a checkbox every time when you hit the button. I want to execute something every time when the checkboxes are (un)checked, but I've come across the problem that when you have 4 checkboxes and check the checkbox4, the change event is triggered only once but when you check the checkbox3, it's triggered twice, and when you check the checkbox2, it's triggered 3 times and so on. The code has the same lines inside and outside of $('#btn).click because, let's say we don't have the $('div :checkbox).change event inside the $('#btn).click event, then the change event isn't triggered when checkbox2, 3, 4... are checked.
I just want the change event to be triggered only once when I (un)check the checkbox, but how can I do this? Thank you for your help in advance.

Don't nest event handlers. Use unobtrusive event handling via $(document).on() (docs):
$(function() {
var checkboxCnt = 0;
var checkboxHtml =
`<input type="checkbox" id="checkbox$%%">` +
`<label for="checkbox$%%">Checkbox %%</label><br>`;
function addCheckbox() {
checkboxCnt++;
$("#btn").before(checkboxHtml.replaceAll('%%', checkboxCnt));
}
$(document).on('change', 'div :checkbox', function () {
if (this.checked) {
console.log(this.id + ' is checked');
} else {
console.log(this.id + ' is unchecked');
}
});
$('#btn').click(addCheckbox);
addCheckbox();
});
#btn {
width: 100px;
height: 100px;
background-color: yellow;
display: block;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.js"></script>
<div>
<button type="button" id="btn">Click Me!</button>
</div>

Related

How to ignore click listening on child elements in jQuery?

I have simple div with one element:
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
When I click on #drop-zone I want to trigger input manually. I'm trying like this:
jQuery('#drop-zone:not(input)').click(function() {
jQuery(this).find('input[type="file"]').trigger('click')
})
The main problem is that I'm getting an endless loop of clicks as my manual click trigger listener on parent element.
Make sure that the element clicked was the drop-zone by checking the id of the target. When jQuery emulates an event it will pass the same this reference but will not pass the event, so just check if the event is set.
$("#drop-zone").click(function(event) {
if (this.id === "drop-zone" && event.originalEvent) {
$("#drop-zone>input").trigger("click");
}
})
#drop-zone {
background-color: red;
height: 50px;
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
You could also just trigger the event manually.
$("#drop-zone").click(function(event) {
if (this.id === "drop-zone") {
$("#drop-zone>input")[0].click();
}
})
#drop-zone {
background-color: red;
height: 50px;
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none;" multiple="multiple">
</div>
Maybe this is what you want:
var x_m = 0;
var y_m = 0;
$('#drop-zone').click(function(event) {
var mtarget = document.elementFromPoint(x_m, y_m);
if (mtarget.id === "drop-zone") {
var input = $(this).find('input[type="file"]');
var h = false;
if ($(input).is(":visible")) {
input.hide();
} else {
input.show();
h = true;
}
console.log("You clicking, the #drop-zone, input.visible =>", h);
} else {
console.log("You clicking the input.");
}
})
$('body').mousemove(function(evt){
x_m = evt.pageX;
y_m = evt.pageY;
});
#drop-zone {
height: 40px;
width: 250px;
background-color: #8b5fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="drop-zone">
<input type="file" style="display: none; background: green;" multiple="multiple">
</div>

On/Off Button to Activate function

I'm looking to have the mouse hover function active only when my button is On and when my button is off have it not activate the hover function. I can get the hover to work but not when its on
function changeBoxColor() {
let myBox = document.getElementById("myBox");
if (myBox.style.backgroundColor === "green") {
myBox.style.backgroundColor = "red";
} else {
myBox.style.backgroundColor = "green";
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
} else {
toggleButton.value = "ON";
}
}
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
<input id="toggleButton" type="button" value="ON">
<div style="height: 400px; width: 400px; background-color: red;" id="myBox"></div>
Like j08691 commented above, you just aren't binding the change in EventListeners on load, or change of the toggle button. Here is updated code that does exactly this:
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
document.getElementById("myBox").removeEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").removeEventListener("mouseleave", changeBoxColor);
} else {
toggleButton.value = "ON";
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
Now, this code assumes that the toggleButton starts as on, which is why we automatically addEventListener when the script is loaded. The other change is that when you check the toggleButton.value, we add/remove the EventListener from the element.
Simple add the events when the button value is 'ON', otherwise remove the events
function changeBoxColor() {
let myBox = document.getElementById("myBox");
if (myBox.style.backgroundColor === "green") {
myBox.style.backgroundColor = "red";
} else {
myBox.style.backgroundColor = "green";
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
var eventOver = ["mouseover",changeBoxColor];
var eventLeave = ["mouseleave",changeBoxColor];
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
document.getElementById("myBox").removeEventListener(...eventOver);
document.getElementById("myBox").removeEventListener(...eventLeave);
} else {
toggleButton.value = "ON";
document.getElementById("myBox").addEventListener(...eventOver);
document.getElementById("myBox").addEventListener(...eventLeave);
}
}
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
<input id="toggleButton" type="button" value="ON">
<div style="height: 400px; width: 400px; background-color: red;" id="myBox"></div>
FWIW, this can be done using HTML and CSS only, if you accept that your 'toggle button' can be a checkbox (a checkbox basically is a toggle button).
You can then use an attribute selector to find the checkbox, or simply select it using its class or id. Then, using + div and + div:hover, you can style the div after it.
The trick is in this selector:
input[type=checkbox]:checked + div:hover
Which basically says, target a hovered div, that is right after a checked input of type checkbox.
input[type=checkbox] + div {
height: 400px;
width: 400px;
background-color: red;
}
input[type=checkbox]:checked + div:hover {
background-color:green;
}
<input id="toggleButton" type="checkbox" value="">
<div id="myBox"></div>
Of course, you can style the checkbox to look more like the button you want, or hide it completely and use a <label for="toggleButton"></label>, which can take the place of the checkbox visually, and be styled however you like.
Or, you can even use a normal button, and just change the class of the button on click. You can then still use CSS to style the div.
This could be done using <input, but you'd have to set the value through JavaScript. For the sake of example, I used <button, which has content rather than a value, and so you can toggle the caption as well using CSS, if you would like that.
(function(element) {
element.addEventListener('click', function() {
if (element.classList.contains('on'))
element.classList.remove('on');
else
element.classList.add('on');
});
})(document.getElementById('toggleButton'));
button + div {
height: 400px;
width: 400px;
background-color: red;
}
button.on + div:hover {
background-color:green;
}
/* If you like, you can even set the button text in CSS, but
beware of accessibility issues. */
button:after {
content: "off";
}
button.on:after {
content: "on";
}
<button id="toggleButton" type="button"></button>
<div id="myBox"></div>

How to get value if div is focused in jquery?

Here I am having one div and one input text. I can get the input element value which is focused, but couldn't get the div value.
If I use .val(), I can get the input text value.
If I use .html(), I can get div element value.
But, I need the value of whatever is focused.
HTML
<div class="tab_common tab_addclass" tabindex="-1">4</div>
<input class="text-input tab_addclass" id="other-input"/>
<button type="button" id="btn">Validate</button>
JS
$(document).on ('click', '.tab_addclass', function(){
$('.tab_addclass').each(function() {
if($(this).hasClass('tab_focus'))
{
suc_flg=1;
$(this).removeClass('tab_focus');
}
});
$(this).addClass('tab_focus');
});
$(document).on ('click', '#btn', function(){
alert($('.tab_focus').val());
});
CSS
.tab_focus {
border: 2px solid #7ECC27;
background-color: #F2F2F2;
}
.tab_common{
border: 2px solid #d4d4d4;
border-radius: 4px;
cursor: pointer;
}
div {
background: #fff;
margin: 20px;
}
div:focus {
border: 2px solid #7ECC27;
}
JSFIDDLE
$(document).on ('click', '.tab_addclass', function(){
$('.tab_addclass').each(function() {
if($(this).hasClass('tab_focus'))
{
suc_flg=1;
$(this).removeClass('tab_focus');
}
});
$(this).addClass('tab_focus');
});
$(document).on ('click', '#btn', function(){
var test = $('.tab_focus').html()||$('.tab_focus').val()
alert(test);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="tab_common tab_addclass" tabindex="-1">4</div>
<input class="text-input tab_addclass" id="other-input"/>
<button type="button" id="btn">Validate</button>
Updated answer that returns the value of the most recently focused div or input following a button click:
$(document).on('click', '#btn', function () {
var focusExist = $(".focus").length;
if (focusExist) {
$focus = $(".focus");
if ($focus.hasClass("tab_common")) {
var tabValue = $focus.text();
alert(tabValue);
} else {
var inputValue = $focus.val();
alert(inputValue);
}
}
});
$(document).on('focus', '.tab_addclass', function () {
$(".focus").removeClass("focus");
$(this).addClass("focus");
});
Updated Fiddle
You have to loop through your elements and check if it is div then get the text otherwise take the input value:
$(document).on ('click', '#btn', function(){
var val = {};
$('.tab_addclass').each(function(){
if($(this).is('div')){
val.div = this.textContent;
}else{
val.input = this.value;
}
});
$('p').text(JSON.stringify(val));
});
p{background:black; color:white;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab_common tab_addclass" tabindex="-1">4</div>
<input class="text-input tab_addclass" id="other-input" value='input value' />
<button type="button" id="btn">Validate</button>
<br><br><br><br>
<p></p>
Use jQuery's keydown() funtion.
$(function(){
$('.tab_focus').keydown(function(){
alert($(this).val());
});
});
Try this in your js
alert($('.tab_focus').val() | $('.tab_focus').html());

Checkboxes not binding to tags they create on DOM jquery

I have created a modal with checkboxes that when checked, are added to the DOM. The issues that I am having that I have been trying to troubleshoot for days are that whether the checkboxes are checked or unchecked, the tag is added to the DOM, not just when checked.
I also cannot figure out how to remove the tag from the DOM when the associated checkbox is unchecked. I have the amount of checkboxes that are able to be checked max out at 6, which is what I am looking to have, but is there a way to max the amount of child divs within a parent div there could be? That way theres another safeguard to fall back on so that no more than 6 tags can be selected at one time?
Here is a jsfiddle http://jsfiddle.net/co5w7c9j/ with what I have, hopefully I explained enough without making it sound too confusing.
Below is my jquery that I have written thus far, I think I am missing a step somewhere to achieve what I am looking for.
Thank you for taking the time to look through my code.
// When specilaty is checked, add tag to profile page
$('[name=specialty]').click(function() {
$newTag = $("<div class='specTag'>" + $(this).attr('value') + "<div class='xOut'>x</div></div>");
$(this).attr('value');
$('.Specialties').append($newTag);
/* if ($('.Specialties > .specTag').has(('[name=specialty]:checked').attr('value'))) {
$('.Specialties > .specTag').has((this).txt()).remove();
} */
// Count number of checkboxes selected and display in modal
var increment = 0;
$('[name=specialty]:checked').each(function() {
if (this.checked) {
increment++;
} else {
increment--;
}
$('#specCount').html(increment);
});
// Disable checkboxes when 6 (maximum) are selected
$("input[type=checkbox][name=specialty]").click(function() {
var bol = $("input[type=checkbox][name=specialty]:checked").length >= 6;
$("input[type=checkbox][name=specialty]").not(":checked").attr("disabled", bol);
});
// Create array of checked items - add on checked - remove on uncheck
specialtyArray = $('[name=specialty]:checked').map(function() {
return $(this).val();
// if item is in the array, then remove it from the DOM
if (jQuery.inArray($('[name=specialty]:checked').val(), specialtyArray) > -1) {}
});
console.log(specialtyArray.get());
});
// When Specialties modal closes, uncheck all checked boxes, reset count
$(document.body).on('click', '.close', function() {
$('.modal-body > #updateSpecForm > .columns').children().removeAttr('checked');
$('#specCount').html(0);
})
// Fade out specialty tags when x is clicked
$(document.body).on('click', '.xOut', function() {
$(this).parent().fadeOut('slow');
$(this).parent().remove();
});
Try
// When specilaty is checked, add tag to profile page
$('input[name=specialty]').change(function() {
var value = this.value;
//if checked add a new item else remove item.
if (this.checked) {
var $newTag = $("<div class='specTag'>" + value + "<div class='xOut'>x</div></div>").attr('data-id', value);
$('.Specialties').append($newTag);
} else {
//use the attribute value which is the same as the input value to find out the item to be removed
$('.Specialties').find('div.specTag[data-id="' + value + '"]').remove()
}
//cache the result since it is used multiple times
var $checked = $('input[name=specialty]:checked');
// Count number of checkboxes selected and display in modal
var increment = $checked.length;
$('#specCount').html(increment);
// Disable checkboxes when 6 (maximum) are selected
var bol = increment.length >= 6;
//use prop instead of attr to set the disabled state
$("input[type=checkbox][name=specialty]").not(":checked").prop("disabled", bol);
// Create array of checked items - add on checked - remove on uncheck
var specialtyArray = $checked.map(function() {
return $(this).val();
});
console.log(specialtyArray.get());
});
// When Specialties modal closes, uncheck all checked boxes, reset count
$(document.body).on('click', '.close', function() {
$('.modal-body > #updateSpecForm > .columns').children().prop('checked', false);
$('#specCount').html(0);
})
// Fade out specialty tags when x is clicked
$(document.body).on('click', '.xOut', function() {
$(this).parent().fadeOut('slow', function() {
$(this).remove();
});
//uncheck the corresponding checkbox
$('input[name=specialty][value="' + $(this).closest('.specTag').attr('data-id') + '"]').prop('checked', false)
});
.Specialties {
background-color: #FFFFFF;
width: 350px;
height: 135px;
margin-left: 249px;
margin-top: 125px;
top: 0;
position: absolute;
z-index: 1;
}
.specTag {
background-color: #51b848;
color: #FFFFFF;
font-weight: 200;
letter-spacing: 1px;
font-size: 12px;
width: 150px;
height 30px;
padding: 8px;
position: relative;
margin-left: 10px;
margin-bottom: 5px;
border-radius: 5px;
display: inline-block;
}
.xOut {
background-color: #FFFFFF;
width: 25px;
padding: 3px;
position: absolute;
right: 5px;
text-align: center;
color: #333333;
top: 5px;
border-radius: 0 3px 3px 0;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="#" method="GET" id="updateSpecForm">
<!-- ATHLETIC TRAINER OPTIONS -->
<div class="columns" id="athleticTrainer">
<input type="checkbox" name="specialty" value="Boot Camp" />Boot Camp
<br />
<input type="checkbox" name="specialty" value="Children's Fitness" />Children's Fitness
<br />
<input type="checkbox" name="specialty" value="Circuit Training" />Circuit Training
<br />
<input type="checkbox" name="specialty" value="Core Training" />Core Training
<br />
<input type="checkbox" name="specialty" value="Cycling/Spinning" />Cycling/Spinning
<br />
<input type="checkbox" name="specialty" value="Dance" />Dance
<br />
<input type="checkbox" name="specialty" value="Flexibility/Balance" />Flexibility/Balance
<br />
<input type="checkbox" name="specialty" value="Meal Planning" />Meal Planning
<br />
<input type="checkbox" name="specialty" value="Men's Fitness" />Men's Fitness
<br />
<input type="checkbox" name="specialty" value="Women's Fitness" />Women's Fitness
<br />
</div>
<div class="Specialties">
<!-- SHOW BELOW DIV ONLY IF LOGGED IN -->
<!-- <div class="updateOn">+ Update My Specialties</div> -->
<!-- ***PRO CAN ADD UP TO 6 SPECIALY TAGS*** -->
</div>
</form>
Sometimes it's easier to compartmentalize code by setting parts of it into functions so that conditional aspects are easier to read through .
The biggest issue in your code was not testing if checkboxes were checked or not in the click handler.
Since the checkbox needs to do the same as the click on new tag does when it is unchecked, all logic flows through the change event of checkbox. Note that the click handler on X of tag triggers the change also
var maxChecked = 6;
// use change handler on checkboxes, will get triggered also below in another click handler
var $checkboxes = $('[name=specialty]').change(function() {
var value = $(this).val();
if(this.checked ){
addTag( value);
}else{
removeTag( value );
}
checkBoxStatus();
});
function removeTag(checkBoxValue){
/* we stored the checkbox value as data attribute, use that to filter*/
$('.specTag').filter(function(){
return $(this).data('value') === checkBoxValue;
}).slideUp(function(){
$(this).remove();
})
}
function addTag( checkBoxValue){
$newTag = $("<div class='specTag'>" + checkBoxValue + "<div class='xOut'>x</div></div>");
/* store the value in elment data so we can reference back to checkbox */
$newTag.data('value', checkBoxValue);
$('.Specialties').append($newTag);
}
/* use this to both disable and enable checkboxes */
function checkBoxStatus(){
var limitReached = $checkboxes.filter(':checked').length === maxChecked;
$checkboxes.not(':checked').prop('disabled',limitReached);
}
$(document.body).on('click', '.xOut', function () {
var $element = $(this).parent(),
$checkbox = $checkboxes.filter(function(){
return this.value === $element.data('value');
/* trigger change to remove element and reset disabled checkboxes */
}).prop('checked',false).change();
});
DEMO
Working fiddle:
http://jsfiddle.net/co5w7c9j/1/
// When specilaty is checked, add tag to profile page
$('[name=specialty]').click(function() {
$newTag = $("<div class='specTag'>" + $(this).attr('value') + "<div class='xOut'>x</div></div>");
$(this).attr('value');
$('.Specialties').append($newTag);
EnableDisableCheck();
// Create array of checked items - add on checked - remove on uncheck
specialtyArray = $('[name=specialty]:checked').map(function(){
return $(this).val();
// if item is in the array, then remove it from the DOM
if (jQuery.inArray($('[name=specialty]:checked').val(), specialtyArray) > -1) {
}
});
console.log(specialtyArray.get());
});
// When Specialties modal closes, uncheck all checked boxes, reset count
$(document.body).on('click', '.close', function () {
$('.modal-body > #updateSpecForm > .columns').children().removeAttr('checked');
$('#specCount').html(0);
})
// Fade out specialty tags when x is clicked
$(document.body).on('click', '.xOut', function () {
$(this).parent().fadeOut('slow');
$(this).parent().remove();
var text = $(this).parent().text();
$('[name=specialty]:checked').filter(function () {
return text.indexOf($(this).val()) > - 1;
}).removeAttr('checked');
EnableDisableCheck();
});
function EnableDisableCheck(){
if($('[name=specialty]:checked').length >=5)
{
$('[name=specialty]').attr("disabled","disabled");
}
else
{
$('[name=specialty]').removeAttr("disabled");
}
}

create an array with values of selected images

Im trying to gather the images selected, take their values, put them into an array, and then push them to a mysql database.
Here is my current code
$(document).ready(function() {
var startfind = $("body").find('.on').val();
var awnsers = $('.on').map(function() {
return $(startfind).text();
}).get().join(',');
$("img").click(function() {
$(this).toggleClass("on");
});
$('button').click(function() {
alert(awnsers);
});
});
#seasoning {
margin: 8px;
font-size: 16px;
height: 100px;
width: 100px;
}
.on {
padding: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://i.imgur.com/7HyU4yh.jpg" id="seasoning" value="0">
<br>
<img src="https://i.imgur.com/OEHCjCK.jpg" id="seasoning" value="1">
<br>
<button>Submit</button>
I can't get the alert to show the values of the items selected.
You can trigger an event when you click on an image
Then listen on that event, an update the answer
use answer when you need it
an I change a little in your html code, that change img's value attr to data-value
============Here is the code and jsFiddle=======================
$(function(){
//catch this values, because you will use these for more than one time
var answers = [];
function getAnswers(){
answers = []; //empty old answers so you can update it
$.map($('.on'), function(item){
answers.push($(item).data('value'));
});
}
//init the answers in case you use it before click
getAnswers();
$(document).on('click', 'img', function(e){
e.preventDefault();
$(this).toggleClass('on');
//trigger the state change when you click on an image
$(document).trigger('state-change');
});
//get answers when event was triggered
$(document).on('state-change', function(e){
getAnswers();
});
$('#btn-show').click(function(){
alert(answers.join(',') || 'nothing was selected');
});
});
#seasoning {
margin: 8px;
font-size: 16px;
height: 100px;
width: 100px;
}
.on {
padding: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://i.imgur.com/7HyU4yh.jpg" id="seasoning" data-value="0">
<br>
<img src="https://i.imgur.com/OEHCjCK.jpg" id="seasoning" data-value="1">
<br>
<button id="btn-show">Submit</button>
Please check this code.
$("img").on('click',function() {
$(this).toggleClass("on");
});
$(document).on('click', 'button', function() {
var awnsers = $('.on').map(function() {
return $(this).attr('value');
}).get().join(',');
alert(awnsers);
});
Working fiddle - http://jsfiddle.net/Ashish_developer/6ezf363a/

Categories

Resources