Clicking images to pass the names in a URL string - javascript

I have a low level knowledge of javascript and am trying to create a basic image based quiz that passes data back to a search page for local businesses.
Each image would have it's own "tag" as the image ID that relates to one of the options in the search. Ie. Outdoor, Ballroom, Barn, Garden, etc.
Upon submission, it would send the selected image ID's data to www.sitename/search/?_characteristics=TAG1,TAG2,TAG3
That search page will filter the business listings by the tags. Currently it's search function filters the businesses with the following format: website.com/search/?_characteristics=TAG1%2CTAG2
The HTML would look like this:
<img src="http://website.com/image1" id="TAG1"/>
<br/>
<img src="http://website.com/image2" id="TAG2"/>
<form action="https://website.com/business/?&_characteristics=TAG1, TAG2, TAG3" method="get">
<input type="submit" value="View Selected"/>

What you want is the following
Register a click handler on your images to
Capture ids into a collection (array or Set)
Toggle the "selected" class
Register a submit handler on the form to inject an hidden input element, transforming the tag collection into a CSV and setting it to the input value
const form = document.querySelector("form")
const tags = new Set()
document.querySelectorAll("img[id]").forEach(img => {
img.addEventListener("click", () => {
const selected = img.classList.toggle("selected")
tags[selected ? "add" : "delete"](img.id)
})
})
form.addEventListener("submit", (e) => {
const input = Object.assign(document.createElement("input"), {
name: "_characteristics",
type: "hidden",
value: ([...tags]).join(",")
})
form.append(input)
// this is just for the example, omit the following
e.preventDefault()
console.log(`Submitting to ${form.action}?${new URLSearchParams(new FormData(form))}`)
input.remove()
})
img { border: 2px solid grey; }
img.selected { border-color: red; }
<img src="https://picsum.photos/100" id="TAG1"/>
<br/>
<img src="https://picsum.photos/100" id="TAG2"/>
<form action="https://website.com/business/" method="get">
<input type="submit" value="View Selected"/>
</form>

I'm not sure how you want to get the selected img, but here's a way to do it:
Add the class active to the selected img
When clicking on the button, get the id and push it to the output array
Create the link of the tags (id's)
Read the comments below for the detailed explanation.
// Get the images and the submit button
let images = document.querySelectorAll('img');
let btn = document.getElementById('btn');
// Array to hold the tags
let output = [];
// variable to hold the link
let link = '';
// Add the class active to the selected images
for(let i = 0; i < images.length; i++) {
// For each image onclick:
images[i].addEventListener('click', () => {
// Toggle the `active` class on click
images[i].classList.toggle('active');
});
}
// Button onclick:
btn.addEventListener('click', () => {
for(let i = 0; i < images.length; i++) {
// Get the images with the `active` class and push the id to the output array
images[i].classList.contains('active') ? output.push(images[i].getAttribute('id')) : '';
}
// Remove duplicates if found
let uniq = [...new Set(output)];
// Create the link by adding the tags to the string (output values)
link = `www.sitename/search/?_characteristics=${uniq.join(',')}`;
// Print the link to the console
console.log(link);
});
img.active {
box-shadow: 0 0 1px 1px #121212;
}
5. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="air-conditioned"/>
<br/>
6. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="outdoor"/>
<br/>
7. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="indoor"/>
<br/>
8. <img src="http://www.gravatar.com/avatar/e1122386990776c6c39a08e9f5fe5648?s=128&d=identicon&r=PG" id="house"/>
<br/>
<button id="btn">Submit</button>

Related

Cloned, file upload and preview issue with Jquery

I have a clone creation command. The id parameter created as clone is as follows (example: id = "myid_1"), increments it by one and makes id = "myid_2". So far there is no problem. That way, each object has a unique ID value, but a simple file upload and preview function within these clones causes my function to malfunction.
I created a simple example on jsfiddle. https://jsfiddle.net/magecode/mbk9ps2x/12/
The problem I understand here is that the id value of the file upload in the onhange event must increase in parallel with the image preview id. For this, I resorted to the attr function and tried to increase the id in parallel, but it never changed.
The code I want to do in the example. The value i is always incrementing but is not added to the cloned object.
<div class="clonable-block" data-toggle="cloner">
<a href="#" id="addrow" class="btn btn-info btn-block clonable-button-add" style="border-radius: 0px; font-size: 13px;">
<i class="fa fa-file pr-2"></i>Add Row</a>
<div class="clonable">
<br/>
<br/>
<img id="upload_1" alt="your image" width="100" height="100" class="clonable-increment-id" />
<input type="file" id="preview_1"
onchange="document.getElementById('upload_1').src = window.URL.createObjectURL(this.files[0])">
<br/>
<br/>
</div>
</div>
var i = 1;
$("#addrow").click(function () {
i++;
$("#upload_" + i+"").attr("onchange", "document.getElementById('preview_'+ i + '').src = window.URL.createObjectURL(this.files[0])");
});
I recreated this with vanilla.js, you can then transform it to Jquery.
The thing is that it could be much easier. I recommend you vanilla.js, it has a better overall performance, but i understand the simplicity of Jquery.
Here it goes:
const CloneSource = document.querySelector(".clonable-source");
const buttonRow = document.getElementById("add_row");
const clonesContainer = document.getElementById("clones");
let globalCounter = 1; // Create a globalCounter for the Form IDs
window.addEventListener("change", function(e) {
let target = e.target
// This try catch is just for strictly saying that we
// want to target the .clonable class
try {
let form = target.closest(".clonable")
let fd = new FormData(form)
let img = fd.get("img");
let preview = form.children[0]
let url = URL.createObjectURL(img)
preview.setAttribute("src", url);
} catch {
console.log("No Form")
}
})
buttonRow.addEventListener("click", function(e) {
// Creates Form, img, and input elements
let formSource = document.getElementById("source")
let Form = document.createElement("form")
let Img = document.createElement("img")
let Input = document.createElement("input")
Form.className = `clonable clonable-clone`
Form.setAttribute("id", `clonable-${globalCounter}`) // This add the ID to the Form
globalCounter++; // Sum 1 to the globalCounter;
Img.setAttribute("src", formSource.children[0].getAttribute("src"))
Input.setAttribute("type", "file")
Input.setAttribute("name", "img")
Form.appendChild(Img)
Form.appendChild(Input)
// Then append the form to the clones container
clonesContainer.appendChild(Form);
});
img {
width: 5rem;
}
<button id="add_row">Add Row</button>
<div id="clones">
<form class="clonable clonable-source" id="source">
<img src="#">
<input type="file" name="img">
<p>Select an Image</p>
</form>
</div>

Each tasks added would have his own property

I have created a todo-apps with js but I have a problem : when I am clicking on the check button to do someting or on the edit button or the time button all tasks are changed : for example when I click on the check button on « learn js » I want that just this task changed ( underline) but when I do that all my tasks become underline. I know this is a beginner question sorry. This is my HTML code :
<h1>To Do List</h1>
<input type="text" placeholder="Name..." id="Name">
<input type="button" id="addItem" value="Add Item" />
<div class="choices">
<p id="p"></p>
</div>
<button id="btn" type="submit"> Clear Items</button>
This is my JS code :
let clear = document.getElementById("btn");
let add = document.getElementById("addItem");
let choices = [];
let vide = document.getElementById('p');
var choice = document.getElementById("Name").value;
let invalid = document.getElementById("invalid");
function main() {
add.addEventListener('click', function() {
addItems();
})
}
function addItems() {
choice = document.getElementById("Name").value;
vide.innerHTML += choice;
choices.push(choice);
document.getElementById('p').insertAdjacentHTML('beforeend', `<i id="check" class="far fa-check-circle"></i>`);
document.getElementById('p').insertAdjacentHTML( 'beforeend', `<i id="null" class="far fa-times-circle"></i>`);
document.getElementById('p').insertAdjacentHTML( 'beforeend', `<i. id="edit" class="far fa-edit"></i>`);
vide.insertAdjacentHTML('beforeend', `<br/><br/>`);
document.getElementById('p').classList.add('listClass');
document.getElementById('check').onclick = function() {
document.getElementById('p').classList.toggle("done");
document.getElementById('check').classList.toggle('opacity');
};
document.querySelector('#null').onclick = function() {
vide.innerHTML ='';
};
document.getElementById('edit').onclick = function() {
// I have not finished this part
}
}
}
main();
This is a picture of the result :
Depsite the fact that you have many mistakes(especially code redundancy) in your code, the main issue is that your IDs are not unique in the page.
As I said, the code is not that flexible to allow us building on it, so I took sometime to provide you a more modern, readable, performant solution (regarding yours of course !).
The code is commented to allow you understand easily what I'm doing.
// selecting the elements from the DOM
const todoList = document.getElementById("todo-list"),
newTodoForm = document.getElementById("new-todo-form"),
todoInp = document.getElementById("todo"),
clearBtn = document.getElementById("clear"),
choices = [],
/**
* createElement: a function that creates an HTML element with the specified attributes and events
* #param nodeName (string) the HTML element tag name
* #param opts (object) the attributes object which can contain :
* content: (object) an object to specify the element's content and it has two fields :
* html: (boolean) is the content should be inserted as HTML or a simple text. Defaults to false, pass true to treat the content as HTML
* value: (string) the actual content
* classList: (string) specifies a space-separated classes to be assigned to the element
* id: (string) the elemnt's ID
* data: (object) an object for the "data-TOKEN=VAL" attributes where each key (in camelCase) is the "TOKEN" and its value is the "VAL", example: {someDataOne: 'some value one', someDataTwo: 'some value two'} will be transformed into "data-some-data-one="some value one" data-some-data-two="some value two""
* events: (object) the keys are event names and the values are the events callbacks. Example {click: () => alert('clicked !')}
**/
createElement = (nodeName, opts) => {
// create the requested element
const el = document.createElement(nodeName);
// merge the options with the default ones
opts = Object.assign({
content: {
value: "",
html: !1
},
classList: "",
id: "",
data: {},
events: {}
},
opts
);
// apply the classes if the "opts.classList" is not empty
!!opts.classList && (el.classList = opts.classList);
// apply the ID if the "opts.id" is not empty
!!opts.id && (el.id = opts.id);
// apply the content if the "opts.content.value" is not empty and check if we want the content to be treated as HTML
!!opts.content.value &&
(el[opts.content.html === !0 ? "innerHTML" : "textContent"] =
opts.content.value);
// apply the data-* if the "opts.data" is not empty
if (Object.getOwnPropertyNames(opts.data).length) {
for (let p in opts.data)
if (opts.data.hasOwnProperty(p)) el.dataset[p] = opts.data[p];
}
// assign the events if the "opts.events" is not empty
if (Object.getOwnPropertyNames(opts.events).length) {
for (let p in opts.events)
if (opts.events.hasOwnProperty(p))
el.addEventListener(p, opts.events[p]);
}
// return the created element after applying the requested attributes and events
return el;
},
/*
* a function that generates a list-item template (HTML code that contains the todo text, buttons for edit, delete and so on...)
* #param txt (string) the todo text
*/
todoItemTpl = txt => {
// "item" is the list-item wrapper that contains all the buttons and todo text for only one todo item
// as you can see, we're using the "createElement" function so the code doesn't get redundant and also it become more readable and flexible
const item = createElement("div", {
classList: "todo-item row col-12 py-2 px-0 m-0 my-1 align-items-center"
}),
// the "p" element that shows the todo text
txtWrapper = createElement("p", {
content: {
value: txt
},
classList: "todo-text col-auto m-0"
}),
// a wrapper for the options (delete, edit and check) buttons of a todo item
btnsWrapper = createElement("div", {
classList: "todo-btns col-auto"
}),
// an array that holds the 3 option buttons so later we can loop through it and append each button to "btnsWrapper"
// every button here has its click event so the browser won't get confused which todo item should it alter
// !!: the edit functionality is not implemented it simply prints some text to the console when the edit button is clicked
optionBtns = [
createElement("button", {
content: {
value: '<i class="far fa-check-circle"></i>',
html: !0
},
classList: "option-btn check-btn ml-1",
events: {
click: function() {
this.closest('div.todo-item').classList.add('finished');
this.disabled = !0;
}
}
}),
createElement("button", {
content: {
value: '<i class="far fa-edit"></i>',
html: !0
},
classList: "option-btn edit-btn ml-1",
events: {
click: function() {
console.log('Edit functionnality not yet implemented !');
}
}
}),
createElement("button", {
content: {
value: '<i class="fa fa-times"></i>',
html: !0
},
classList: "option-btn del-btn ml-1",
events: {
click: function() {
const todoItem = this.closest('div.todo-item'),
txt = todoItem.querySelector('.todo-text').textContent;
todoItem.remove();
choices.splice(choices.indexOf(txt), 1);
}
}
})
];
// append the option buttons to the buttons wrapper
optionBtns.forEach((b) => btnsWrapper.appendChild(b));
// append the todo text to the todo-item
item.appendChild(txtWrapper);
// append the option buttons wrapper text to the todo-item
item.appendChild(btnsWrapper);
// return the newly created todo-item
return item;
};
// listen for the form submission
newTodoForm.addEventListener("submit", e => {
// store the trimmed input (the todo name) value
const inpVal = todoInp.value.trim();
// prevent form submission to disable page reload
e.preventDefault();
// stop execution if the todo item name is empty
if (!inpVal) return;
// if the todo text is not empty then :
// append the entered value to the "choices" array
choices.push(inpVal);
// append the todo-item to the todo list (that is initially empty) using "todoItemTpl" function and by passing the entered value for the todo name
todoList.appendChild(todoItemTpl(inpVal));
// finnaly, empty up the todo name input field
todoInp.value = "";
});
// listen for the click event of the clear button
// when clicked, remove all the todo-items and empty up the "choices" array
clearBtn.addEventListener('click', () => (todoList.innerHTML = '', choices.length = 0));
// styling for the demo, nothing fancy !
.todo-list * {
transition: all .4s 0s ease;
}
.todo-list {
background-color: #f5f5f5;
}
.todo-list .todo-item {
border-bottom: 1px solid #c5c5c5;
}
.todo-list .todo-item.finished {
background-color: #65d4a8;
}
.todo-list .todo-item.finished .todo-text {
text-decoration: line-through;
}
<!-- importing Bootsrap and Font-Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<!-- some transformations to use Bootsrap's classes -->
<div class="todo-form-wrapper">
<form action="#" id="new-todo-form">
<h1>To Do List</h1>
<input type="text" placeholder="Name..." id="todo">
<button type="submit" value="Add Item">Add</button>
</form>
</div>
<!-- the todo list wrapper is initially empty -->
<div id="todo-list" class="todo-list row m-0"></div>
<button id="clear" type="button">Clear Items</button>
Eventhough the code looks good, I don't recommand using it in production as it has some issues, it doesn't support old browsers like IE for example.
I guess you are adding all the contents inside one single - p - tag and when you change the class- i.e: toggling the class of that - p - tag to "done", it is getting applied to all inner texts.
You need separate wrapper for each task assertion to handle this problem.

Adding event handler to many dynamically generated buttons with jQuery

I have a dynamically generated form with groups of checkboxes representing categories of companies. These eventually get plotted on a dynamic chart (not shown here). Each group of companies has a toggle button to turn all the checkboxes on or off in each category.
I have a jQuery handler for the first toggle button (Tech Giants) using its ID and then checks or unchecks all the boxes in that group accordingly.
My question is this, which refers to the last portion of code in the block below. Instead of manually coding a handler for each toggle button, how can I create one that will apply to all of them on the page? Each button should only check or uncheck all the boxes in its specific category. Note that the first button on the page is separate, and not part of the category selection checkboxes we want to handle.
Here's the code in JSFiddle:
https://jsfiddle.net/gq5tw309/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This button is different than the other buttons -->
<button class="button-text" id="customize-button">Open User Settings</button>
<!-- Placeholder for dynamic form -->
<div id="company-selection-form"></div>
<script type="text/javascript">
function toMachineString(humanString) {
var machineString = humanString.replace(/\s+/g, '-').toLowerCase();
machineString = machineString.replace('&','');
return machineString;
}
// Setup the form
var categories = new Map([
['Tech Giants',['Alphabet','Amazon','Apple','Facebook','Microsoft']],
['Semiconductors', ['AMD','Intel','Nvidia']],
['Telecoms',['AT&T','Verizon','Sprint','T-Mobile']]
// ...
]);
// Build company selection form inputs
let companySelectionHTML = '';
for (let category of categories) {
categoryName = category[0];
categoryList = category[1];
// Setup a div to differentiate each category of companies.
// Will be used for turning on/off categories en masse
companySelectionHTML += `<div id="${toMachineString(categoryName)}">\n`;
// Category heading
companySelectionHTML += `<h4>${categoryName}</h4><button id="btn-${toMachineString(categoryName)}" data-checked="true">Toggle</button>`;
categoryList.forEach(companyName => {
companySelectionHTML += `
<label class="checkbox-label">
<input id="x-${toMachineString(companyName)}" class="checkbox" type="checkbox" name="company" value="${companyName}" checked>
<label for="x-${toMachineString(companyName)}">${companyName}</label>
</label>`;
});
companySelectionHTML += '</div>\n</div>\n</div>\n';
}
// Append to DOM
const companySelectionId = document.getElementById('company-selection-form');
companySelectionId.insertAdjacentHTML('beforeend', companySelectionHTML);
// Arm the toggle button
// HOW DO I APPLY THIS TO ALL THE TOGGLE BUTTONS INSTEAD OF JUST ONE?
$(document).ready(function(){
$('#tech-giants').click(function() {
// Access the data object of the button
var buttonData = $(this).data();
// Set all checkboxes 'checked' property
$('#tech-giants input[type=checkbox]').prop('checked', !buttonData.checked);
// Set the new 'checked' opposite value to the button's data object
buttonData.checked = !buttonData.checked;
// Update the chart -- code goes here
// dynamically-refresh-chart();
});
});
</script>
Thank you!
First bind your event like so for dynamically generated HTML (the buttons):
$('body').on("click", ".yourClass", function () {
//Your code goes here
});
Then use the class on the button instead of an ID, to apply the event listener to all buttons with the given class.
You could do it like this: bind the click() event to all buttons that have an id starting with "btn" $(document).on("click", "button[id^='btn']", function() {}); or just add a class to all toggle buttons and bind the click() event to them, which I did in the following code.
function toMachineString(humanString) {
var machineString = humanString.replace(/\s+/g, '-').toLowerCase();
machineString = machineString.replace('&', '');
return machineString;
}
// Setup the form
var categories = new Map([
['Tech Giants', ['Alphabet', 'Amazon', 'Apple', 'Facebook', 'Microsoft']],
['Semiconductors', ['AMD', 'Intel', 'Nvidia']],
['Telecoms', ['AT&T', 'Verizon', 'Sprint', 'T-Mobile']]
// ...
]);
// Build company selection form inputs
let companySelectionHTML = '';
for (let category of categories) {
categoryName = category[0];
categoryList = category[1];
// Setup a div to differentiate each category of companies.
// Will be used for turning on/off categories en masse
companySelectionHTML += `<div id="${toMachineString(categoryName)}">\n`;
// Category heading
companySelectionHTML += `<h4>${categoryName}</h4><button id="btn-${toMachineString(categoryName)}" class="category" data-checked="true">Toggle</button>`;
categoryList.forEach(companyName => {
companySelectionHTML += `
<label class="checkbox-label">
<input id="x-${toMachineString(companyName)}" class="checkbox" type="checkbox" name="company" value="${companyName}" checked>
<label for="x-${toMachineString(companyName)}">${companyName}</label>
</label>`;
});
companySelectionHTML += '</div>\n</div>\n</div>\n';
}
// Append to DOM
const companySelectionId = document.getElementById('company-selection-form');
companySelectionId.insertAdjacentHTML('beforeend', companySelectionHTML);
$(document).ready(function() {
$(document).on("click", ".category", function() {
var buttonData = $(this).data();
$(this).closest("div").find('input[type=checkbox]').prop('checked', !buttonData.checked);
buttonData.checked = !buttonData.checked;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button-text" id="customize-button">Open User Settings</button>
<div id="company-selection-form"></div>

How to add task to current method?

I am trying to do a web app similar to google calendar. I have done the object and methods within it but now it's time to be able to add what I want as a task. My idea is for the user to add something to the input and that input being console.logged for now.
Any idea?
HTML
<div class="new-task" id="task-input">
<div id="add-new-task">Task: <input type="text"></div>
<div id="add-time">Time: <input type="text"></div>
<button class ="save-task" onclick="">Save task</button>
</div>
Javascript
var idCounter = 0
var tasksManager = {
array: [],
add: function(task){
taskObject = {
title: task,
idVerification: idCounter ++
}
tasksManager.array.push(taskObject)
},
show:function(id){
var i;
for (i = 0; i < tasksManager.array.length; i++) {
if(id === tasksManager.array[i].idVerification){
return tasksManager.array[i]
}
}
},
delete:function(task){
if(this.show){
tasksManager.array.splice(task)
}
}
}
var newTask = document.getElementById("add-new-task")
newTask.addEventListener('click',tasksManager.add())
console.log(tasksManager.array)
As you can see with console.log above the array index [0] is logged as undefined but I wanted the user to write in the input " Go to the gym" and this to be logged within the array.
Thanks
Some issues:
You are not assigning the click handler. Instead you execute it immediately (not on click).
When you call .add() you don't provide an argument: the name of the task
The click handler should be on the button element, not on the div that has the input element. And so it will be useful to give that button an id attribute.
You should retrieve the value from the input element, and so it would be more appropriate to give that element an id and not so much the div that wraps it.
The console.log at the end of your script is executed immediately. It should be done only when the user has clicked the button.
Snippet with some corrections (also in the HTML!):
var idCounter = 0
var tasksManager = {
array: [],
add: function(task){
let taskObject = {
title: task,
idVerification: idCounter ++
}
tasksManager.array.push(taskObject)
},
show:function(id){
var i;
for (i = 0; i < tasksManager.array.length; i++) {
if(id === tasksManager.array[i].idVerification){
return tasksManager.array[i]
}
}
},
delete:function(task){
if(this.show){
tasksManager.array.splice(task)
}
}
}
var button = document.getElementById("save-task"); // <-- the button
var input = document.getElementById("add-new-task"); // <-- the input (move the ID attribute to the input!)
button.addEventListener('click', () => {
tasksManager.add(input.value);
console.log(tasksManager.array)
})
<div class="new-task" id="task-input">
<div >Task: <input id="add-new-task" type="text"></div>
<div id="add-time">Time: <input type="text"></div>
<button class ="save-task" id ="save-task" onclick="">Save task</button>
</div>

Comparing array results and then unhiding audio elements

I am trying to compare the the results of 2 arrays, and then make the corresponding elements visible.
I am passing in a list from the controller, and setting the element Id's and Names using the values from the model. I can get the values from the ticked check boxes and these alert correctly, but when I try and get the values from the appropriate audio tags, I get undefined.
<div style="display:none;" name="audioDiv" id="audioDiv">
#foreach (var item in Model)
{
<div class="divclass" value="#item.Name" id="audioDiv" hidden>
<h1> #item.Track - #item.Singer</h1>
<audio controls id="audioPlayer" value="#item.Name">
<source src="~/MP3s/#item.Name" type="audio/mp3" />
</audio>
</div>
}
</div>
function myFunction() {
document.querySelector(".table").style.display = "none";
var audionodes = document.getElementsByTagName('audio').value;
alert(audionodes)
var checkboxes = document.getElementsByName('playlist');
var vals = "";
for (var i = 0, n = checkboxes.length; i < n; i++) {
if (checkboxes[i].checked) {
vals += "," + checkboxes[i].value;
}
}
if (vals) vals = vals.substring(1);
alert(vals);
alert(audionodes)
}
I want to be able to compare the values of 'vals' and 'audionodes' and then un hide the corresponding audio elements. so for example - if the checkbox for luis fonzi - despacito is ticked, on the click of submit, I want that audio element to be visible, and the table I had displaying the 'playlist' information to be hidden.
One array will have the values of the checked boxes - so a list of track names. The second will contain all of the values for every hidden audio element - which is a value for every song. Once they've been compared, it then makes the appropriate audio elements visible.
Well if I understand you right, you are trying to display the audios based on the checkbox selection, in order to do that you need to check 2 arrays and display them, I converted html collection to array and iterated over them, you can check my comments and implement it in your own.
document.querySelector(".table").style.display = "none";
//getting all audio controls with element and its value
var audionodes = Array.from(document.getElementsByTagName('audio')).map(a => {
return {
element: a,
value: a.getAttribute("value")
}
});
//getting all the checkboxes checked
var checkboxes = Array.from(document.getElementsByTagName('input')).reduce((prev, next) => {
if (next.checked) {
prev.push(next.getAttribute("value"))
}
return prev;
}, []);
//filtering the audio control values with checkboxes and displaying them.
audionodes.filter(a => checkboxes.indexOf(a.value) >= 0).forEach(a => {
a.element.style.display = "block";
});
audio {
display: none
}
<table class="table">
<audio value="luis fonzi - despacito">test</audio>
</table>
<input value="luis fonzi - despacito" name="playlist" checked type="checkbox">
<input value="luis fonzi - despacit1o" name="playlist1" type="checkbox">

Categories

Resources