Well it seems I know enough Javascript to hurt myself so I come asking help from you guys here. Here is what I am attempting to do and my issue.
I have two forms and only one will be filled out depending on the users choice. They will click one button or the other. When they click the button the form fades in and the button changes classes (goes from a light button to a dark button) Here is were I am running into issues. First I cannot get the form to fade in at all and the buttons will only change classes if I click them twice not once.
One other thing I am not sure how to go about is if I have say form 1 chosen but I meant to click form 2 then I want form one to fade out, form 2 to fade in and the buttons change accordingly. Here is my Code:
JS
<script type="text/javascript">
var $j = jQuery.noConflict();
var $jtest1 = $j('#test1');
var $jtest2 = $j('#test2');
$j("#button1").live('click',function(){
//Fade out form if shown and fade in form selected
$jtest2.fadeOut("slow", function(){
$jtest1.fadeIn("slow");
});
$j('#button1').live('click', function(){
//change class from light to dark
$j(this).addClass('dark_button').removeClass('light_button');
}); //I need to change this class to light if
// button 2 is selected and change button 2 to dark
});
</script>
HTML
<p class="light_button" id="button1">Test 1 </p>
<p class="light_button" id="button2">Test 2 </p>
<div class="hide" id="test1"><p>TEST</p></div>
<div class="hide" id="test2"><p>TEST 2</p></div>
Note: class="hide" is style="display:none"
Thanks for any help because I am a but stuck and not sure to go about this. Also please give me an example because I do not always follow when someone say change this to that etc.
Look at the code below, added comments on why
$j("#button1").live('click',function(){
//Fade out form if shown and fade in form selected
$jtest2.fadeOut("slow", function(){
$jtest1.fadeIn("slow");
});
//The following is inside the click so I do not get added until the first click
//and added after every click so I multiply!
//Hence why it takes 2 clicks
$j('#button1').live('click', function(){
//change class from light to dark
$j(this).addClass('dark_button').removeClass('light_button');
}); //I need to change this class to light if
// button 2 is selected and change button 2 to dark
});
You should be doing something like this
$j("#button1, #button2").live('click',
function(){
//figure out what button was clicked.
if(this.id === "button1"){
var btnA = $j(this);
var btnB = $j("#button2");
var divA = $j('#test1');
var divB = $j('#test2');
}
else{
btnA = $j(this);
btnB = $j("#button1");
divA = $j('#test2');
divB = $j('#test1');
}
//make sure it is not already active, no use to show/hide when it is already set
if(btnA.hasClass('dark_button')){
return;
}
//see if div is visible, if so hide, than show first div
if(divB.is(":visible")){
divB.fadeOut("slow", function(){
divA.fadeIn("slow");
});
}
else{//if already hidden, just show the first div
divA.fadeIn("slow");
}
//Add and remove classes to the buttons to switch state
btnA.addClass('dark_button').removeClass('light_button');
btnB.removeClass('dark_button').addClass('light_button');
}
);
jsfiddle example
Related
I'm having some problems getting this page to work like I need it to. I finally got it to where it'll only allow 1 of the 9 sections open at a time but I can't get these sections to toggle open and close using the same trigger button. If these could have some sort of transition as well, such as sliding open and close, that would be great too. I'm just learning jquery and finally at a point where I should just ask the experts.
https://toyotechus.com/expanding-rows/ is the page I have this set up on.
This is the code I'm using. I have the initial script repeated for all 9 sections and the toggle code below it all.
<script>
( function( $ ) {
'use strict';
$( document ).ready( function() {
var $trigger = $( '.open-vc-row-auto1' );
var $hiddenRow = $( '.vc-row-auto1' );
if ( $hiddenRow.length ) {
$trigger.click( function() {
$hiddenRow.toggle();
return false;
} );
}
} );
} ( jQuery ) );
</script>
<script>
$(".togglerowlink").on("click", function(e) {
var target = $(this).attr("href");
$(target).slideToggle('slow');
$(".vc-row-auto").not(target).hide();
e.preventDefault();
});
</script>
Ideally this toggle would open AND close the section, not just open it. Also I believe it should be sliding open and closed between section changes and it's not.
So it looks likes you wrote individual script blocks to open and close each panel. 9 panels = 9 script blocks. This code opens and closes the rows properly, but doesn't close all the other ones, so you can have 2 or 3 rows open at the same time. This is BAD because you're repeating code over and over again, and making it difficult to change in the future.
But then you did a great thing!! You tried to write a SINGLE script block to close any panel that shouldn't be open. That's the right idea, and you should apply it to every panel.
Problems first:
This line doesn't work because you don't have href attributes on
your HTML elements: var target = $(this).attr("href"); So target === undefined and this does nothing.
You're being too specific with your selectors. This var $trigger = $( '.open-vc-row-auto9' ); is far far too specific to be reused for all the elements. That's why you have to write it 9 times. :(
Solutions - this will require a little html refactoring, but lets list our goals.
Write one piece of code to manage all buttons. It should apply the click handler to ALL buttons, and when a button is clicked, we should know what specific panel that button is trying to target.
Write HTML generic enough to allow for Goal 1 to be achieved. We will use data- attributes to identify buttons, and their corresponding panels.
<style>
.panel { display: none; }
</style>
<!-- buttons -->
<button class="btn" data-target="panel-1">Show Panel 1</button>
<button class="btn" data-target="panel-2">Show Panel 2</button>
<button class="btn" data-target="panel-3">Show Panel 3</button>
<!-- panels -->
<div class="panel" data-panel="panel-1"><h1>This is panel 1.</h1></div>
<div class="panel" data-panel="panel-2"><h1>This is panel 2.</h1></div>
<div class="panel" data-panel="panel-3"><h1>This is panel 3.</h1></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function(){
// select all buttons
// get their target
// if target is open, close it
// if target is closed, open it, and close all others
$('.btn').click(function(e){
e.preventDefault();
var btn = $(e.target);
var target = btn.attr('data-target'); // panel-1, panel-2, etc.
var target_panel = $('[data-panel="'+target+'"]'); // css attribute selector
var targetIsVisible = target_panel.css('display') === 'block'; // display: block; means it's visible ;)
if (targetIsVisible === true){
target_panel.slideUp(); // show the one we want
} else {
$('.panel').hide(); // hide all panels that may or may not be open
target_panel.slideDown(); // show the one we want
}
});
});
</script>
JS FIDDLE DEMO
You'll need to apply the concepts to your code, it's not a perfect copy/paste fix. Good luck. You got this!
I have several buttons including divs which they have the same name. unfortunately I can not change the names, they are generated by cms.
So for example when I click only on first button, only the first div is hidden or displayed, and that's fine.
But after refresh page it opens or closes all divs depending is the first div closed or opened, and that I do not want it.
here is the code:
<button class="a">Button</button>
<div class="target"></div>
<button class="a">Button</button>
<div class="target"></div>
$('.a').click(function() {
$(this).next(".target").slideToggle(function() {
localStorage.setItem('visible', $(this).is(":visible"));
});
});
$('.target').toggle(localStorage.getItem('visible') === 'true');
here you can see jsfiddle example: https://jsfiddle.net/pj3gs0z9/3/
So my question is, is it possible to store only clicked button information, and after page refresh display or hide div from only clicked button ?
Thank you
It is possible, but probably not in your case. If you tell us you can't change your button properties, and they are exactly the same, then you won't be able to store different data in your localStorage.
Isn't there any way where you can add some additional information to your button ? It could be a class, an id, a name, or even a data-XXX attribute.
By the way, how are your buttons generated ? are they hard coded, or fetched from a database, or ... ?
EDIT
Here is a way of adding different classes to all of your buttons (althoguh I recommend adding data attributes, but whatever floats your boat) :
let buttons = document.getElementsByTagName('button'); // Array of your buttons
let index = 0;
for (let button of buttons) {
button.className += 'myCustomClass-' + ++index; // Add a custom class to your buttons
}
// Now in your local storage, you can store the class of the button !
EDIT 2 I would store it like this :
// On click, in VanillaJS (sorry, haven't used JQuery in a while)
button.onclick = () => {
let visibleButtons = localStorage.getItem('visible-buttons') || [];
visibleButtons.push(button.className.match(/(myCustomClass-[0-9]*)/)[0]);
}
This is one quick solution, but because of a slideToggle you gonna have a small flash of milliseconds of a visible div unless you first have them hidden and then based on localStorage display them.
$('.a').click(function() {
$(this).next(".target").slideToggle(function() {
localStorage.setItem('visible-' + $(this).index(), $(this).is(":visible"));
});
});
$.each($('.target'), function(k, trg) {
$(trg).toggle(localStorage.getItem('visible-' + $(trg).index()) === 'true');
});
I have a WP page with a main div area and 2 buttons above it.
I have some JS which is meant to:
On page load, show a list type view of posts in the main div
When you press the 'gallery view' button, swap that main div content to the gallery view and hide the list view
when you press the list view button, swap the main div content back to the list view and hide the gallery view
Further pressing them continues to swap the div content
The JS I have nearly works. On page load it shows the list content. However on the first press of the gallery button, it doesn't hide the list view. But if you then press the list view button again, it works and the gallery view does get hidden and then further presses of buttons, it continues to work as it should.
It's just that first div switch where it doesn't hide the div that's the issue.
Here's the relevant JS, CSS and HTML:
JS:
<script>
var _targetdiv = null;
function showdiv(id) {
if(_targetdiv)
_targetdiv.style.display = 'none';
_targetdiv = document.getElementById(id);
_targetdiv.style.display = 'block';
}
</script>
CSS:
.hidden {
display: none;
}
HTML:
<div id="project-view-controls">
<a onclick="showdiv('project-image-archive');" id="project-gallery-btn" class="project-hide-btn">Link</a>
<a onclick="showdiv('project-list-archive');" id="project-list-btn" class="project-hide-btn">Link</a>
</div><!-- #project-view-controls -->
<div id="project-image-archive" class="hidden">
<p>Image view view here</p>
</div><!--#project-image-archive-->
<div id="project-list-archive">
<p>list view here</p>
</div><!--#project-list-archive-->
I'm not sure why it's just not working on the first instance of the button being pressed but it works after that.
Any help would be greatly appreciated!
The first thing I want to answer, is your question, why it is not working on the first button click. Its pretty simple, so lets have a look at your JS.
var _targetdiv = null;
function showdiv(id) {
if(_targetdiv)
_targetdiv.style.display = 'none';
_targetdiv = document.getElementById(id);
_targetdiv.style.display = 'block';
}
First you set the _targetdiv to NULL. The first time you click on a button and your function showdiv is called. The first time you call this function your if-statement is false, cause _targetdiv is null, so your code jumps to the next line _targetdiv = document.getElementById(id); and execute it, so _targetdiv is now set and will be displayed. So the second time you call this function _targetdiv is still set, so it can be hidden trough your code, cause your if-statement is true.
I would change your Javascript to something like this:
function showdiv(obj){
// First set both elements invisible, so nothing is displayed
document.getElementById('project-image-archive').style.display = 'none';
document.getElementById('project-list-archive').style.display = 'none';
// Now show only the div that is requested
document.getElementById(obj).style.display = 'block';
}
What the Javascript now does is, it hides both elements, so that nothing is displayed and directly after that it takes the id from the given object and displays it.
I hope this helps you a bit.
Here's what I have so far, which allows the user to click an image to open a new window and go to a location. When that click occurs, the image in the parent window is replaced with the next div.
Example: http://jsfiddle.net/rzTHw/
Here's the working code so far...
<div class = "box"><img src="http://placehold.it/300x150/cf5/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/f0f/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/fb1/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/444/&text=img+1"></div>
Jquery:
$('.box').not(':first').hide();
$('.box a').click(
function(e){
e.preventDefault();
var newWin = window.open(this.href,'newWindow'),
that = $(this).closest('.box'),
duration = 1200;
if (that.next('.box').length){
that.fadeOut(duration,
function(){
that.next('.box').fadeIn(duration);
});
}
});
What I am having trouble with is:
Creating a "next" button so the user can cycle through to the next div without having the click the image, thus avoiding having to open a new window to get to the next image.
Having a click on the last div redirect the window location to a URL, while still doing the normal function of opening a new window to the a href location if the image is clicked. Otherwise if clicking the "next" button when the last div is shown, simply redirect the user.
What's the best way to go about this? Thanks!
Here is my attempt at tweaking your code to allow for a next button, and my best guess at what you want to happen for the last image:
var redirectUrl = 'http://www.google.com'; // replace in your code
function next(event, duration) {
duration = duration || 1200; // default value
var that = $('.box:visible');
if (that.next('.box').length) {
that.fadeOut(duration, function() {
that.next('.box').fadeIn(duration);
});
} else {
window.location.href = redirectUrl;
// the above line doesn't work inside jsFiddle, but should on your page
}
return false;
}
$('.box').not(':first').hide();
$('.box a').click(
function(e) {
e.preventDefault();
var newWin = window.open(this.href, 'newWindow'),
duration = 1200;
next(e, duration);
});
$('.next').click(next);
jsFiddle example here. Note the redirect is prevented in some browsers since it is running inside an iframe. But it should work in a normal page.
Perhaps look at a slideshow jquery plugin. JQuery Cycle being just one example. There are plenty. Just google jquery Slideshow or jquery cycle and pick the one that suites you best. The cycle plugin itself has a number of "pager" examples that let you change the contents of the displayed picture without leaving the page.
Most of them offer having the contents be html and not just a simple picture so you can play around with what exactly you want.
There's also Fancybox, lightbox, colorbox, etc. if that's what you're trying to accomplish.
Basically I have three images (call them img1, img2, img3) with three menus associated with each. (menu1, menu2, menu3)
When a user clicks img1, menu1 should pop up with three radio button selections (rad1, rad2, rad3). Say the user clicks rad2, menu1 should then hide and img2 should appear (but rad2 should still be selected). When img2 is clicked, menu2 then should show up with rad2 selected. Then if rad3 is clicked, menu2 hides and img3 shows up (but rad3 is still selected). And so on and so forth.
How to code this in javascript?
Here is an example of how to show a hidden div by clicking on an image.
<script language="javascript">
function showDiv() {
mydiv = document.getElementById('div1');
mydiv.style.display = 'block';
}
</script>
<div id='div1' style="display:none;">
<!-- content -->
</div>
<img src='img.gif' onclick='showDiv();'/>
It should be as easy as:
function img1clk() {
menu1div.style.display = "block";
}
function menu1radclk() {
menu1div.style.display = "none";
img1div.style.display = "block";
menu2div.style.display = "block";
}
and so on. You will have to initialize the elements so their onClick property is pointing to the correct function, but thats simply
img1div.onclick = ing1clk();
or in html
<div onclick="img1clk()"><img src="..."></div>
Hope this helps ya!
This becomes pretty easy if you use jQuery's built-in methods, such as show() or hide(). Don't re-invent the wheel and all that :)
If all 3 menus are essentially the same but just look different why not bring up the same menu every time but change its css class?
Also, I couldn't agree more that jQuery is the way to go. The jQuery site's own documentation I find a bit lame, but once you've got around the basics it's really intuitive.