Implementing toggles on more than one div - html

I have a div which I want to toggle show on button click.
Here's the HTML structure :
<div>
<button onclick="toggle()"> Show </show>
<div id="toggle"> </div>
</div>
The script for this would be :
var div = document.getElementById("toggle");
if(div.style.display=="none" ||div.style.display == ""){
div.style.display="block" }
else{
div.style.display="none";
}
This works fine but what I I have multiple button-div combo ? Obviously I will have to use different id for each div but how will I get this id inside the function ? Or is there any other way ?
Also is this the right way to do it ? Using multiple id's for each div ? Is there any other way to implement such a system?

function toggle(id) {
var div = document.getElementById(id);
if(div.style.display=="none" ||div.style.display == ""){
div.style.display="block" }
else{
div.style.display="none";
}
}
And in your HTML
<div>
<button onclick="toggle('toggle')"> Show </show>
<div id="toggle"> </div>
</div>

Related

Toggle Text between multiple buttons

I would like to have two buttons which are basically categories. Let's name them category A and category B. The are displayed left and right. Below i would like to display some text which is dependent of the chosen category (i.e the clicked button) so that category A shows text A and category B shows text B.
This if for html. I'm working on a wordpress homepage.
I was able to install one button which toggles text (basically button 1 = Category A). But i couldn't manage to insert a second button (basically button 2 = Category B). Any ideas? Highly appreciated!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Click the button to swap the text of the DIV element:</p>
<p><button onclick="myFunction()">Click Me</button></p>
<div id="myDIV">Hello</div>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.innerHTML === "Hello") {
x.innerHTML = "Swapped text!";
} else {
x.innerHTML = "Hello";
}
}
</script>
</body>
</html>
I expect to have 2 buttons which display 2 categories, the text should toggle according to which button has been clicked.
Could put the description in an attribute, then get the attributes value on click and change the html of the description. Here is a jsFiddle
<div>
<button class="js-button default-button" data-description="Category A's Description" onclick="myFunction(this)">
Category A
</button>
<button class="js-button default-button" data-description="Category B's Description" onclick="myFunction(this)">
Category B
</button>
</div>
<div id="js-description" class="description">
</div>
<script>
function myFunction(elem) {
var x = document.getElementById("js-description");
var description = elem.getAttribute('data-description');
x.innerHTML = description;
var button = document.getElementsByClassName('js-button');
for (var i = 0; i < button.length; i++) {
button[i].classList.remove('active-button');
}
elem.classList.add('active-button');
}
</script>
<style>
.default-button{
font-size:16px;
border-radius: 4px;
padding:7px 12px;
}
.active-button{
background:blue;
color:#fff;
}
.description{
margin-top:20px;
}
</style>
I don't really like all these solutions because everything is written from JS but contents probably come from database. So here is my solution :
// Native JS version
// Working Fiddle : https://jsfiddle.net/d34cbtw7/
var togglers = document.querySelectorAll('[data-toggle="tab"]');
for (var i = 0; i < togglers.length; i++) {
togglers[i].addEventListener('click', function() {
var tabs = document.querySelectorAll('.tab');
for(var j = 0; j < tabs.length; j++) {
tabs[j].classList.remove('active');
}
var $target = document.querySelector(this.getAttribute('data-target'));
$target.classList.add('active');
});
}
// jQuery version
$('body').on('click', '[data-toggle="tab"]', function(e) {
e.preventDefault();
// Select our target
var $target = $($(this).data('target'));
// Hide all tabs
$('.tab-contents .tab').removeClass('active');
// Show only $target tab
$target.addClass('active');
});
.tab-contents .tab {
display: none;
}
.tab-contents .tab.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-toggle="tab" data-target="#cat-A-content">
Cat A
</button>
<button data-toggle="tab" data-target="#cat-B-content">
Cat B
</button>
<div class="tab-contents">
<div class="tab active" id="cat-A-content">
My category A contents
</div>
<div class="tab" id="cat-B-content">
My category B contents
</div>
</div>
I also don't really like "onclick" attribute in HTML...
I've made a quick codepen as example.
You can achieve this by passing a parameter to the onClick function. In this example I keep track of the last button clicked, and the text it should render. If the last button clicked was the same button, the switched back to default. I hope this helps.
https://codepen.io/maffekill/pen/rbpjzw
HTML
<p>Click the button to swap the text of the DIV element:</p>
<p><button onclick="myFunction(1, 'TEXT A')">TEXT A</button></p>
<p><button onclick="myFunction(2, 'TEXT B')">TEXT B</button></p>
<div id="myDIV">Default Text</div>
JS
// Keep track of the button currently clicked
var activeBtn = null;
function myFunction(btnId, text) {
var x = document.getElementById("myDIV");
// If the last button is the same as the new one, show default text
if (activeBtn === btnId) {
x.innerHTML = "Default Text";
activeBtn = null
} else {
// Else show the text given to the text param
x.innerHTML = text;
activeBtn = btnId;
}
}
There are multiple ways to achieve this, but the easiest way I could come up with to explain this to you would be as following:
function myFunction(myEle) {
var x = document.getElementById("myDIV");
x.innerHTML = "This is category " + myEle.value;
}
<p>Click the button to swap the text of the DIV element:</p>
<p>
<button onclick="myFunction(this)" value="a">
Category A
</button>
<button onclick="myFunction(this)" value="b">
Category B
</button>
</p>
<div id="myDIV">Hello</div>
JSFiddle
No need to overcomplicate things.
Firstly you would like to send the clicked element from the caller (which in this case would be the clicked element as well, the <button> element). You could use JavaScript's thisfor this purpose.
Within your function you can name a parameter between parenthesis, so in my example above: function myFunction() contains a parameter called myEle so it will look like: function myFunction(myEle). Once the function will be triggered, the parameter called myEle will be set to the clicked element (or
JavaScript's this). You can simply access any of its attributes like value by using a dot: myEle.value.
Knowing the above, you could apply it to whatever you require your function to do (refer to my example code above).

*ngIf & Jquery acting weird - Angular 5

I'm trying to use expand-collapse feature of bootstrap 4 and was encountering a weird issue with the use of *ngIf for expansion and collapse.
Whenever I try to use *ngIf as follows, the jquery doesn't work but works when *ngIf is deleted.
HTML:
<div class="collapse-group">
<div class="row">
<div class="col-md-7" id="row">
<div id="link_text_div" *ngIf="this.collapseExpandArrowFlag==true">
<span id="collapse_all" class="close-button" (click)="arrowFunc($event)" style="cursor: pointer;" >
Collapse all
</span>
</div>
<div id="link_text_div" *ngIf="this.collapseExpandArrowFlag==false">
<span id="expand_all" class="open-button" (click)="arrowFunc($event)" style="cursor: pointer;"
>
Expand all
</span>
</div>
</div>
</div>
</div>
.Ts:
collapseExpandArrowFlag = true;
arrowFunc(event) {
if(event.srcElement.id === "collapse_all") { //On-Click Collapse Logic
this.collapseExpandArrowFlag = false;
$(".close-button").on("click", function() {
$(this).closest('.collapse-group').find('.multi-collapse').collapse('hide');
});
}
if(event.srcElement.id === "expand_all") {
this.collapseExpandArrowFlag = true;
$(".open-button").on("click", function() {
$(this).closest('.collapse-group').find('.multi-collapse').collapse('show');
});
}
Try to remove "this" in the ngIf like this:
*ngIf="collapseExpandArrowFlag==true"
Please remove the 'this.' from the *ngIf and just write
*ngIf="collapseExpandArrowFlag"
If this not working , try to change *ngIf to
[hidden]="collapseExpandArrowFlag"
and
[hidden]="!collapseExpandArrowFlag"
This will add the element and the event on the dom on load time. and will keep it there (with a display : none property in css).
Plus take into consideration how you need to work with external library code like JQuery.
See references:
Use jQuery script with Angular 6 CLI project
Change you ts file as follows
collapseExpandArrowFlag = true;
arrowFunc(event) {
if(event.srcElement.id === "collapse_all") { //On-Click Collapse Logic
this.collapseExpandArrowFlag = false;
$(this).closest('.collapse-group').find('.multi-collapse').collapse('hide');
}
if(event.srcElement.id === "expand_all") {
this.collapseExpandArrowFlag = true;
$(this).closest('.collapse-group').find('.multi-collapse').collapse('show');
}
What's happening here is, when you click the button, inside ts code,
this.collapseExpandArrowFlag = false;
is called, and in the template the close-button is removed.
But in the very next line of ts code,
$(".close-button")
is called, But in this state that element is removed from the DOM
And make sure you've removed this. from *ngIf statements

How can i change the innerHTML content when clicking on an image?

I'm quite new in coding, trying to educate myself because i'm interested. So, sorry if it's going to be a bit dumb question or not so specific or not really correct...
On my "practicing site" i'm having some navigation links, which are referring to different innerHTML contents (like different pages). I used the 'onClick' event to make them show up, for example like this:
<div class="nav" onClick="changeNavigation('a')">menu</div>
It works with texts perfectly, but my problem is that i don't know how to make the same with an image. So when i click on the image, i want to be redirected to that innerHTML page, like i did it with the text based button. I tried to do it like these two ways, but none of them worked.
<img src="picture.png" onClick="changeNavigation('a')" />
<div onClick="changeNavigation('a')"><img src="picture.png"></div>
Is it possible to make this with an image and the 'onClick' event? Or how else can i make this work?
By the way this is my script to make innerHTML show up:
<script>
function changeNavigation(id) {
document.getElementById('main').innerHTML = document.getElementById(id).innerHTML
}
</script>
I also tried to add my image an id that says 'main' like in the script this way, but with no result.
<img id="main" onClick="changeNavigation('f')" src="picture.png" />
Can you help me please? I would appreciate any answer, because i already searched about this and i didn't find anything that could've helped solve my problem and i'm really stuck right now.
(Sorry if my english isn't the best, it's not my native language.)
I have updated my answer to what you want. You need to the divs id you want to display as a parameter to the function you use for onclick. A sample is below.
var divs = ["Menu1", "Menu2", "Menu3", "Menu4"];
var visibleDivId = null;
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
.main_div{text-align:center; background: #00C492; padding:20px; width: 400px;}
.inner_div{background: #fff; margin-top:20px; height: 100px;}
.buttons a{font-size: 16px;}
.buttons a:hover{cursor:pointer; font-size: 16px;}
img {cursor:pointer}
<div class="main_div">
<div class="buttons">
<img src="http://www.clker.com/cliparts/J/g/2/D/p/I/one-hi.png" width="50px" onclick="toggleVisibility('Menu1');"> <img src="http://www.clker.com/cliparts/E/x/J/x/m/z/blue-number-two-hi.png" width="50px" onclick="toggleVisibility('Menu2');">
<img src="http://www.clker.com/cliparts/L/H/T/b/g/N/three-md.png" width="50px" onclick="toggleVisibility('Menu3');">
<img src="http://www.clker.com/cliparts/v/G/G/A/D/s/four-md.png" width="50px" onclick="toggleVisibility('Menu4');">
</div>
<div class="inner_div">
<div id="Menu1">I'm container one</div>
<div id="Menu2" style="display: none;">I'm container two</div>
<div id="Menu3" style="display: none;">I'm container three</div>
<div id="Menu4" style="display: none;">I'm container four</div>
</div>
</div>
You can just keep all of the sections as children of #main, and selectively show them when the section button in clicked. E.g.,
HTML
<nav>
<button type="button" data-index=0>Show one</button>
<button type="button" data-index=1>Show two</button>
<button type="button" data-index=2>Show three</button>
</nav>
<main id="main">
<section>One</section>
<section class="hidden">Two</section>
<section class="hidden">Three</section>
</main>
CSS
.hidden {
display: none;
}
JavaScript
const buttons = Array.from(document.querySelectorAll('button'));
const contentBlocks = Array.from(document.querySelectorAll('section'));
function hideSections (arr) {
arr.forEach(a => {
a.classList.add('hidden');
});
}
function showSection (index, sections) {
// Just a basic check, not exhaustive by any stretch
if (index !== undefined && sections !== undefined) {
hideSections(sections);
sections[index].classList.remove('hidden');
}
}
buttons.forEach(button => {
button.addEventListener('click', () => {
const contentBlocks = Array.from(document.querySelectorAll('section'));
const index = button.getAttribute('data-index');
showSection(index, contentBlocks);
});
});
Obviously you'll have to adjust your selectors for your use case, but Here's a pen
Here's a GitHub Gist pointing to some examples I created on JSFiddle based off of your specific use case (Stack Overflow doesn't let me post links to JSFiddle directly without including code here, but it's easier to follow along/experiment entirely in JSFiddle):
https://gist.github.com/andresn/f100386f06ee28e35bd83c62d9219890
More advanced stuff:
Ideally, you'd use what's called event delegation instead of adding an onclick to every anchor (DRY = Don't Repeat Yourself is good to always keep in mind while programming and so is KISS = Keep It Simple Silly). Here is a resource explaining event delegation:
https://davidwalsh.name/event-delegate
You can even take this further by preloading all your images so they load behind the scenes when the user first loads the page:
https://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Disable a div in AngularJS with ng-click property?

I need to disable a div in AngularJS depend on a condition. Yes I can do it by using css change (giving low contrast and less color appearance) in appearance but I have ng-click property in it. So I need to prevent that calling also. How can I do it?
Here is my code:
<div ng-repeat="item in list.items" ng-click="goToFunction()" ng-disabled="true">
Yes ng-disabled does not work for div. It will for each html element which support the disable property (eg : input).
https://docs.angularjs.org/api/ng/directive/ngDisabled
I created a simple fiddle to demonstrate how to achieve it with a simple div http://jsfiddle.net/5Qc5k/1/
function MyCtrl($scope, $templateCache) {
$scope.isDisabled = false;
$scope.alertMe = function(){
if($scope.isDisabled === true){
return;
}
// disable the function
$scope.isDisabled = true;
alert("foo");
}
}
You can do that in controller ie:
<div ng-repeat="item in list.items" ng-click="goToFunction(item)" ng-disabled="true">
and after that in controller:
function goToFunction(item){
if(item.condition == disable){
return false
}
else {
// do something
}
}
To prevent the ng-click functionality based on disable you can do in following:-
<div ng-repeat="item in list.items" ng-disabled="item.condition" ng-click="goToFunction(item)">
item.value
</div>
$scope.goToFunction = function(item){
if(item.condition == false){
// Dont do anything
}else{
//do something
}
In this scenario when div is disabled, click functionality wont do anything, otherwise it will do.

multistep form - toggle between styled radio buttons

i have built a multi step form that works , but it is not very "elegant" coded,
so i am asking
for your advice to make it more efficient ,
i have placed here only 2 steps out of 3 because the first step - email name etc', is not relevant for my question:
in each step 2 and 3 there are 2 styled radio button yes and no for the user to select,
in each step i need to toggle between check and uncheck styled images and of course prevnt that both
yes and no check images will show at the same time.
i know that the default/not styled radio buttons behavior prevents two checked buttons at the same time- can i use it here to save some lines of code?
the html(index.php)
<form method="post" id="userForm" action="process_form.php">
<fieldset class="formFieldset">
<div id="second_step" class="vanish">
<div class="form slide_two check_wrap">
<div class="quizyes quizbtn">
<img class="uncheck_pic pic one" src="images/check_not.png">
<img class="check_pic pic agree" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">yes</h1>
</div>
<div class="quizno quizbtn">
<img class="uncheck_pic pic two" src="images/check_not.png">
<img class="check_pic not not_agree pic first_not" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">no</h1>
</div>
<div id="feedback_wrap"><div class="feedback"></div></div>
<div id="submit_wrap" >
<input type="radio" class="yep decideOne" val ="1" name="yep" style="display: none;"/>
<input type="radio" class="nope decideOne" val ="2" name="nope" style="display: none;"/>
</div>
</div></div>
<!-- end of second step -->
<!-- third step -->
<div id="third_step" class="vanish">
<div class="form check_wrap">
<div class="quizyes quizbtn">
<img class="uncheck_pic pic one" src="images/check_not.png">
<img class="check_pic pic agree" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">yes</h1>
</div>
<div class="quizno quizbtn">
<img class="uncheck_pic pic two" src="images/check_not.png">
<img class="check_pic not not_agree pic second_not" src="images/check_bgfull.png" style="display: none;">
<h1 class="quizText">no</h1>
</div>
<div id="feedback_wrap"><div class="feedback"></div></div>
<div id="submit_wrap">
<input type="radio" class="yep decideTwo" val ="1" name="yep" style="display: none;"/>
<input type="radio" class="nope decideTwo" val ="2" name="nope" style="display: none;"/>
</div>
</div></div>
<!-- end of third step -->
</fieldset>
<div id="submit_wrap">
<input class="submit btn" type="button" name="submit_all" id="submit_all" value="" />
</div>
</form>
the script
$(document).ready(function(){
$(function() {
$('.check_pic').hide();
//original field values
var isDecide= false;
//toggle images and set values
$('.pic').on('click', function(event) {
if ($(this).hasClass('uncheck_pic') && $(this).hasClass('one') ){
$(".yep").val('agree');
$(this).hide();
$(this).siblings('.check_pic').show();
$(".not").hide();
$(".two").show();
}
else if ($(this).hasClass('uncheck_pic') && $(this).hasClass('two') ){
var isDecide = $(".nope").val('notagree');
$(this).hide();
$(this).siblings('.check_pic').show();
$('.agree').hide();
$(".one").show();
}
else if ($(this).hasClass('check_pic') && $(this).hasClass('agree') ){
$(this).hide();
$(this).siblings('.uncheck_pic').show();
}
else if ($(this).hasClass('check_pic') && $(this).hasClass('not_agree') ){
$(this).hide();
$(this).siblings('.uncheck_pic').show();
}
});
// start the submit thing
$('#submit_all').click(function() {
if($('#second_step').is(":visible")) {
$('.decideOne').removeClass('error valid');
// prevent empty boxes and display a message
if($('.one').is(":visible") && $('.two').is(":visible")) {
$('.feedback').text('please select one').show();
return false;
}
// case the user selects yes
if($('.agree').is(":visible")) {
$('.feedback').text('thank you for selecting yes').show();
var isDecide = $(".yep").val();
var name = $("#firstname").val();
var phone = $("#phone").val();
var email = $("#email").val();
var dataString = 'user-details:name=' + name + ' phone=' + phone + ' email=' + email + ' decide=' + isDecide ;
$.ajax({
type : "POST",
url : "/",
data: dataString,
success : function(data) {
console.log('data');
$('#second_step').delay(1000).fadeOut(600, function() {
$('#first_step').fadeIn(400);
$('.feedback').hide();
});
}
});
}
// case the user selects no
if($('.first_not').is(":visible")) {
$(".yep").val();
$(".nope").val();
$('#second_step').fadeOut(600, function() {
$('#third_step').fadeIn(600);
$('.feedback').hide();
});
}
return false;
// end second step
} else if($('#third_step').is(":visible")) {
$('.third_input').removeClass('error').removeClass('valid');
// prevent empty boxes and display a message
if($('.quizyes .one').is(":visible") && $('.quizno .two').is(":visible")) {
$('.feedback').text('please select one').show();
return false;
}
// if decide yes then submit
if($('.agree').is(":visible")) {
$('.feedback').text('thank you for selecting yes').show();
var isDecide = $(".yep").val();
var name = $("#firstname").val();
var phone = $("#phone").val();
var email = $("#email").val();
var dataString = 'user-details:name=' + name + ' phone=' + phone + ' email=' + email + ' decide=' + isDecide ;
$.ajax({
type : "POST",
url : "/",
data: dataString,
success : function(data) {
console.log('data');
$('#second_step').delay(1000).fadeOut(600, function() {
$('#first_step').fadeIn(400);
$('.feedback').hide();
});
}
});//end ajax
return true;
}//end if agree is visible
// if decide no then send message and quit
if($(".second_not").is(":visible")) {
$(".nope").val("no");
$('.feedback').text('too bad bye bye').show();
$('#third_step').fadeOut(3000, function() {
$('#first_step').fadeIn(600);
$('.feedback').hide();
});
}
}
// end third step
});
//end submit_all
}) // general function
}); // document ready
Dude my wish to you take a look on good js library - knockout to represants all that kind show, hide functunality and forms inputs, checkbox, radiobutton modifications.
If you're using images to style your radiobuttons I would suggest combining the images into a Sprite and just using css to move the background-position of the image using the input[type=radio]:checked selector. No javascript necessary.
For Example - you combine your two images into a single image that is 100px wide, each individual image being 50px wide. And then style the checkbox...
input[type=radio].myCustomRadioButton {
background: url(myRadioButtonSprite.png) 0 0;
}
input[type=radio].myCustomRadioButton:checked {
background-position: -50px 0;
}
Assuming your images are lined up horizontally in your sprite, this would move the background image of the radiobutton left 50px to display the checked-image, when the radiobutton is checked.
As a side note, doing this is going to require unsetting some of the browser styling that is going to occur automatically. A good reset for form elements is to start with these styles.
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
Keep in mind if you need to support Internet Explorer versions less than 9, the :checked pseudo-selector isn't available in pure CSS and you may need to resort to some scripting.
Listen for the change event on your custom radio buttons and update a parent element based on that.
Here's an example.
The <input> has position: absolute so the clip property can be applied to hide it and it does not affect the content box of its parent, which has relative position to contain it.
I used background-color but you could swap this in for your image urls or change the background-position of a sprite as suggested in rob-gordon's answer.
You can still add visible label text inside the label as you see in the second set of radio inputs.