Get DIV ID then change href value - javascript

I have multiple divs that are switched using this javascript
<script language="JavaScript">
//here you place the ids of every element you want.
var ids = new Array('a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10');
function switchid(id) {
hideallids();
showdiv(id);
}
function hideallids() {
//loop through the array and hide each element by id
for (var i = 0; i < ids.length; i++) {
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
if (document.getElementById) { // DOM3 = IE5, NS6
document.getElementById(id).style.display = 'none';
}
else {
if (document.layers) { // Netscape 4
document.id.display = 'none';
}
else { // IE 4
document.all.id.style.display = 'none';
}
}
}
function showdiv(id) {
//safe function to show an element with a specified id
if (document.getElementById) { // DOM3 = IE5, NS6
document.getElementById(id).style.display = 'block';
}
else {
if (document.layers) { // Netscape 4
document.id.display = 'block';
}
else { // IE 4
document.all.id.style.display = 'block';
}
}
}
</script>
Then each div has some option (yes,no,continue,etc..) that switches from one div to another
<div id='a1' style="display:block;">
<div style="border-bottom: 1px solid black;margin-left: auto; margin-right: auto;text-align: center;">
<i>"I'm sorry to hear you have lost your card. I can cancel the lost card for your proection."</i><br />
<b>Find the most recent card by checking it's ISSUE date.</b><br /><br />
</div>
<div style="margin-left: auto; margin-right: auto;text-align: center;">
<span style="color:red;">Has the card been deactivated already?</span><br /><br />
<a class="spl_btn btn_green" href="javascript:switchid('a2');" onclick="document.getElementById('back').href='javascript:switchid(\'a1\');';"><span><span>Yes</span></span></a>
<a class="spl_btn btn_pink" href="javascript:switchid('a3');" onclick="document.getElementById('back').href='javascript:switchid(\'a1\');';"><span><span>No</span></span></a>
</div>
</div>
Then outside of the switching divs i have a back button. If you can see from above when you choose an option it changes to the corresponding div and then switches the back buttons href value. Now my only problem is I have 2 divs (numbers 3 and 4) that both have an option (no in this case) that lead to either 5 or 6. This specific button I have in a php variable like so
<?php echo $addr_update; ?>
Then the variables them self work like this
$project_id = $_GET["project_id"];
switch ($project_id) {
case "al":
$addr_update = "<a class=\"spl_btn btn_pink\" href=\"javascript:switchid('a5');\"><span><span>No</span></span></a>";
break;
So there are 32 different variables for this one button. I would like to be able to add an onclick event to the variable that would possibly have it grab its div id and then change the back button accordingly.
For example you are on div 2 and press no which in this case will lead you to div 5 and not div 6. The back button needs to point back to div 2. Because both div 2 and div 3 can lead to either 5 or 6 depending on the variable I cannot just add the onclick event to change the back button without knowing where the user was before.
EDIT: Just to add a little more. If you clicked the option on DIV 2 then it would set the back button to DIV 2. So in my mind if i can grab the DIV ID and then apply it to the href="javascript:switchid('a4');" part of it, it should be simple. kind of like this:
<a class="spl_btn btn_green" href="javascript:switchid('a2');" **onclick="document.getElementById('back').href='javascript:switchid(\'a1\');'; Some sort of function that would grab the containing divs id and then put it in the .href value of the document.getElement part**"><span><span>Yes</span></span></a>
Hope this makes sense and any help would be greatly appreciated.

you could use data-attributes on your divs for knowing where to go on which click:
<div id="div1" data-on-yes="div2" data-on-no="div3"></div>
and so on.
in your script you could then read that attribute
document.getElementById('div1').getAttribute('data-on-yes')
hope that helps, your question is kind of confusing ;-)

Aside from data-attributes you can track current and prev ids
<script type="text/javascript">
//here you place the ids of every element you want.
var ids = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10'];
function switchid(id) {
if(id === current) {return;}
hideallids();
showdiv(id);
current = id;
}
//previous and current id;
var prev, current;
function switchNext() {
var next = this.getAttribute("data-next-id"); //get next id from data-attr
prev = this.parentNode.parentNode.id; //get parent div's id
switchid(next);
}
function switchPrev() { //For back link
if(!prev) {return;}
var curr = current; //store current id
switchid(prev); //switch to what was previous
prev = curr; //set prev to what was current. Not sure if you need this
}
function hideallids() {
//loop through the array and hide each element by id
for (var i = 0; i < ids.length; i++) {
hidediv(ids[i]);
}
}
function hidediv(id) {
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
document.getElementById(id).style.display = 'block';
}
</script>
Markup
<div id='a1' style="display:block;">
<div style="border-bottom: 1px solid black;margin-left: auto; margin-right: auto;text-align: center;">
<i>"I'm sorry to hear you have lost your card. I can cancel the lost card for your proection."</i><br />
<b>Find the most recent card by checking it's ISSUE date.</b><br /><br />
</div>
<div style="margin-left: auto; margin-right: auto;text-align: center;">
<span style="color:red;">Has the card been deactivated already?</span><br /><br />
<a class="spl_btn btn_green" data-next-id="a2" href="#" onclick="switchNext.call(this);"><span><span>Yes</span></span></a>
<a class="spl_btn btn_pink" data-next-id="a3" href="#" onclick="switchNext.call(this);"><span><span>No</span></span></a>
</div>
</div>
And for back button
<a id="back" onclick="switchPrev.call(this);" href="#">Back</a>

Related

Javascript - get class of another element with onclick

I want to individually toggle to different divs using the same function. Each of these divs has a common class and a different id. The function toggle is called using an onclick parameter on two separate <a> elements:
<a class="btn" id="btnOne" onclick="toggler();">Show/hide divOne</a>
<div class="box" id="divOne">
<a class="btn" id="btnTwo" onclick="toggler();">Show/hide divTwo</a>
<div class="box" id="divTwo">
I first tried to get these divs with getElementsByClassName but, as it returns an HTMLCollection, the script can't target each div individually.
So I tried to select the <a> tags ids (btnOne and btnTwo), but couldn't figure out how to retrieve the divs class using these ids (as we're talking about two different elements here).
In the end, I came back to the getElementById method, as I couldn't figure out how to select them based on their class:
function toggler() {
var id = document.getElementById("divId");
if (id.style.display === "none") {
id.style.display = "block";
} else {
id.style.display = "none";
}
};
This leaves me with two functions instead of just one. Any suggestion on how to target the two divs individually?
You can access the next sibling using nextElementSibling presuming the box will always be right after the hyperlink.
// Put the buttons into an array
const buttons = [...document.getElementsByClassName("btn")];
// Assing an event listener for every button
buttons.map(button => button.addEventListener("click", function(e) {
// Find the next sibling
const box = e.target.nextElementSibling;
// Toggle the display value
if (box.style.display === "none") {
box.style.display = "block";
} else {
box.style.display = "none";
}
}));
a {
display: block;
}
.box {
width: 5rem;
height: 2rem;
background-color: blue;
}
<a class="btn">Show/hide divOne</a>
<div class="box"></div>
<a class="btn">Show/hide divTwo</a>
<div class="box"></div>
There is a simple way to select the divs with their class name and you already used it.
The answer is getElementsByClassName. But in vanilla JS things are a little bit (over)complicated.
It will not target both divs individually. Instead, if you want to select the first div with this class you would do it like this:
getElementsByClassName('classname')[0]
If you want to select the second div you would use:
getElementsByClassName('classname')[1]
and so on. But there is a way of course.
You want to use loops:
var x = document.getElementsByClassName("classname");
for (var i = 0; i < x.length; i++) {
if (x[i].style.display === "none") {
x[i].style.display = "block";
} else {
x[i].style.display = "none";
}
}
In this way, you will target ALL divs with this class.
I'd dynamically add the events on the switches, using their classes. I added the class showHideDivBtn to them. To make sure you know which div you have to toggle, I used a data-id.
With addEventListener, I can use the event variable I named e. With this one, I have access to properties, such as the data-id I wrote.
let buttons = document.getElementsByClassName("showHideDivBtn");
for (let i = 0; i < buttons.length; ++i)
{
buttons[i].addEventListener('click', function(e)
{
let divToToggle = document.getElementById(e.srcElement.dataset.id);
if (divToToggle.style.display === "none")
divToToggle.style.display = "block";
else
divToToggle.style.display = "none";
});
}
<a class="btn showHideDivBtn" data-id="divOne" id="btnOne">Show/hide divOne</a>
<div class="box" id="divOne">One</div>
<br />
<a class="btn showHideDivBtn" data-id="divTwo" id="btnTwo">Show/hide divTwo</a>
<div class="box" id="divTwo">Two</div>
Use substr to get the word after extracting 'btn' from anchor id which will result in One or Two then while defining the if use "div"+word this will get the div by it is related a tag
function toggler() {
var word=this.id.substr(3);
var id = document.getElementById("div"+word);
if (id.style.display === "none") {
id.style.display = "block";
} else {
id.style.display = "none";
}
};

How to hide current content by clicking outside its area, and when I show another content in IE11?

Clicking on the button shows and hides the corresponding content.
function funC(id) {
var el = document.getElementById(id);
if(el.style.display == 'inline-block')
el.style.display = '';
else
el.style.display = 'inline-block';
}
button {margin:2px; outline:0; font-size:12px;}
span {padding:2px; border:1px solid silver;
font-size:12px;}
.cb {display:none;}
<button onclick="funC('cnt1');">b1</button><span id="cnt1" class="cb">content b1...</span>
<br />
<button onclick="funC('cnt2');">b2</button><span id="cnt2" class="cb">content b2...</span>
<br />
<button onclick="funC('cnt3');">b3</button><span id="cnt3" class="cb">content b3...</span>
fiddle example
1. But, how to hide content when clicking outside its area,
and as with showing the next content, hide the previous one?
2. Is it possible to do the same without using id?
Only pure javascript. Thank you.
This might not be a perfect solution but here is a proposition :
function hideAllContent() {
var elements = document.querySelectorAll(".cb");
for(var i =0, l = elements.length; i < l; i++) {
var element = elements[i];
element.visible = false;
element.style.display='none';
}
}
function funC(id, event) {
// We need to stop the event to avoid bubling until the body
event.stopPropagation();
// let's hide others before displaying the new one
hideAllContent();
var el = document.getElementById(id);
if(el.visible) {
el.visible = false;
el.style.display = 'none';
} else {
el.visible = true;
el.style.display = 'inline-block';
}
}
document.body.onclick = function(event) {
if (!event.target.classList.contains('cb')) {
hideAllContent();
}
}
button {margin:2px; outline:0; font-size:12px;}
span {padding:2px; border:1px solid silver;
font-size:12px;}
.cb {display:none;}
<button onclick="funC('cnt1', event);">b1</button><span id="cnt1" class="cb">content b1...</span>
<br />
<button onclick="funC('cnt2', event);">b2</button><span id="cnt2" class="cb">content b2...</span>
<br />
<button onclick="funC('cnt3', event);">b3</button><span id="cnt3" class="cb">content b3...</span>
About avoiding ids, you could use the target property on click event and find the sibling node or something like that or use a querySelector. But ids are safe and fine i would say.
No inline on-clicks attached.
No IDs use.
Used backward-compatible syntax for IE 11.
// JavaScript
// get all button and span tags
var btns = document.querySelectorAll('button');
var otherSpans = document.querySelectorAll('span');
// Detect all clicks on the document
document.addEventListener("click", function(event) {
const spanElems = document.querySelectorAll('span');
const spanElemsArray = Array.prototype.slice.call(spanElems);
let matches = event.target.matches ? event.target.matches('button') : event.target.msMatchesSelector('button');
// If user clicks inside the element, do nothing
if (matches) {
return;
} else {
// If user clicks outside the element, hide it!
spanElemsArray.forEach( function (spanElem) {
spanElem.classList.remove("open");
});
}
});
// convert buttons and spans variable objects to arrays
const btnsArray = Array.prototype.slice.call(btns);
const otherSpansArray = Array.prototype.slice.call(otherSpans);
// loop through every button and assign a click to each one
btnsArray.forEach( function (btn) {
btn.addEventListener('click', spanFunc)
});
// Pass the button clicked as a reference
function spanFunc(){
openSpan(this);
}
// toggle the display class on the span next to the button using nextElementSibling method
function openSpan(e) {
e.nextElementSibling.classList.toggle("open");
// hide every other spans
function otherSpanFunc() {
otherSpansArray.forEach( function (otherSpan) {
if (otherSpan !== e.nextElementSibling) {
otherSpan.classList.remove('open');
}
});
}
otherSpanFunc();
}
/* css */
button {margin:2px; outline:0; font-size:12px;}
span {padding:2px; border:1px solid silver;
font-size:12px;}
.cb {display:none;}
.open {display:inline-block;}
<!-- HTML -->
<button>b1</button><span class="cb">content b1...</span>
<br />
<button>b2</button><span class="cb">content b2...</span>
<br />
<button>b3</button><span class="cb">content b3...</span>
jsFiddle: https://jsfiddle.net/ypofz4d5/55/

Append new Element only once on click and save it to local storage html javascript

Here is JS Fiddle!
I am trying to append new Elements to the div, this is working.
My problem is that I want to append the new element only once on button click, and save it to localStorage so that I would not loose the state on refresh or any other action.
div {
text-align: center;
}
#Neighborhood {
color: brown;
}
#NewElement {
color: green;
}
<div id="Neighborhood">
<div id="Neighbor1">Neighbor 1</div>
<div id="Neighbor2">Neighbor 2</div>
<div id="Neighbor3">Neighbor 3</div>
</div>
<input type="button"onclick="add_prev();" value="ACTION">​
/* Adds Element BEFORE NeighborElement */
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
}, false;
/* Adds Element AFTER NeighborElement */
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
}, false;
/* Typical Creation and Setup A New Orphaned Element Object */
add_prev = function () {
var NewElement = document.createElement('div');
NewElement.innerHTML = 'New Element';
NewElement.id = 'NewElement';
NewElement.appendBefore(document.getElementById('Neighbor2'));
}
I am thankful for every tip or solution! Cheers!
Pass this to the onclick function. That way, after you do your things, just remove the listener to click or disable the button.
Also, when the page loads, load the information from the storage, if it's true, directly call the function and then disable the button.
Maybe it isn't exaclty what you need, but it can help a lot, you can follow this logic to get there. The code below is just an example.
OBS: it won't work well here because localStorage is not allowed in StackOverflow.
In this fiddle you can try it better: https://jsfiddle.net/so5u1c4z/
On the fiddle above, create the element, then save and reload the page. the element will be there once the page loads.
$(document).ready(function(){
add_prev = function (elem) {
var NewElement = document.createElement('div');
NewElement.innerHTML = 'New Element';
NewElement.id = 'NewElement';
document.getElementById('Neighbor2').append(NewElement);
localStorage.setItem('elementCreated', true);
if (elem){
$(elem).attr('disabled', true);
}
}
var isCreated = localStorage.getItem('elementCreated');
if (isCreated){
add_prev();
$("#btnAdd").attr('disabled', true);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" onclick="add_prev(this);" value="ACTION" id="btnAdd">
<div id="Neighbor2"></div>

How to leave one active button in the JavaScript?

I am beginner.
I have four buttons and I want to leave one active button every time with expression operator (if). One button must have active every time .
I tried to do it something like that. I am open to your ideas, if you can do without (if) .Help me!
var count = 4;
var flag = true;
function select(currentColor, changeColor){
if(count > 1 && flag === true){
var currentElement = angular.element(document.getElementsByClassName(currentColor));
currentElement.toggleClass(changeColor);
count--;
console.log(count);
console.log('From minus: ' + count);
}else{
flag = false;
}
if(count < 4 && flag === false) {
var currentElement = angular.element(document.getElementsByClassName(currentColor));
currentElement.toggleClass(changeColor);
count++;
console.log(count);
console.log('From plus: ' + count);
}else{
flag = true;
}
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<style>
.changeColor{
color: red !important;
}
.first{
color: #07888A;
}
.second{
color: #07888A;
}
.third{
color: #07888A;
}
.fourth{
color: #07888A;
}
h1{
display: inline;
margin-right: 20px;
}
</style>
</head>
<body>
<h1 class="first" onClick="select('first', 'changeColor')">First</h1>
<h1 class="second" onClick="select('second', 'changeColor')">Second</h1>
<h1 class="third" onClick="select('third', 'changeColor')">Third</h1>
<h1 class="fourth" onClick="select('fourth', 'changeColor')">Fourth</h1>
</body>
</html>
Add this bit:
function select(currentColor, changeColor) {
// Get the list of the `.changeColor` elements.
changed = document.querySelectorAll(".changeColor");
// Loop through all the elements with `changeColor` class.
for (i = 0; i < changed.length; i++)
// Remove the changeColor class from their class list.
changed[i].classList.remove("changeColor");
// Rest comes your code.
if(count > 1 && flag === true){
are you trying to get one button disabled when any three buttons are enabled ? if so, perhaps this could help. I highly suggest not to use the h1 tags for this purpose, and use something like a button or div, and removing the onclick attributes from your elements and incorporate them in your main js file similar to the js snippet found below.
(function() {
//an empty array to track the number of elements currently colored
var numberOfElesColored = [],
eles = document.querySelectorAll('h1'),
//the number of active elements allowed at once
numberOfActiveElementsAllowed = eles.length - 1;
//loop though all the elements and attach click event
[].forEach.call(eles, function(ele, i) {
ele.addEventListener('click', function(event) {
var currentEle = event.target;
//is there at least two other elements avaliable still ?
if (!(numberOfElesColored.length === numberOfActiveElementsAllowed)) {
//yes
//is the current clicked element not active already ?
if (!currentEle.classList.contains('changeColor')) {
//yes
//add 1 to tracking array
numberOfElesColored.push(1);
//activate element
return currentEle.classList.add('changeColor');
} else {
//no
//remove 1 from tracking array
numberOfElesColored.pop();
//deactivate elements
return currentEle.classList.remove('changeColor');
}
//are all the elements active already ?
} else if (numberOfElesColored.length === numberOfActiveElementsAllowed) {
//yes
//is the current element an active one ?
if (currentEle.classList.contains('changeColor')) {
//yes
//remove 1 from tracking array
numberOfElesColored.pop();
//deactivate element
return currentEle.classList.remove('changeColor');
}
}
});
});
})();

Show tab or menu choice as the active element with javascript

This is not a jQuery question. I'm not using an <anchor> or list for my menu. I want the menu (tab) item to be a different color when that menu (tab) is active. I've tried using CSS :active and :selection, but they don't work. I'm using a <label> inside a <p> tag for my menu:
<div id="MainMenu">
<p class="floatLeftP" id="SiteName">Site Name Here</p>
<p class="floatLeftP"><label id="ViewLink1" onclick="mainMenuChg('Home')">HOME</label></p>
<p class="floatLeftP"><label id="ViewLink2" onclick="mainMenuChg('Offered')">OFFERED</label></p>
<p class="floatLeftP"><label id="ViewLink3" onclick="mainMenuChg('Input')">INPUT</label></p>
<p class="floatLeftP"><label id="ViewLink4" onclick="mainMenuChg('Wanted')">WANTED</label></p>
<p class="floatLeftP"><label id="ViewLink5" onclick="mainMenuChg('MyAccount')">My Account</label></p>
<p class="floatLeftP"><label id="ViewLink6" onclick="openHTTPS()">Sign Up!</label></p>
<p class="floatRightP"><label id="ViewLink7" onclick="openHTTPS()">Sign In</label></p>
</div>
The CSS :active is for a link, but I'm not using a link.
When most of the menu items are clicked a function named mainMenuChg('argHere') runs.
function mainMenuChg(argPage) {
window.location.href = "#" + argPage;
};
This changes the URL in the browser, which then causes an angularJs router to trigger.
I don't want to use angularJs for this. I only want to use JavaScript. I can get a menu item to change color using:
document.getElementById(theID).style.color = "yellow";
But then it stays that color. If I click another menu item, then two menu items have turned yellow. I need to set the current <label> to a different color, then turn the last one back to it's original color. The menu items are different colors, so I need a way to set it back to the default.
I need a way to store the old id in a variable that doesn't loose it's value. But if I define a variable inside the function, it seems to loose it value.
I've seen a couple of questions that show a solution in jQuery, but not JavaScript.
First you can give a class to all labels.
For example, class="this-is-a-tab".
Then you can edit a little the function and add another parameter.
function mainMenuChg(argPage,tabId).
And on the labels...
onclick="mainMenuChg('Home',this.id)">
Now back to the function...
function mainMenuChg(argPage,tabId) {
//First We Remove the Yellow from all Tabs
var tabs = document.getElementsByClassName("this-is-a-tab");
//Then go through them
for(var i=0; i< tabs.length; i++)
{
tabs[i].style.color = "blue";
}
//Then we give yellow to the tab we clicked on.
document.getElementById(tabId).style.color = "yellow";
window.location.href = "#" + argPage;
};
Check if following pseudo code helps you
prevObj; // global variable.
if(prevObj != undefined) {
precObj.style.color = original_color;
}
this.style.color = "yellow";
prevObj = this;
Thanks to everyone's kind answers, I've been able to come up with a working solution. There is a full working version at jsFiddle, the link is at the bottom of the page. Here is the HTML.
<div id="menu">
<ul>
<li><a class="myMenu" id="xyz1" href="#" title="Update"><span>Home</span></a>
</li>
<li><a class="myMenu" id="abc2" href="#" title="Save"><span>Save</span></a>
</li>
<li><a class="myMenu" id="hij9" href="#" title="User"><span>User</span></a>
</li>
</ul>
</div>
And here is the code:
var menuHome = document.getElementById('xyz1');
var menuSave = document.getElementById('abc2');
var menuUser = document.getElementById('hij9');
menuHome.addEventListener('mouseup', clickedHome, false);
menuSave.addEventListener('mouseup', clickedSave, false);
menuUser.addEventListener('mouseup', clickedUser, false);
var currentMenuItem = '';
function clickedHome() {
if (menuHome === currentMenuItem) {
return;
};
//alert("home menu clicked: ");
menuHome.style.background = 'blue';
//alert('currentMenuItem: ' + currentMenuItem);
if (currentMenuItem !== undefined && currentMenuItem !== "") {
//alert("it ran: ");
currentMenuItem.style.background = '';
}
setCurrent(menuHome);
}
function clickedSave() {
if (menuSave === currentMenuItem) {
return;
};
//alert("home menu clicked: ");
menuSave.style.background = 'cyan';
if (currentMenuItem !== undefined && currentMenuItem !== "") {
//alert("it ran: ");
currentMenuItem.style.background = '';
}
setCurrent(menuSave);
}
function clickedUser() {
//alert("home menu clicked: ");
if (menuUser === currentMenuItem) {
return;
};
menuUser.style.background = 'blue';
if (currentMenuItem !== undefined && currentMenuItem !== "") {
//alert("it ran: ");
currentMenuItem.style.background = '';
}
setCurrent(menuUser);
}
function setCurrent(argMenu) {
//alert("set current ran: ");
currentMenuItem = argMenu;
//alert('currentMenuItem: ' + currentMenuItem);
};
Here is a working example at jsFiddle.
Highlight Active Menu Item on Menu Bar

Categories

Resources