I have a list of photo on the page, each have an unique id, user can click on them to toggle select the photo, when they click the submit button, I need to send the array of selected photo ids to the back end, in the order that the photo was selected.
I think that the fastest way to track if a photo is selected is to use an object that use photo id as key, like:
var selected = {
"6272861": true,
"6272888": true
}
when the user unselect a photo, I just need to delete selected["6272861"].
But this will ignore the order, if I use an array to keep the selected photos:
var selected = ["6272861", "6272888"];
then when I need to unselect a photo, I have to loop through the array and delete the item.
Is there better ways? thanks.
Here is some JavaScript that does what you say:
window.addEventListener("load", function () {
"use strict";
var imgClick = function (elemSelected, elemThis) {
var idIndex;
if ((idIndex = imgSelected.indexOf(elemThis.id)) === -1) {
imgSelected.push(elemThis.id);
elemThis.className = "selected"
} else {
imgSelected.splice(idIndex, 1);
elemThis.className = "unselected";
};
console.log(elemSelected);
}
var imgDiv = document.getElementById("imgDiv");
var imgChildren = imgDiv.children;
var imgElements = [];
var imgSelected = [];
var i;
for (i = 0; i < imgChildren.length; i += 1) {
imgElements.push(imgChildren[i]);
imgChildren[i].addEventListener("click", function () {imgClick(imgSelected, this)});
}
});
Here is the associated HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<script type="text/javascript" src="imageSelect.js"></script>
<style type="text/css">
img.unselected {
border-color: black;
border-width: 1px;
border-style: solid;
}
img.selected {
border-color: red;
border-width: 3px;
border-style: solid;
}
</style>
<body>
<div id="imgDiv">
<img class="unselected" id="img01" src="intrepidWidgets.ico" title="Unselected"/>
<img class="unselected" id="img02" src="300px-Java_logo_svg.png" title="Unselected"/>
</div>
</body>
</html>
Here is a link that discusses the indexOf property of the Array global object. It may have compatibility problems with Internet Explorer before IE 9, but they have code to fix that:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
Here is a link to the working code. You need to open the console to see the resulting log (press F12 in Chrome):
http://www.quirkscode.com/flat/forumPosts/imgSelect/imageSelect.html
MDN also discusses addEventListener (search for that element name). It is the preferred way now of adding event listeners, but has compatibility issues with IE < 9:
As you seem to already know, objects do not keep the order so if the order is important, then you will want to use an array.
You can add an item to the end of the array with:
selected.push("6272898");
You can remove an item with a simple function:
function removeSelected(item) {
for (var i = selected.length - 1; i >= 0; i--) {
if (selected[i] === item) {
selected.splice(i, 1);
}
}
}
Note: This searches the array from back to front so when an item is removed, we don't have to correct/change the loop index.
Related
I'm trying to create a to-do list application. I'm using JS to dynamically create list elements on the web page when a user clicks on the submit button along with their user input.
Here's what I have so far:
const inputTXT = document.querySelector('.inputText'); //input element
const submitBUTT = document.querySelector('.submitButton'); //button element
const listITEMS = document.querySelector('.items'); //list element
function createListElement(inputString){
const newListItem = document.createElement("li");
const newEditButton = document.createElement("button");
const newDeleteButton = document.createElement("button");
const listText = document.createTextNode(inputString);
newListItem.appendChild(listText);
const editText = document.createTextNode("Edit");
newEditButton.appendChild(editText);
const deleteText = document.createTextNode("Delete");
newDeleteButton.appendChild(deleteText);
newListItem.appendChild(newEditButton);
newListItem.appendChild(newDeleteButton);
//assign class to each list element for line below:
newDeleteButton.className = "deleteCLASS";
newEditButton.className = "editCLASS";
//delete function:
var deleteButtonArray = document.querySelectorAll(".deleteCLASS");
for(var i=0; i < deleteButtonArray.length ; ++i){
deleteButtonArray[i].onclick = function(){
this.parentNode.remove();
}
}
return newListItem;
}
function addTask(){
listITEMS.classList.remove('hidden');
const ITEM = createListElement(inputTXT.value);
document.getElementsByClassName("items")[0].appendChild(ITEM);
inputTXT.value = ''; //Resets user input string
}
submitBUTT.addEventListener("click", addTask);
*{
margin: 0;
padding: 0;
}
.container{
width: 800px;
margin: 0 auto;
font-family: sans-serif;
}
.main-header{
background: #e7e7e7;
text-align: center;
margin: 15px;
padding: 20px;
}
.inputText{
margin-top: 20px;
}
h1{
font-size: 35px;
}
ul{
list-style: square;
margin-left: 275px;
}
.hidden{
display: none;
}
.itemLIST{
margin-bottom: 5px;
}
.editBUTT{
margin-left: 20px;
}
.deleteBUTT{
margin-left: 4px;
}
<!DOCTYPE html>
<head>
<title> "To-do List" </title>
<link href="style.css" rel="stylesheet"/>
<meta charset = "UTF-8"/>
</head>
<body>
<div class = "container">
<div class = "main-header">
<h1>My To-do List</h1>
<input type="text" placeholder = "Enter Item" class= "inputText" required>
<button class = "submitButton">Submit</button>
</div>
<ul class ="items hidden">
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
This works for the most parts, but I cannot delete the last list element for some reason.
The only debugging I've done to figure out what is happening is print out the "deleteButtonArray" variable, which uses the keyword "querySelectorAll". From this, I found out that when the user hits the submit button, an empty NodeList printed. When the user hits the submit button a second time, only then do we get a NodeList with 1 element. When the user hits the submit button a third time, we get a NodeList with 2 elements.
It looked like the problem had something to do with querySelectorAll not properly updating in time when the user hits the submit button. I replaced it with getElementsByClassName, and still the same issue.
Now, I think the problem has something to do with the way I'm trying to implement the delete function within the createListElement function.
The way I think my code works:
Every time a user hits the submit button, a list element is created along with an array (actually a NodeList) that contains all the list elements present so far. This means that if I delete list elements, the array will update with the correct number of list elements.
And, it does update correctly, for the most parts. I just don't know why the array is empty when we first create an element. Shouldn't querySelectorAll or getElementsByClassName return a non-empty NodeList when the user first hits the submit button?
All right, so here's a solution I've tried and tested it, and it seems to be working.
I removed the delete item portion out of the createListElement function, made it its own function, and added an event listener to each delete button that's created, so it will run the now separate delete function when clicked.
No changes were made to the HTML or the CSS.
const inputTXT = document.querySelector('.inputText'); //input element
const submitBUTT = document.querySelector('.submitButton'); //button element
const listITEMS = document.querySelector('.items'); //list element
function createListElement(inputString){
const newListItem = document.createElement("li");
const newEditButton = document.createElement("button");
const newDeleteButton = document.createElement("button");
const listText = document.createTextNode(inputString);
newListItem.appendChild(listText);
const editText = document.createTextNode("Edit");
newEditButton.appendChild(editText);
const deleteText = document.createTextNode("Delete");
newDeleteButton.appendChild(deleteText);
newListItem.appendChild(newEditButton);
newListItem.appendChild(newDeleteButton);
//Here is the new addEventListener
newDeleteButton.addEventListener("click", deleteStuff);
//assign class to each list element for line below:
newDeleteButton.className = "deleteCLASS";
newEditButton.className = "editCLASS";
return newListItem;
}
//Here is the new delete function. The onclick function that was there before has been removed because, in this case, it's not needed.
function deleteStuff() {
//delete function:
var deleteButtonArray = document.querySelectorAll(".deleteCLASS");
for(var i=0; i < deleteButtonArray.length ; ++i){
this.parentNode.remove();
}
}
function addTask(){
listITEMS.classList.remove('hidden');
const ITEM = createListElement(inputTXT.value);
document.getElementsByClassName("items")[0].appendChild(ITEM);
inputTXT.value = ''; //Resets user input string
}
submitBUTT.addEventListener("click", addTask);
I'm currently working on a sidebar menu where I toggle the "selected" class on a category, which has the classname "sidebar-category".
With jQuery I can easily achieve my desired goal: after toggling the "selected" class (if I click on another category) the previous category gets the class removed and is then applied to the currently clicked category:
$('.sidebar-category').click(function() {
$(".sidebar-category").not(this).removeClass("selected");
$(this).toggleClass('selected');
});
My problem is that for this project I cannot use jQuery and must use vanilla Javascript.
So far I can achieve the toggling easily, but I'm not sure how I can remove the class when clicking on another category using vanilla Javascript. This is my current code:
var selectCategory = document.getElementsByClassName('sidebar-category');
for (var i = 0, l = selectCategory.length; i < l; i++) {
selectCategory[i].onclick = function() {
this.classList.toggle('selected');
}
}
The jQuery code that removes the selected class is equivalent to a loop. So just write that loop in your event listener.
var selectCategory = document.getElementsByClassName('sidebar-category');
for (var i = 0, l = selectCategory.length; i < l; i++) {
selectCategory[i].onclick = function() {
for (var j = 0; j < l; j++) {
if (selectCategory[j] != this) {
selectCategory[j].classList.remove("selected");
}
}
this.classList.toggle('selected');
}
}
Assuming your target environment supports ES2015 (or you transpile your code to support such an environment), a declarative approach using Array.from, filter and forEach can be achieved with the following code:
function toggleSelectedClass(event) {
Array.from(document.getElementsByClassName('sidebar-category'))
.filter(element => element !== event.target)
.forEach(element => {
element.classList.remove('selected')
element.setAttribute('aria-pressed', false);
});
event.target.classList.toggle('selected');
const pressed = event.target.getAttribute('aria-pressed') === 'true';
event.target.setAttribute('aria-pressed', String(!pressed));
}
.sidebar-category {
padding: 5px;
}
.selected {
background: blue;
color: white;
}
<div onclick="toggleSelectedClass(event)">
<button type="button" class="sidebar-category selected" aria-pressed="true">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
<button type="button" class="sidebar-category" aria-pressed="false">Click</button>
</div>
Note: getElementsByClassName returns an HTMLCollection, not an array, so Array.from is required to use the array methods filter and forEach.
Note 2: Keep accessibility in mind when designing such a menu. A good reference for this is https://inclusive-components.design/toggle-button/.
This can be achieved with the Events API in JavaScript.
Using the onClick="" property of an HTML element we can construct a toggling system.
Create a function to handle the click action of the user and pass in the element that has been clicked as the parameter. function toggle(element){...}
Inside that element first fire off an event to clear the selected element(s) using the event named clearselected that will iterate through the elements and set the selected property to false. Thus, semantically deselecting the elements.
Change the selected property of the element passed in the onclick handler to true.
Update the user interface (UI) using an event called updateui that changed the selected element to its desired appearance, and all non-selected elements to their desired appearance using a for loop that iterates through all elements and looks at the selected property.
Down below I have a code snippet that uses vanilla JavaScript to create a toggle system on the UI. It has a very basic HTML that uses the same class names and adds very little CSS to make the demo easier to understand. I hope this is the thing you were looking for!
// Set up the HTML elements in JavaScript
var sidebar = document.getElementsByClassName("sidebar")[0];
var sidebarCategories = document.getElementsByClassName("sidebar-category");
// Add an event listener for clearing the selected elements
sidebar.addEventListener("clearselected", function(e) {
for(var i = 0; i < sidebarCategories.length; i++){
sidebarCategories[i].selected = false;
}
}, false);
// Add an event listener updating the UI to reflect changes
sidebar.addEventListener("updateui", function(e) {
for(var i = 0; i < sidebarCategories.length; i++){
var current = sidebarCategories[i];
if(current.selected){
current.textContent = "selected";
}else{
current.textContent = "";
}
}
}, false);
// Write a on click handler to handle the toggle
function toggle(element){
var event = document.createEvent("Event");
event.initEvent("clearselected", true, true);
element.dispatchEvent(event);
element.selected = true;
var event = document.createEvent("Event");
event.initEvent("updateui", true, true);
element.dispatchEvent(event);
}
.sidebar-category {
width: 100px;
height: 100px;
border: 3px solid black;
margin-bottom: 10px;
line-height: 100px;
text-align: center;
}
<div class="sidebar">
<p>Click the boxes to see the toggle in action</p>
<div class="sidebar-category" onclick="toggle(this)"></div>
<div class="sidebar-category" onclick="toggle(this)"></div>
<div class="sidebar-category" onclick="toggle(this)"></div>
</div>
I'm studying JavaScript basics and today I built a simple html page which let the user to add/remove a list item. Well, I think I could be there (I know that there are a lot of better solutions, but hey, I'm just learning).
// the function that adds a list item
function addListItem () {
var newLi = document.createElement("li");
newLi.className = "listItem";
// newLi.innerHTML = "<h3>List item</h3> <p>This is a simple list item</p>";
list.appendChild(newLi);
}
You can see full code here: https://jsfiddle.net/l_wel/cuvc0m5g/
The problem is: how you can see within the first function, I put a commented code. It inserts html content inside the new list item. Is there a better way to do it? I mean, what if i would the new list item to have the number of the list item into the ?
Something like that:
List item 1
List item 2
List item 3
etc.. etc..
I know I should use a counter, but I was not able to let the created list items to have all the original html content from the first list item without the need to rewrite it within the function.
Ok, sorry for my bad english and sorry if you think this is a very simple problem, but I tried for hours. I hope you understood what I'm trying to achieve. I think that without the comment it could work as well, depending on the project.
P.S.
I don't know jQuery yet, I wanted to solve this using vanilla js.
See if this works for you:
// store the list
var list = document.getElementById("list");
var number = 1;
// the function that adds a list item
function addListItem () {
number++;
var newLi = document.createElement("li");
newLi.className = "listItem";
newLi.innerHTML = "<h3>List item</h3> <p>This is a simple list item " + number + "</p>";
list.appendChild(newLi);
}
// the function that removes the last list item
function removeListItem () {
number--;
var ulList = document.querySelectorAll("listItem");
var lastLi = list.lastElementChild;
var containerLi = lastLi.parentNode;
containerLi.removeChild(lastLi);
}
// add a list item
var btnAdd = document.getElementById("btnAdd");
if(btnAdd.addEventListener) {
btnAdd.addEventListener("click", addListItem, false);
} else {
btnAdd.attachEvent("click", addListItem, false);
}
// remove the last list item
var btnRemove = document.getElementById("btnRemove");
if(btnRemove.addEventListener) {
btnRemove.addEventListener("click", removeListItem, false);
} else {
btnAdd.attachEvent("click", removeListItem, false);
}
body {
font-family: monospace;
background: #1e2530;
color: #cce8ff;
}
.top { text-align: center; }
#list {
list-style-type: none;
padding: 0;
margin: 10px;
}
.listItem {
background: #cce8ff;
color: #1e2530;
margin-bottom: 10px;
padding: 5px 0 5px 10px;
border-radius: 5px;
}
<body>
<div class="top">
<h2>challenge #8</h2>
<button id="btnAdd">Add an item list</button>
<button id="btnRemove">Remove an item list</button>
</div>
<ul id="list">
<li class="listItem">
<h3>List item</h3>
<p>This is a simple list item 1</p>
</li>
</ul>
</body>
addListItem is a function which can accept parameters. for example, the forEach command is iterating the array and calling the addListItem for each of the items, forEach is calling the callback with two arguments, the first argument is the item itself, and the second is the index of the item in the array...
then you can use the arguments to display the data...
var items = ['Dog','Cat','Mouse'];
function addListItem( title, index ) {
var newLi = document.createElement("li");
newLi.className = "listItem";
newLi.innerHTML = "<h3>"+title+"</h3> " + index;
list.appendChild(newLi);
}
items.forEach( addListItem );
I know you said you didn't want to use JQuery (http://api.jquery.com/append/), but it does make your life easier. For example, you could use the function below. Writing JavaScript is fun, but reading good open source JavaScript (like reading JQuery source) is a far better learning experience.
you are going to need to create a counter to get the list number:
var lst = $('ul.mylist') //class is my list, if ul.mylist doesn't exist use append to append it to the document
for(let i = 0; i < [number of elements]; i++) {
lst.append('<li>List Item' + i + '</li>);
}
How do you properly delete list item by clicking on it?
I have been using the following line for code to delete an item but instead this deletes the entire list itself:
var list = document.getElementById("shoppinglist");
list.onclick = function() { list.parentNode.removeChild(list);}
I have been searching online on how to do this and the same kind of code keeps appearing and I am not sure how to solve this. I assumed that the list item generated was a child of the "shoppinglist".
I am very new to Javascript and I know this is a rookie mistake but I would really appreciate any help. Thank you.
<!doctype html>
<html dir="ltr" lang="en-gb">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<style>
body {
/* Sets the width then uses the margin auto feature to centre the page in the browser */
width:800px;
margin: 0px auto; /*0px top/bottom auto left/right */
font-size:10px; /* By default fonts are usually 16px but may not be in some browsers */
}
p, li {
font-size:1.5em; /* Set all text to be 1.5 * overall font size = 15 pixels */
}
section {
/* each of the two sections will use just under half the width of the width of the body */
width:395px;
display:block;
}
#choices {
/* float the choices list to the left of the page */
float:left;
background-color: #FFFF99;
}
#cart {
/* float the shopping cart to the right of the page */
float:right;
background-color: #7FFF00;
}
.cartlist {
/* Simplify the display of the lists, removing default bullet points and indentation */
list-style-type:none;
margin:0px;
padding:0px;
width:inherit;
}
.cartlist li {
/* Set each list item to be 2* the height of the text */
height:2em;
}
.cartlist li:nth-child(odd) {
/* Colour odd list items ie first, third, fifth etc, a different colour */
background-color:#eee;
}
#outputinfo {
/* prevents the DIV from joining the floating behaviour so it displays below the lists */
clear:both;
}
</style>
</head>
<body>
<section id="choices">
<p>Available Choices</p>
<ul id="sourcelist" class="cartlist">
<li data-value="2.99">£2.99 : Chocolate</li>
<li data-value="3.49">£3.49 : Cereal</li>
<li data-value="0.98">£0.98 : Milk</li>
<li data-value="0.89">£0.89 : Bread</li>
<li data-value="3.79">£3.79 : Coffee</li>
<li data-value="2.53">£2.53 : Strawberries</li>
<li data-value="3.89">£3.89 : Cheesecake</li>
</ul>
</section>
<section id="cart">
<p>Shopping Cart</p>
<ul id="shoppinglist" class="cartlist"></ul>
</section>
<div id="outputinfo">
<p><button id="calctotal">Calculate Total</button> : <span id="totalresult"></span></p>
</div>
</body>
<script>
function getTargetElement(e) {
var targetelement=null;
targetelement=(e.srcElement || e.target || e.toElement)
return targetelement;
}
function calcTotal() {
var shoppinglist=document.getElementById("shoppinglist");
var total=0;
for(i=0;i<shoppinglist.children.length;i++) {
total+=parseFloat(shoppinglist.children[i].getAttribute("data-value"));
}
var totalresult=document.getElementById("totalresult");
totalresult.innerHTML="£"+total.toFixed(2);
}
function handleEvent(e) {
var listclicked=getTargetElement(e);
var newlistitem=document.createElement("li");
var datavalue=listclicked.getAttribute("data-value");
newlistitem.setAttribute("data-value",datavalue);
newlisttext=document.createTextNode(listclicked.innerHTML)
newlistitem.appendChild(newlisttext);
var shoppinglist = document.getElementById("shoppinglist");
shoppinglist.appendChild(newlistitem);
var list = document.getElementById("shoppinglist");
list.onclick = function() { list.parentNode.removeChild(list);}
console.log(listclicked);
}
function removeItem(e){
var listclicked=getTargetElement(e);
var node = document.getElementById('shoppinglist');
listclicked.parentNode.removeChild(listclicked);
}
document.onreadystatechange = function(){
if(document.readyState=="complete") {
var sourcelist=document.getElementById("sourcelist");
for(i=0;i<sourcelist.children.length;i++) {
if(document.addEventListener) {
sourcelist.children[i].addEventListener("click", handleEvent, false);
} else {
sourcelist.children[i].attachEvent("onclick", handleEvent);
}
var totalbutton=document.getElementById("calctotal");
if(document.addEventListener) {
totalbutton.addEventListener("click",calcTotal,false);
} else {
totalbutton.attachEvent("onclick",calcTotal);
}
}
}
}
</script>
</html>
You don't want to remove the entire list, just the clicked LI element.
As you don't seem to have nested elements, event delegation becomes a little easier
var list = document.getElementById("shoppinglist");
list.addEventListener('click', function(evt) {
list.removeChild(evt.target);
},false);
FIDDLE
For the future, if you wanted nesten elements, you could use element.closest()
var list = document.getElementById("shoppinglist");
list.addEventListener('click', function(evt) {
var p = evt.target.closest('li');
list.removeChild(p);
}, false);
Note the somewhat lacking support in older browsers for closest(), but there are several polyfills available if needed.
Also note that you're binding event handlers inside event handlers, which is a big no-no, your code does the equivalent of
var sourcelist = document.getElementById("sourcelist");
for(i = 0; i < sourcelist.children.length; i++) {
sourcelist.children[i].addEventListener("click", handleEvent, false);
...
// and then
function handleEvent(e) {
var list = document.getElementById("shoppinglist");
list.addEventListener('click', function(evt) {
list.removeChild(evt.target);
},false);
....
so every time you add another list item to the list, you bind a new event handler, and it adds up, but you only need one single event handler, having multiple event handlers will just try to remove the same element over and over again, but it's removed the first time.
list.onclick = function() { list.parentNode.removeChild(list);}
list is the whole list (<ul id='list'>). You're listening for a click on the whole list. Then grabbing the whole list's parent node with list.parentNode ( which gives you <section id="cart">) and deleting the list from it.
Your code is doing exactly what you told it to do.
Like this:
list.removeChild(list.childNodes[indexToRemove])
You need to specify what node to remove. You can test this in chrome by opening up the console and pasting the following:
var list = document.getElementById("shoppinglist");
console.log('List:', list)
console.log('List children:', list.childNodes)
var indexToRemove = 0;
list.removeChild(list.childNodes[indexToRemove]);
console.log('List:', list)
console.log('List children:', list.childNodes)
You can use this:
var list = document.getElementById("shoppinglist");
list.onclick = function(e) { e.target.parentNode.removeChild(e.target);}
You can read more about target and currentTarget and checkout this example http://fiddle.jshell.net/hidoos/Lpz917vo/
I was wondering if someone could help me out with a command;
If have the following script:
<script type="text/javascript">
function show_table(id){
document.getElementById('table1').style.display='none';
document.getElementById('table2').style.display='none';
document.getElementById('table3').style.display='none';
document.getElementById('table4').style.display='none';
document.getElementById('table6').style.display='none';
document.getElementById('table'+id).style.display='block';
}
</script>
And it shows the tables just fine that I have, but now I want to use a command to open two tables at the same time, so with one click on the below reference link;
Table6
Is it possible to use it with a double onclick="" command? I would like to open as example table(6) and table(2). What should I write? By the way I can only use javascript, no PHP.
I tried something like this, but is does not do the job
Table6 and Table2
Try this version, which can take a number or an array:
function show_table(id) {
var ix;
for (ix = 1; ix <= 6; ++ix) {
document.getElementById('table' + ix).style.display='none';
}
if (typeof id === "number") {
document.getElementById('table'+id).style.display='block';
} else if (id && id.length) {
for (ix = 0; ix < id.length; ++ix) {
document.getElementById('table'+ix).style.display='block';
}
}
}
Then you can say show_table([1, 2]) instead of just show_table(1).
function show_table(ids) {
var idArr = ids.split(",");
document.getElementById('table1').style.display='none';
document.getElementById('table2').style.display='none';
document.getElementById('table3').style.display='none';
document.getElementById('table4').style.display='none';
document.getElementById('table6').style.display='none';
for(var i = 0; i< idArr.length; i++) {
document.getElementById('table'+idArr[i]).style.display='block';
}
}
<a href="#" onclick="show_table('6,2')">
If you prefer minimum force aproach, try this:
function hide_all_tables(){
document.getElementById('table1').style.display='none';
document.getElementById('table2').style.display='none';
document.getElementById('table3').style.display='none';
document.getElementById('table4').style.display='none';
document.getElementById('table6').style.display='none';
}
function show_table(id){
document.getElementById('table'+id).style.display='block';
}
And then use the code this way:
Table6 and Table2
I have never used a 'double onclick command' and to be honest don't think they work, or are good practice. Why don't you just house both show table comands in a javascript function and call the function onclick?
If i am understanding you correctly.
You can change them all at once without looping, if the tables have logical associations (they must, right?).
The idea is to assign them a class (or multiple classes) and change the whole class at once:
<script>
function f(classname, show)
{
var mysheet=document.styleSheets[0];
/* Each class in the styleSheet is called a 'rule' */
var myrules=mysheet.cssRules;
var value = show ? '' : 'none'; /* show or hide? */
for (i=0; i<myrules.length; i++){
/* find the class we want to change */
if(myrules[i].selectorText==classname){
/* change the rule */
myrules[i].style.display = value;
}
}
}
</script>
<style type="text/css" >
.hasPets { color: green; display: none; }
.hasCats { font-weight: bold; display: none; }
</style>
<button onclick="f('.hasPets', true)">Show Pets</button>
<button onclick="f('.hasCats', true)">Show Cats</button>
<button onclick="f('.hasPets', false)">Hide Pets</button>
<button onclick="f('.hasCats', false)">Hide Cats</button>
<div class="hasPets">Pets</div>
<div class="hasCats hasPets">Cats</div>
In this example, Show Pets shows both, Hide Cats hides only Cats. You can't show only Cats -- Pets overrides it.
Note: I've kept this short for clarity. In practice you'll have to add a few more lines because not all versions of IE support the .cssRules property, I think they called it .rules.
This function allows for any number of tables to show.
function show_table(){
for(var i = 1; i < 7; i++) // change 7 to the amount of tables
if(document.getElementById('table'+i))
document.getElementById('table'+i).style.display='none';
for (var i = 0; i < arguments.length; i++)
if(document.getElementById('table'+arguments[i]))
document.getElementById('table'+arguments[i]).style.display='block';
}
To show tables with ids of table3 and table5 then:
show_table(3,5);