I have tabs on a page that are giving me trouble. I think it is in the js code. Sometimes you have to doubleclick on the tabs, sometimes you don't.
This is using HAML in Rails, which I am not as familiar with. I also didn't write the original code. I am taking over on a project.
Here are the codes:
HAML
#myTabs
%ul.tab-buttons.tab-buttons--boxed.tab-buttons--left.js-tabs.nav-tabs
%li.active.tab-button
%a#tab1.tab-button-link.active{"data-toggle" => "tab", "data-projects" => "not_archived"} Current Projects
%li.tab-button
%a#tab2.tab-button-link{"data-toggle" => "tab", "data-projects" => "archived"} Archived Projects
.tab-content
#tab1C.container
%ul.list-project
= render #projects
#tab2C.container
%ul.list-project
JS
$('.js-tabs li a:not(:first)').addClass('inactive');
$('.container').hide();
$('.container:first').show();
$('.js-tabs li a').click(function(){
var that = this;
var t = $(that).attr('id');
$.get("/projects", {projects: $(that).data("projects")}, function(){},'json')
.done(function(data){
var projects = data.projects;
if($(that).hasClass('inactive')){
$(that).removeClass('inactive');
$(that).addClass('active');
$('#'+t+'C .list-project').html(projects);
$('.container').hide();
$('#'+ t + 'C').fadeIn('slow');
} else {
$(that).removeClass('active');
$(that).addClass('inactive');
$('#'+t+'C .list-project').html(projects);
$('.container').hide();
$('#'+ t + 'C').fadein('slow');
};
$('.open-popup-link').magnificPopup(magnificPopupOptionsPermissionEmail);
})
});
I tried to show the codes in codepen but it isn't showing accurately.
Codepen
Are you finding that you have to double click if you just entered the page, but single click if you refresh the page?
If so, then turboloading may be the problem. A common fix is as follows:
var ready;
ready = function() {
// add your functions and calls here
}
$(document).ready(ready);
$(document).on('page:load', ready);
Related
I am loading PHP files with JQuery/Ajax.
This is the index.php file where the webpages are called
<div class = "view-screen">
<?php include('home.php'); ?>
</div>
Depending on which nav link is clicked, that page will display without refreshing.
$(document).ready(function() {
// ...
$navLinks.click( function() {
var $this = $(this)
target = $this.data('target')
toggleMenu()
$viewScreen.load(target + ".php")
$this.data('clicked', true)
if ($this.data('clicked') && target === "about") {
activateAbout()
}
return false
})
function activateAbout() {
console.log('activated')
}
}
The console log works, and displays 'activated'. The pages do load.
All of my scripts compile and link correctly to each other.
However, when I include code that updates the target page CSS in the activateAbout() function, it doesn't work. For example:
$('body').css("background-color", "white")
in activateAbout() works, but calling/updating CSS elements in the chosen .php file doesn't, such as
$('.about p').css("color", "white")
// OR
$('.about').toggleClass('activate')
I have a feeling this has something to do with the order in which these files are loaded, but I'm not sure! Thanks for the help in advance
This is common phenomenon. The reason you are not able to apply the css is because, your content is loading after, you call activateAbout(). I would recommend to call activateAbout() once the $viewScreen.load(target + ".php") loads the data successfully. jQuery.load() supports callback too. Refer to the example usage at https://www.w3schools.com/jquery/jquery_ajax_load.asp. So, it should look like
$(document).ready(function() {
$navLinks.click( function(){
var $this = $(this);
target = $this.data('target');
toggleMenu();
$viewScreen.load(target + ".php", function() {
$this.data('clicked', true);
if ($this.data('clicked') && target === "about") {
activateAbout();
}
});
return false;
});
});
function activateAbout() {
console.log('activated')
}
Also there is a trick using setTimeout which you can execute after certain time, when the view is expected to be loaded like below
if ($this.data('clicked') && target === "about") {
//The timeout period you can change accordingly
setTimeout(activateAbout, 300);
}
The recommended way is first type solution. Hope this helps you!!
I have a "quick view" feature that captures a dynamic URL also known as "qvURL" and creates a colorbox with it via:
<script type="text/javascript">
$(function(){
$(".quickview_btn").click(function(e){
e.preventDefault();
var qvURL = $(this).attr("href");
$.colorbox({"href": qvURL})
});
$.colorbox.resize();
});
</script>
Now. I need to make some changes in the child window - but it seems the AJAX or whatever is wiping out the entire DOM and anything I load from the parent window doesn't reflect.
For instance - let's say I just want to add a div that says qwerty!
[I'm actually wanting to create an mbox around a Call To Action]
Any insight would be greatly appreciated!
Please note - the URLs it's loading is content that I can not manipulate - so it has to be done in the parent window.
Thanks!
Please see below for my full snippet:
<script>
$( document ).ready(function() {
$('.quickview_btn').click(function(){
//Quickview tracking
$('.quickview').attr('id', 'quickviewClicked-area');
mboxDefine('quickviewClicked-area','quickviewClicked','clicked=Y');
$( 'div.quickview' ).bind( 'click', function() {
console.log('clicked!');
product = $(this).children().attr('href');
console.log(product)
mboxUpdate('quickviewClicked', "link="+product);
});
//thumbnail add to cart tracking
$('div.add-to-cart').attr('id', 'ThumbnailAddToCart-area');
mboxDefine('ThumbnailAddToCart-area','ThumbnailAddToCartClicked','clicked=Y');
$( 'div.qlBtns' ).bind( 'click', function() {
;
mboxUpdate('ThumbnailAddToCartClicked', "clicked=Y");
console.log('mbox updated!')
});
});
});
/*
$(document).ready(function(){
$(qvURL).$colorbox({
iframe : true,
frastIframe: false,
onComplete: function(){
$('.name').html('yeah you got it');
}
});
});
*/
</script>
< script >
$(document).ready(function() {
$('.quickview_btn').click(function() {
//Quickview tracking
$('.quickview').attr('id', 'quickviewClicked-area');
mboxDefine('quickviewClicked-area', 'quickviewClicked', 'clicked=Y');
$('div.quickview').bind('click', function() {
console.log('clicked!');
product = $(this).children().attr('href');
console.log(product)
mboxUpdate('quickviewClicked', "link=" + product);
});
//thumbnail add to cart tracking
$('div.add-to-cart').attr('id', 'ThumbnailAddToCart-area');
mboxDefine('ThumbnailAddToCart-area', 'ThumbnailAddToCartClicked', 'clicked=Y');
$('div.qlBtns').bind('click', function() {;
mboxUpdate('ThumbnailAddToCartClicked', "clicked=Y");
console.log('mbox updated!')
});
});
});
/*
$(document).ready(function(){
$(qvURL).$colorbox({
iframe : true,
frastIframe: false,
onComplete: function(){
$('.name').html('yeah you got it');
}
});
});
*/
< /script>
I see this line in your code:
$.colorbox({"href": qvURL})
and my first question is whether or not that selector is enough. Mind you I am more a middle-ware than a client-side guru, but from my knowledge of jQuery, that selector won't do anything because jQuery can't tell what you mean. See how you used the quotes in the assignment of the click function?
$(".quickview_btn").click(function(e){
e.preventDefault();
if you used $("#colorbox") to get the object (if that is its id) or $(".colorbox" if is is a a class you are targeting.
(I am not an expert, as I said, but those who are agree:
$(".someClass") selects all elements with class name someClass
$("#testButton") selects the element with the id value of testButton
-- Courtesy of the DZone jQuery Ref Card at https://dzone.com/refcardz/jquery-selectors
So it may be that everything else is fine, you just aren't passing your code anything to hook into the colorbox object.
Upon loading a page I make a database call (via ajax / php) to get a dynamic list. The list displays fine and looks something like this:
<ul id="menu">
<li>bla</li>
<li>bla2</li>
<li>bla3</li>
</ul>
As soon as the list is done loading I want to dynamically load content based on the page I am on, so I grab the page URL which in this case lets say is bla3. I want to look through the list and grab the URL(href) of the li item containing bla3.
I figured something like this below would work but it does not.
$(document).ready(function() {
$('#menu').on('load', function(){
var pageID = $('#menu li a[href$="?bla3"]').attr('href');
alert(pageID);
});
});
The problem (I am assuming) is that #menu is not loaded quickly enough so the on load event fires before #menu loads, I have tried it with body and that didn't work either. Essentially I just need a away to look through a dynamically generated list after it and the page it is on is fully loaded.
Any ideas?
<body onload="findList()">
Then you need this function in your <head>
<head>
<script type="text/javascript" language="javascript">
function findList() {
var list = document.getElementById("menu").getElementsByTagName("li");
var contains = "bla3";
var patt = new RegExp(contains,"g");
for (var x=0;x<list.length;x++) {
if (list[x].match(patt).length>0) {
var hrefVal = list[x].childNodes[0].href;
alert(hrefVal);
}
}
}
</script>
</head>
To start, it seems like you're in need of a way to wait for your menu. You can try polling the DOM for the element.
Here's a rough fiddle that seems to simulate what you're describing: http://jsfiddle.net/rkLVx/1/
var menuHasArrived = function (fn) {
console.log('checking...');
if ($('#menu').length) {
fn();
} else {
setTimeout(function () {
menuHasArrived(fn);
}, 1000);
}
}
menuHasArrived(function () {
alert($('#menu li a:contains(bla2)').attr('href'));
});
setTimeout(function () {
$('body').append(
'<ul id="menu">' +
'<li>bla</li>' +
'<li>bla2</li>' +
'<li>bla3</li>' +
'</ul>');
}, 2000);
Good luck
I'm using Drupal 7 and get my content with View module on page. And my pager Views Load More module. And my thumbnail effect hover, shadow etc. Image hover using this code:
var hoverImg = '<div class="hoverimg"></div>';
$(".thumb").each(function(){
$(this).children("div").each(function(){
$(this).find("a").append(hoverImg);
});
});
$(".thumb div").hover(function() {
$(this).find(".hoverimg").animate({ opacity: 'toggle' });
});
$(".thumb").hover(function() {
$(this).find("div").each(function(){
$(this).find(".shadow").fadeOut(500);
});
});
And getting number on my current thumbnail. This code:
var c = '';
var d = '';
$('.view-content div.views-row').each(function(){
c = 0;
d = 0;
var i = 1;
d = $(this).find('.thumbimg').length;
$(this).find('.thumbimg').each(function(){
sayi=i++;
$(this).append('<div class="img_no">0'+sayi+'</div>');
});
});
Everything is OK. All effects on start page. But when click Load More button, my effects can't work another page.
How do i solve this problem? Thanks.
The reason why it stops working is due to the hover function (and your other scripts/functions) only works on existing elements. So if you add something with ajax, it wont apply to that unless you reload the script after the ajax load.
Another option is to use live() or on() (for the hover part. On is the new version of live, added in jQuery 1.7).
Live and on listens for any existing or future elements.
A live script would look something like this:
$(".yourElement").live({
mouseenter:
function () {
// Do something
},
mouseleave:
function () {
// Do something
},
mousemove:
function () {
// Do something
}
});
I have an accordion style navigation list set up so that when categories are clicked it opens up to show sub-categories that link to pages.
What I would like to do is have the accordion navigation list keep it's open or closed state when the new page opens.
I've gathered that cookies work to retain the state on refresh, but how do I retain the state when a different page is visited? All the pages have the same accordion navigation list.
Try Web Storage. Store the state of the tabs on page unload, restore the state on the page load event.
I found a solution, it uses the accordian plug-in found here, http://www.i-marco.nl/weblog/archive/2010/02/27/yup_yet_another_jquery_accordi and the jquery cookie.js plug-in
I added id's to the header anchor tages in the HTNL mark-up like so,
<li>
<a id="m1" class="label" href="#">Sound/Audio Systems</a>
<ul class="acitem">
<li>PA Systems</li>
<li>Loudspeakers</li>
<li>Microphones </li>
<li>DJ Equipment</li>
<li>Sound Processing Equipment</li>
</ul>
</li>
And modified the accordian.js code, I added the lines beginning with $.cookie, and the If statement in the document.ready funciton.
jQuery.fn.initMenu = function() {
return this.each(function(){
var theMenu = $(this).get(0);
$('.acitem', this).hide();
$('li.expand > .acitem', this).show();
$('li.expand > .acitem', this).prev().addClass('active'),
currentID = "";
$('li a', this).click(
function(e) {
e.stopImmediatePropagation();
var theElement = $(this).next();
var parent = this.parentNode.parentNode;
if($(parent).hasClass('noaccordion')) {
if(theElement[0] === undefined) {
window.location.href = this.href;
}
$(theElement).slideToggle('normal', function() {
if ($(this).is(':visible')) {
$(this).prev().addClass('active');
currentID = $(this).prev().attr('id');
$.cookie('menustate', currentID, {expires: 2, path: '/'});
}
else {
$(this).prev().removeClass('active');
$.cookie('menustate', null, {expires: 2, path: '/'});
}
});
return false;
}
else {
if(theElement.hasClass('acitem') && theElement.is(':visible')) {
if($(parent).hasClass('collapsible')) {
$('.acitem:visible', parent).first().slideUp('normal',
function() {
$(this).prev().removeClass('active');
$.cookie('menustate', null, {expires: 2, path: '/'});
}
);
return false;
}
return false;
}
if(theElement.hasClass('acitem') && !theElement.is(':visible')) {
$('.acitem:visible', parent).first().slideUp('normal', function() {
$(this).prev().removeClass('active');
$.cookie('menustate', null, {expires: 2, path: '/'});
});
theElement.slideDown('normal', function() {
$(this).prev().addClass('active');
currentID = $(this).prev().attr('id');
$.cookie('menustate', currentID, {expires: 2, path: '/'});
});
return false;
}
}
}
);
});
};
$(document).ready(function() {
$('.menu').initMenu();$('#side-navigation_frame').show();
if ($.cookie('menustate')) {
var anchor = "",
elementID = $.cookie('menustate');
anchor = document.getElementById(elementID);
$(anchor).addClass('active');
$(anchor).next().show();
}
});
It works nicely, not bad for a beginner, thanks for all the advise.
Rob Fenwick
Cookies "retain state" across the full path and domain for which they are specified. So if you can get them to work for just one page, you should have them work automatically on all pages of your site.
You can still use cookies, you just have to make sure they're not specific to the one page. For example:
document.cookie = 'openitem=5; expires=somedate; path=/';
will be accessible to all pages on the site. More about cookies.
Ok so I took a look at the library you are using, it's a decent library and all but you might find it easier to find solutions to your problems if you use a more standard library like jQuery UI, it has an accordion control http://jqueryui.com/demos/accordion/ and like I mentioned there are so many people using it that the answer to most problems can be found.
But like I mentioned I did take a look at your library. As others have mentioned you would use a cookie to store the value. This library supports 'pre expanding' a particular section of the accordian, to do that you would add the expand class to the element. You can either do that server side or you can do it using JavaScript before initMenu() is called.
The other less elegant option is to trigger the click event on the anchor tag after the call to initMenu. Finally you can use jQuery's show() to show expand the section without animation.
The first thing you have to do is find out which section was clicked on, then you would store that sections name in a cookie. On page load you would get that value and expand the appropriate according section. This is what the code should kinda look like - note this is psuedo code and you have fill in the appropriate parts.
$(function() {
$(".menu.collapsible .label").click(function() {
var accordianSection = $(this).text();
rememberSection(accordianSection);
});
var section = recallSection();
if(section !== undefined) {
expandSection(section);
}
});
The expandSection function can look something like this:
var sectionLink = $(".menu.collapsible .label").filter(function() {
return $(this).text() == section;
});
sectionLink.trigger('click');