make one element visible and 49 others invisible - javascript

I am absolutely new to javascript, so please bear with me.
I have 50 elements on my page with ids. All are set to visibility:hidden and position:fixed. I have a button that corresponds to each element. When a button is clicked, a javascript function is initiated which makes the corresponding element visibile and position:relative. Code looks something like this:
document.getElementById("id1").style.position='relative';
document.getElementById("id1").style.visibility='visible';
To ensure that only one element is ever visible and relative, I also need to make the other 49 elements hidden and fixed. How can I accomplish this without having to resort to the following sort of code:
function makeid1visibile()
{
document.getElementById("id1").style.position='relative';
document.getElementById("id1").style.visibility='visible';
document.getElementById("id2").style.position='fixed';
document.getElementById("id2").style.visibility='hidden';
document.getElementById("id3").style.position='fixed';
document.getElementById("id3").style.visibility='hidden';
document.getElementById("id4").style.position='fixed';
document.getElementById("id4").style.visibility='hidden';
// etc...
}
Any help would be appreciated, because with 50 elements, the number of lines of coding would be outrageous.

Should be able to handle it with a single loop, just pass in the number of the item you wish to show:
function makeIdVisible(id) {
document.getElementById("id" + id).style.position='relative';
document.getElementById("id" + id).style.visibility='visible';
for (var i = 1; i <= 50; i++) {
if (i !== id) {
document.getElementById("id" + i).style.position='fixed';
document.getElementById("id" + i).style.visibility='hidden';
}
}
}

give yours checkboxes classname "someclass" and select all elements by function documet.getElementsByClassName

You can write a function like this:
function makeVisible( id ){
var idList = ['id1','id2','id3','id4'];
for( var i = 0, l = idList.length; i<l ; i++ ){
document.getElementById(idList[i]).style.position='fixed';
document.getElementById(idList[i]).style.visibility='hidden';
}
document.getElementById(id).style.position='relative';
document.getElementById(id).style.visibility='visible';
}
Then you can use
makeVisible('#id1');
to make the id1 element visible

Related

Append items in a for loop- jquery

I am adding a simple toggle button through Javascript. Then I want to add three span tags inside it.
So, I am creating variable of span and trying to append it inside our very own basic FOR loop. Iteration count is 3 times.
Here's my basic code below. Please let me know what has been missing or misplaced that my span tag refuses to append more than once. I checked this in the inspect mode.
Then, I brought up console tab and the value of i was 3. Append is meant to append and NOT replace the element. Right ?
var $navbar_header = $('<div class="navbar-header"></div>');
var $button = $("<button></button>");
var $span = $('<span class="icon-bar"></span>');
for (var i = 0; i < 3; i++) {
$button.append($span);
}
$button.addClass('navbar-toggle');
$navbar_header.append($button);
$("#menu").append($navbar_header);
Here's a link to fiddle.
The DOM is a tree, where any element points to its parent (see parentNode). An element can have only one location. So when you append an element, you're removing it from its precedent location.
The solution here is either to clone the element:
$button.append($span.clone());
or just to create it in the loop:
for (var i = 0; i < 3; i++) {
$button.append('<span class="icon-bar"></span>');
}

jQuery, using for loops to manipulate elements? (adding/removing classes etc)

function roomGen(minimum, maximum, interv) {
for (var i = minimum; i < maximum; i += interv) {
room = "#room" + i;
$(room).addClass('currentRoom');
console.log(room);
}
}
roomGen(1,20,1);
Hey all. I am trying to dynamically add classes to multiple divs at the same time via specific ids . I have divs with the id #room.. from numbers 1-100.
I was expecting the function to be the equivalent of typing:
$('#room1').addClass('currentRoom');
$('#room2').addClass('currentRoom');
etc...
However it is not giving me what I had hoped for. The console.log method is returning what I was expecting (#room1, #room2) and I am not receiving any errors with JS/jQuery regarding syntax or the elem not being recognised. Basically, when I trigger the roomGen() function... quite literally nothing happens.
I have tried collocating quotation marks (room = "'"+"#room"+i+"'"), I have tried using i.toString() and I have also tried adding the rooms to an array and accessing them. None of which has worked for me.
Any idea if this is possible to do? It seems like it should be.
Your code is working, be sure to add your script inside $(document).ready() or add the script after the DOM elements targeted.
$(document).ready(function() {
function roomGen(minimum, maximum, interv) {
for (var i = minimum; i < maximum; i += interv) {
room = "#room" + i;
$(room).addClass('currentRoom');
console.log(room);
}
}
// generate stub data for test
for (var i = 0; i < 100; i += 1) {
$("#rooms").append('<div id="room'+i+'">room'+i+'</div>');
}
roomGen(1, 20, 2);
});
.currentRoom{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rooms"></div>
jQuery operates on sets of elements. Select and filter the right elements and you don't need loops at all.
$("*[id^=room]").filter(function () {
return 0 + this.id.replace("room", "") <= 100;
}).addClass('currentRoom');

Access dynamic generated div id

I have some div ids that are generated dynamicly via php
<div id='a<?php echo $gid?>>
How can I access them in JavaScript? All these divs start with "A" followed by a number.
Is there some kind of search function
getElementById(a*)?
Thanks for any help
No generic JavaScript function for this (at least not something cross browser), but you can use the .getElementsByTagName and iterate the result:
var arrDivs = document.getElementsByTagName("div");
for (var i = 0; i < arrDivs.length; i++) {
var oDiv = arrDivs[i];
if (oDiv.id && oDiv.id.substr(0, 1) == "a") {
//found a matching div!
}
}
This is the most low level you can get so you won't have to worry about old browsers, new browsers or future browsers.
To wrap this into a neater function, you can have:
function GetElementsStartingWith(tagName, subString) {
var elements = document.getElementsByTagName(tagName);
var result = [];
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.id && element.id.substr(0, subString.length) == subString) {
result.push(element);
}
}
return result;
}
The usage example would be:
window.onload = function() {
var arrDivs = GetElementsStartingWith("div", "a");
for (var i = 0; i < arrDivs.length; i++) {
arrDivs[i].style.backgroundColor = "red";
}
};
Live test case.
In case you choose to use jQuery at some point (not worth for this thing alone) all the above code turns to single line:
$(document).ready(function() {
$('div[id^="a"]').css("background-color", "blue");
});
Updated fiddle, with jQuery.
No, you need a fixed id value for getElementById to work. However, there are other ways to search the DOM for elements (e.g. by CSS classes).
You can use querySelectorAll to get all divs that have an ID starting with a. Then check each one to see if it contains a number.
var aDivs = document.querySelectorAll('div[id^="a"]');
for(var index = 0, len = aDivs.length; index < len; index++){
var aDiv = aDivs[index];
if(aDiv.id.match(/a\d+/)){
// aDiv is a matching div
}
}​
DEMO: http://jsfiddle.net/NTICompass/VaTMe/2/
Well, I question myself why you would need to select/get an element, that has a random ID. I would assume, you want to do something with every div that has a random ID (like arranging or resizing them).
In that case -> give your elements a class like "myGeneratedDivs" with the random ID (if you need it for something).
And then select all with javascript
var filteredResults=document.querySelectorAll(".myGeneratedDivs").filter(function(elem){
....
return true;
});
or use jQuery/Zepto/YourWeaponOfChoice
var filteredResults=$(".myGeneratedDivs").filter(function(index){
var elem=this;
....
return true;
});
If you plan to use jQuery, you can use following jQuery selectors
div[id^="a"]
or
$('div[id^="id"]').each(function(){
// your stuff here
});
You will have to target the parent div and when someone click on child div inside a parent div then you can catch the child div.
<div id="target">
<div id="tag1" >tag1</div>
<div id="tag1" >tag2</div>
<div id="tag1" >tag3</div>
</div>
$("#target").on("click", "div", function() {
var showid = $(this).attr('id');
alert(showid)
});
getElementById() will return the exact element specified. There are many javascript frameworks including jQuery that allow much more powerful selection capabilities. eg:
Select an element by id: $("#theId")
Select a group of elements by class: $(".class")
Select subelements: $("ul a.action")
For your specific problem you could easily construct the appropriate selector.

Jquery wrapping my content with divs using append

for(var i=0; i<num_cols; i++)
{
//Wrapper for column
$('#cupcake-list').append('<div>');
//end wrapper
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$('#cupcake-list').append('<p>'+cupcakeData[d].name+'</p>');
}
//Wrapper for column
$('#cupcake-list').append('</div>');
//end wrapper
}
I just want to encapsulate my p tags within div tags to act as rows, however all I get are <div></div><p>ssdfsdf</p><p>sdfsdfdsf</p><div></div>etc....
What's the best way of doing it?
Start with a fragment so that you don't access the DOM more than once, and append it all at the end. You can skip the wrap by starting with your empty fragment, like so:
var $fragment;
for(var i=0; i<num_cols; i++)
{
$fragment = $('<div />');
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$fragment.append('<p>'+cupcakeData[d].name+'</p>');
}
//Wrapper for column
$('#cupcake-list').append($fragment);
//end wrapper
}
This is a much faster way to do it! Append parts of a string to an array and then you only have to update the DOM once.
var a = [];
for(var i=0; i<num_cols; i++)
{
a.push('<div>');
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
a.push('<p>'+cupcakeData[d].name+'</p>');
}
a.push('</div>');
}
$('#cupcake-list').append(a.join(''));
EDIT:
I'll explain why yours wasn't working. When you were calling $('#cupcake-list').append('<div>'); you thought it would only add the opening div tag, but that is not the case. jQuery won't let you do this is because they want to make sure the html is valid after every function call. If you were to just add the opening div and then do some other stuff, the next closing div (</div>) in the document would close the div you just opened, changing the structure of the document entirely.
In summation:
$('#cupcake-list').append('<div>'); and $('#cupcake-list').append('</div>'); will both append <div></div> to the document. Also, access and update the DOM as if it costs you a million dollars because it is among the slowest things you can do in javascript.
jQuery has a method called .wrap, and some similar ones (.wrapAll).
If you are having the output that you showed, your code is not reaching the inner for, so you have a logic problem. I think your way of doing this is correct. When i need to build some structure on the fly i usually do the same thing.
JQuery append adds DOM nodes, not HTML. So you can accomplish your task like this:
for(var i=0; i<num_cols; i++)
{
col_count++;
num_in_col = rowsInCol(total,num_perCol,col_count);
start = i*num_perCol;
end = start + num_in_col;
for(var d=start; d<end; d++)
{
$('#cupcake-list').append($('<div></div>').append('<p>'+cupcakeData[d].name+'</p>'));
}
}
First, $('<div></div>') creates a new empty div element not yet attached to the page (you can also do $('<div>') as a shorthand if you want). Then .append('<p>...</p>') adds a p element inside the div. Finally, $('#cupcake-list').append(...) adds the whole div to the end of #cupcake-list.

JavaScript multiple draggable DIV windows, zIndex on focus

I have multiple JavaScript draggable DIV windows. When clicking a DIV, I want the window to get the highest z-index value. I've made a solution by adding/removing classes to the element in focus, BUT, I would like the windows to keep their "layer" -order (as if the entire DIV window node was re-appended to the DOM when being clicked).
Let's say there are five DIV's in the DOM. div1, div2, div3, div4 and div5. -div5 is closest to the front and div1 is in the back and so on.
When clicking div1, -div1 will get focus and put to front, setting div5 back one step. Then clicking div3, -div3 gets closest to front and div1 and div5 are put back one step like this: div2, div4, div5, div1, div3.
If you don't want to loop through all your divs and don't want to mess up with z-index you can just append again that div to the parent element (the body?) before dragging.
function stepUpNode(elementDragged){
var parentNode = elementDragged.parentNode;
parentNode.appendChild(elementDragged);
}
If you'd like to do this without re-appending the element, my solution when I wrote something similar a while back was to keep track of the maximum z-index. Every time a window is brought forward, the maximum z-index is incremented and the element's z-index is set to the new value. Of course, if someone messes with the windows enough, they might end up having very large z-index values, so this isn't always the best solution.
var maximumZIndex = 1;
var bringForward = function (element) {
maximumZIndex += 1;
element.style.zIndex = maximumZIndex;
}
The first and most likely easiest approach: simply increase the maximum z-index every time a div gets selected. Since the z-index value can become pretty large (2147483647 if I remember correctly) you most likely will never run out of levels...
The following snippets use some jQuery:
var frontmostWindow = null;
var topZIndex = 10;
$('div').click(function() {
if (this != frontmostWindow) {
frontmostWindow = this;
topZIndex++;
$(this).css('zLevel', topZIndex);
// anything else needed to acticate your div
// ...
}
});
If you have restrictions on the z-indices you can use, you will need to re-assign levels every time a different div gets selected, e.g. like this:
// store z-index-ordered divs in an array
var divs = $('div').toArray().sort(function(a, b) {
return parseInt($(a).css('zIndex'), 10) - parseInt($(b).css('zIndex'), 10);
});
// store available z-indices
var zIndices = [];
for (var i = 0; i < divs.length; ++i) {
zIndices.push($(divs[i]).css('zIndex'));
}
// Event listener for clicks
$('div').click(function() {
alert("heyya " + this.id);
var element = this;
var index = divs.indexOf(element);
// check if clicked element is not already the frontmost
if (index < divs.length - 1) {
// remove div from array and insert again at end
divs.splice(index, 1);
divs.push(this);
// re-assign stored z-indices for new div order
for (var i = 0; i < divs.length; ++i) {
$(divs[i]).css('zIndex', zIndices[i]);
}
// anything else needed to acticate your div
// ...
}
});

Categories