Conditional link with Javascript on Wordpress - javascript

I am trying to create a conditional link based on the width of the window. It's possible there's a better way to do this that I haven't thought of.
There is a horizontal row of square "buttons" with image icons and titles, and when clicking one of the buttons, a small info window drops below the row of "buttons." I used this Javascript for that:
jQuery(function($)("#individuals-full a").click(function(e){
e.preventDefault();
jQuery(".toggle").hide();
var toShow = jQuery(this).attr('href');
jQuery(toShow).show();
});
The problem is that, because there are so many buttons, which collapse to a vertical row on mobile view, it is impractical. The reason being that the "info" window is below all the buttons here, which creates an issue for the user having to scroll very far, and possibly not being aware that there even is a window below all the buttons.
What I would like to do is create a link for every button, which goes to a separate page (one for each button), if the window width is below a certain amount (let's say 700px), rather than displaying the "info" window below all the buttons.
Here is the HTML for the div with all the buttons, but shortened to just include the code for one of the buttons:
<div id="individuals-full"><h1 style="text-align: center;">We assist individual clients to find personalized solutions involving:</h1>
<ul>
<li><div id="fiance" class="individual-icons"><img class="aligncenter size-medium wp-image-1268" src="finance-visas-01- 300x300.png" alt="" width="300" height="300"><h1 style="text-align: center;">Fiancé Visas</h1></div></li>
</ul>
</div>
<div id="info-panel">
<div id="fiance-content" class="toggle" style="display:none"><hr/>
<h2>Best If You Want to Avoid a Long Separation</h2>
When the most important thing is for a couple to be together as quickly as possible, then the fiancé visa usually delivers.  The average processing time (and thus, a good estimate of the period of separation from each other) is 6-8 months, the period from application to admission to the U.S.
</div>

I take it that it's your e.preventDefault(); that's stopping the proper click function so just reinstate it when you're on mobile.
Get the width of the window, then within your function add an if statement to check if the window width is bigger than mobile, if it is then run this function. If you're on mobile, it'll get skipped.
var viewportWidth = jQuery(window).outerWidth();
jQuery(function($)("#individuals-full a").click(function(e){
if ( viewportWidth > 768 ) {
e.preventDefault();
jQuery(".toggle").hide();
var toShow = jQuery(this).attr('href');
jQuery(toShow).show();
}
});

Related

Issue with handling a form using javascript

We have a website hosted at hubspot, we use their native WYSIWYG to design layouts then style them with css and js.
On the homepage http://www.lspatents.com/ it used to have a form under the "Get started here" title, it had around 10 questions, and used javascript to split them to steps so they can fit in the same area on the currently shown blank box.
It was working just fine till two days ago the form disappeared and left it with a blank area as you can see now, and as far as i know no one has touched this code recently.
Here is the js code that was used to manipulate the form
// Hero Form
$(window).load(function() {
// disable autocomplete to fix bug
$('.hero-form form').attr("autocomplete", "off");
$('.hero-form .hs-richtext').each(function() {
$(this).nextUntil('.hs-richtext').wrapAll('<div class="step" />');
});
// Hide Loading icon
$('.hero-form form').css('background', 'none');
$('.hero-form form .step:nth-of-type(2)').show();
// First Step to Second Step
$('.step').find('.hs-richtext').change(function() {
$('.step:nth-of-type(2)').hide().next().next().fadeIn();
});
// Second Step to Third Step
$('.step').find('.hs-input').change(function() {
var names = {};
$(':radio').each(function() {
names[$(this).attr('name')] = true;
});
var count = 0;
$.each(names, function() {
count++;
});
if ($(':radio:checked').length === count) {
$('.step:nth-of-type(4)').hide().next().next().fadeIn();
}
});
});
As far as i was able to tell, the developer used css to hide the whole form area with display:none; and used the js above to split the questions to steps and show a certain number in each step.
You can see the code being called in the footer so there is no problem with the link to the .js file, also if you inspect the element and disable the display:none; that's declared for any of the divs within the hero-form all questions get displayed, so there is no problem with the form either, so why has it stopped working?
Would appreciate any help,
This line will no longer work with your mark-up...
$('.hero-form form .step:nth-of-type(2)').show();
There are a number of additional divs that wrap your mark-up, placed there by react, React has placed a series of div inside your form which are being hidden by your existing CSS (which I assume used to just be a series of STEP's)
The CSS that hides the nodes is :
.hero-form form>div, .hero-form form>.step {
display: none;
}
The nodes that are being hidden with display:none
<div data-reactid=".0.0:$1">
<div class="hs-richtext" data-reactid=".0.0:$1.0">
<hr>
</div>
<div class="step">
<div class="hs_patent field hs-form-field" data-reactid=".0.0:$1.$patent">
<label placeholder="Enter your Do you have a patent?" for="patent-9fc8dd30-a174-43bd-be4a-34bd3a00437e_2496" data-reactid=".0.0:$1.$patent.0">
<span data-reactid=".0.0:$1.$patent.0.0">Do you have a patent?</span>
<span class="hs-form-required" data-reactid=".0.0:$1.$patent.0.1">*</span>
</label>
<div class="hs-field-desc" style="display:none;" data-reactid=".0.0:$1.$patent.1">
</div>
</div>
Your JQuery will add display:block to the DIV with the class 'step' bit wont alter the parent DIV (inserted by React) which still prevents your node from being shown.
You need to alter you JQuery to call show() on the parent() that contains the "step" div you wish to show.
Please check your browser console ans see you have problem loading this form:
https://forms.hubspot.com/embed/v3/form/457238/9fc8dd30-a174-43bd-be4a-34bd3a00437e
and this is the error:
net::ERR_NAME_RESOLUTION_FAILED
It's better you change your DNS to something like 8.8.8.8 and see if the problem still exists or not.

How to get the div behind the div i clicked

Please take a look here at what I'm trying to achieve: http://jsfiddle.net/3m6r7ud2/4/
I have the following html page that looks like this:
<div class="page_conatiner" id="page1">
<img src=$file1>
<div class="page_conatiner" id="page2">
<img src=$file2>
<div class="page_conatiner" id="page3">
<img src=$file3>
And so on.
I also have a fixed button that shows up on hover:
<div class="rotate_button" id="rotate_left" ></div>
<div class="rotate_button" id="rotate_right" ></div>
This is the jQuery I'm using:
$(document).on("click", ".rotate_button", function(){
var direction = $(this).attr("id");
var page_num = ?
rotate_file(page_num,direction)
})
The buttons are in fixed locations on the page, and show on hover. When clicking on this button, I want to get which div was behind that div while clicking
so I could know which of the pages I need to rotate.
How can I do this?
First, I'm not certain what animation you are going for, but there might be a jQuery widget that will do what you want out of the box. Idk. The bootstrap one is handy, but maybe all of bootstrap is more than you want: http://getbootstrap.com/javascript/#carousel.
To answer your question: I would set a variable somewhere that keeps track of the current page num. Set it to 0 (or 1 if that's the first page number) when the page loads, and then in your click handler, increment it by 1. And then make sure to reset it to 0 (or 1) again when it gets high enough to start over. Does that answer your question?

Rotating through divs (hide/fade in) with jQuery

I'm currently in the process of creating a news carousel. On the left panel i have the three titles of each news item, to the right i have an image associated with that news item, and in the bottom right i have three "navigational blocks" for each item.
In my example, when you click a link on the left, it will display the associated content in the larger right hand panel. This also applies for the navigational blocks in the bottom right. If you click one of those, the associated item will be displayed in the larger panel.
The last thing i need to achieve is an auto rotation of these news items. On load, item one will be displayed with "link 1" highlighted, and "block one" of the navigational blocks highlighted. After say, 10 seconds, "link 2" will become highlighted with the "block 2" highlighted and the associated content in the middle being displayed. So on, so forth.
http://codepen.io/anon/pen/wDiGy - Here's a code pen version of it so far.
Code highlighted below:
<div id="title-container">
<ul>
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</div>
<div id="image-container">
<div class="image1 image" itemID="1">1</div>
<div class="image2 image" itemID="2">2</div>
<div class="image3 image" itemID="3">3</div>
<div id="circular-nav">
<li></li>
<li></li>
<li></li>
</div>
jQuery for selecting each item
$('.image:first').show();
$('.title, .circle-title').click(function(){
$('.image').hide();
var itemID = $(this).attr('itemID');
$('.image[itemID="' + itemID + '"]').fadeIn('fast');
});
I will be changing the HTML to integrate into the CMS i'm using, but the class names won't be changing.
Any assistance would be greatly appreciated.
UPDATE: I've managed to get 99% of the way there by fiddling around with it. I now have one hurdle. I'm using .next() to reach each item. If there are three items and it reaches the end, how do you return to the beginning? (PEN Updated)
Use a setInterval to trigger the tile change/image change function for every 10 seconds.
setInterval(function(){
//Code for changing the tile/image
},10000); //Milliseconds
You can put your existing function in a variable and use it for click as well as for interval. Also, since you're passing some information with the click, you can store the ids in an array and increment/reset counter after all the images have been cycled through.
Update:
Working Fiddle!
http://jsfiddle.net/hc4py/ (with only links stylized, not bullets)
setInterval(function () {
var $cur = $('a.active');
var i = $cur.closest('li').index(); //parent 'li' of first active link
$('.image:visible').hide(); //hide visible image
$cur.removeClass('active');
//if active 'a's parent li is the last one
if ($cur.closest('li').is(':last-child')) {
$('.image').eq(0).fadeIn('fast'); //show first image
$cur.closest('ul').find('li:first-child').find('a.title').addClass('active');
}
else {
$('.image').eq(i + 1).fadeIn('fast');//show next image
$cur.closest('li').next().find('a.title').addClass("active");
}
}, 2000);
.title.active{color:red;}
I found a simple solution which just involved an if statement to check the length of the item. Once it ended, it was able to loop around correctly.
setInterval(function () {
if ($('.image:visible').next().length === 0) {
$('.image').hide();
$('.image:first').fadeIn();
} else {
$('.image:visible').hide().next().fadeIn('fast');
}
}, 2000); //Milliseconds

Please cast an eye over my beginners javaScript

I am working on an interface with four main parts:
When a category link is hovered, the projects not in this category are darkened (this seems to be working ok)
When a category link is clicked, the projects not in this category are hidden (seems also to be ok)
The browser window size is detected and a style sheet is chosen to fit. I.e. for older screen or mobile. Go ahead and resize the browser window.
When the browser window is narrow there is an additional script to scroll down to the "main" div.
<div id="container">
<div id="inner-container">
<div id="tag-selector">
<ul>
<li class="all">ALL PROJECTS</li>
<li class="graphic-design">graphic design</li>
<li class="logo-design">logo design</li>
<li class="photography">photography</li>
<li class="web-development">web development</li>
<li class="web-design">web design</li>
</ul>
</div>
<div id="main" role="main">
<p class="items">There are x items in this category</p>
<p class="selected">No category selected</p>
<p class="clicked">No category clicked</p>
<section class="graphic-design">
<p>graphic-design</p>
</section>
<section class="logo-design graphic-design">
<p>logo-design</p><p> graphic-design</p>
</section>
<section class="logo-design graphic-design"><p>etc</p>
</section>
</div>
<footer> </footer>
then here's the javascript. Sorry if it's a bit long. It should be easy enough to read I hope.
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){
var xwidth =$(window).width();//get width of user window
all_projects_showing_text="All projects showing. There are " + n + " projects, in " + t + " categories.";
adjustStyle(xwidth);
$("p.items").text(all_projects_showing_text + " Width=" + xwidth);
$(".all").addClass("selected");
tag="all"
});
</script>
<script>
var n = $("section").length;//number of section boxes on page
var t = $("#tag-selector li").length;//categories
t--;
$("#tag-selector li").click(function() {//clicking section filter li
$("#tag-selector li").removeClass("selected");//removes all filtered class
$(this).addClass("selected");//then adds it to the chosen link (li), showing it as current
tag=$(this).attr("class");//var tag is the class name of the chosen link, i.e. category
var split = tag.split(' '); // this splits the class string and puts each item in an array
tag = split[0];//this chooses the first item of the array, hence not including the hilite class
var numItems = $('.'+tag).length
var numItems=numItems-1;//correct for real number
if (tag!="all"){//if the all link is not picked
$("section").hide();// hide all the boxes
$("#main ."+tag).fadeIn();//show all the boxes with the tag class
if(tag=="graphic-design"){
tag="Graphic design"
}
else if(tag=="logo-design"){
tag="Logo design"
}
else if(tag=="photography"){
tag="Photography"
}
else if(tag=="web-development"){
tag="Web development"
}
else if(tag=="web-design"){
tag="Web design"
}
$("p.items").text(numItems+" " +tag+ " projects");
$("p.selected").text(tag +" selected.");
$("p.clicked").text(tag +" selected.");
}
else{
$("section").fadeIn();//else show all the boxes
$("p.items").text(all_projects_showing_text);// all_projects_showing_text at onReady
}
});
</script>
<script>
$("#tag-selector li").hover(function () {
hovered_link=$(this).attr("class");//get the class of the category being hovered
var split = hovered_link.split(' '); // this returns an array
hovered_link = split[0];//remove any other classes apart from the first i.e. remove hilite
if (tag=="all"){// if All are shown
if(hovered_link!="all"){
$("section").not("."+hovered_link).addClass("section_darkened");//darken section which does not correspond with hovered category link
$("section").not(".section_darkened").addClass("outerglow");//add glow to not darkened sections
}
}
else{
}
if (tag==hovered_link){// if the projects are already filtered by this category, say so on hover
$("p.selected").text(tag +" already selected.");
}
else{
var numItems = $('.'+hovered_link).length
var numItems=numItems-1;//correct for real number
$("p.selected").text("Click to see only "+hovered_link+ " projects. (" +numItems+ " projects)" );
}
$(this).addClass("hilite");//hilite on hover over link
}, function () {
$(this).removeClass("hilite");
$("p.selected").text("...");
$("section").removeClass("section_darkened");//darken categories not in the selected category
$("section").removeClass("outerglow");//give the selected category items a glow
});
</script>
<script>
$(function() {
$(window).resize(function() {
adjustStyle($(this).width());
});
});
function adjustStyle(width) {
width = parseInt(width);
if (width < 600) {
$("#tag-selector li").click(function() {// SCroll function for handhelds
$('html,body').animate({
scrollTop: $("#main").offset().top},
'slow');
});
$("#size-stylesheet").attr("href", "css/nav-style-narrow.css");//style sheet for handhelds
} else if ((width >= 440)&&(width < 1040)){
$("#size-stylesheet").attr("href", "css/nav-style-med.css");
} else {
$("#size-stylesheet").attr("href", "css/nav-style-wide.css");
}
}
</script>
If you've gotten this far and had a look, thanks!
So my questions are;
Am I missing break; in my loops anywhere? Not too sure how to use break.
When my CSS file is chosen, there is a flash of the first style before it changes. Is there a way to avoid this?
When the browser is at the narrowest style sheet, and I click on my link, I have problems scrolling back up again afterwards. help?! :-)
Any glaring mistakes or omissions that would make this easier?
I start to feel like I have a lot of script on my one page. Maybe I should put it in a separate file. Would that help?
Is it ok to post multiple questions like this or should they be individual?
Thanks in advance for anyone who has a look.
Answer regarding break:
break stops the execution of the current loop or switch. You should use it in loops in order to stop a loop before the end of the current iteration, or on a condition that is not checked in the loop statement itself. You should use it at the end of a case in a switch block in order not to execute subsequent cases.
In your specific code there don't seem to be any loops or switches, so no place for any break anywhere.
OK, I'll bite, though I'm not going to try to offer a comprehensive list:
There are various ways to deal with the CSS flash issue. The easiest is to hide everything until you've loaded the correct stylesheet, then show everything once it's loaded.
Yes, in general it's always a good idea to put Javascript in separate files - it just makes managing your code easier, especially if you want to reuse any of it on multiple pages.
You're missing a lot of var statements, e.g. for all_projects_showing_text. This is syntactically correct, but a Bad Idea in Javascript, because it makes those variables global, attaching them to the window object. If you need a global variable, you should still declare it with var.
I'm not seeing any place where break would be appropriate, or even possible. You generally use break within a for or while loop to stop looping; I'm not seeing any loops like that in your code. JQuery code often uses .each() instead, or just loops implicitly through all the items in the selection; I rarely see break in code using jQuery, though there are of course times when it might be appropriate.
It's often a good idea to either cache or chain jQuery selectors. For example,
$("section").removeClass("section_darkened");
$("section").removeClass("outerglow");
could be
var $section = $section;
$section.removeClass("section_darkened");
$section.removeClass("outerglow");
or
$("section")
.removeClass("section_darkened")
.removeClass("outerglow");
or even (in this case, since .removeClass() can remove several classes at once):
$("section")
.removeClass("section_darkened outerglow");
Your long else if section starting if(tag=="graphic-design"){ could be better structured as a map + lookup:
var tagTitles = {
"graphic-design":"Graphic design",
"logo-design":"Logo design",
// etc
};
tag = tagTitles[tag];
break is not a function. It's a statement, so you don't add parenthesis.
The page loads before the css is choosen. If you want to target different screen sizes, you could take a look at css3 media queries. Adding the styles at the beginning of the page should work without flickering. You could still use js to choose styles as backup method.
I think you are adding a new click handler on every resize event! That's a lot of animations running on a click, try to set the handler only once.
Missing var, as already mentioned by nrabinowitz. Indentation could be better / more consistent.
JS in Separate files is better.
cacheable by clients -> page gets faster after first visit
reusable by different pages
easier to manage (version control)
Single (well researched) questions are generally better.

How do I navigate through 5 diffrent divs with a single button

I have 5 divs with ids; #one, #two, #three, #four and #five. I have a navigation menu linked to each div like this;
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
<li>FIVE</li>
</ul>
where each div represents a single page on my website, the the ul works perfectly but is there a way can have a single button like a "next" button that will go to page 2 when clicked and when clicked again will go to page 3 and so on... preferably using some sort of jquery or even javascript
I will respond based on the assumption that this is a purely theoretical exercise and given only the information you have provided. Please note that there are better ways of doing what you ask, as alluded to in the first comment.
However, assuming that you have, as you say, got an identical navigation menu on each page, and that, as you say, each div is on a separate web page, I suggest that you could continue your existing methodology and place a "Previous" and "Next" button on each page, and hook it up manually to the correct page.
For example, on page with #one, you would have buttons that might look like this:
Previous<!-- does nothing.. because you're on the first page -->
Next<!-- goes to page 2 -->
On subsequent pages, you would hard-code the links to the other pages, and on the final page you would blank out the Next button in a similar way to the way the Previous button was blanked out above.
Having said that. You could put all Divs in the same web page, and show/hide them using JavaScript and CSS. For example:
<div id="one" style="display:block;">Div 1</div>
<div id="two" style="display:none;">Div 2</div>
<div id="three" style="display:none;">Div 3</div>
<script type="text/javascript">
function focusOnAParticularDiv(divId)
{
switch(divId)
{
case 'one':
document.getElementById('two').style.display = 'none';
document.getElementById('three').style.display = 'none';
document.getElementById('one').style.display = 'block';
break;
case 'two':
// etc...
break;
case 'three':
// etc...
break;
}
}
</script>
You could then call that JS function on the onClick event of the next/previous buttons.
<input type="button" text="Next" onclick="focusOnAParticularDiv('two');" />
Or something like that...
You could choose to use JQuery's shortcuts if you wish.
Alternatively, you could use an ASP.NET Wizard control :)
As mentioned in some other comments, you can also create the div the user is after at the server side, which would avoid sending ALL the divs to the client on the first request (this would speed up the user's first request). This would mean you do not need any JavaScript, but would also mean that each time the user clicked a button the page would be destroyed and recreated on the server and sent back to the client (a full round-trip), which would have an impact on the number of hits your server gets.
It really depends what you're after and what your criteria are; hence why I have tried to cover several bases for you.
JQuery has a trigger event. You can trigger click event on your links when a user clicks next or previous button.
Something like
$(document).ready(function() {
var links = [];
var cnt=0;
$("ul li a").each(function(i) {
links[i] = this.href;
});
$("#next").click(function(e) {
cnt++;
if (cnt>=links.length) cnt=0;
location.hash=links[cnt].split("#")[1];
e.preventDefault();
});
});

Categories