Making image gallery, undefined is not a function? - javascript

I'm using a tutorial to create an image gallery and it gives me an error on line 31 of the js file. Not familiar with jQuery language so I thought the code might be out of date. Tried using the migrate plugin and it still doesn't work. On the jQuery site it says .live() was removed and to use .on() instead but not sure how to do that.
html file:
<body>
<header>
<div class="container">
<nav id="navbar"></nav>
</div>
</header>
<section id="main">
<div class="container">
<ul id="gallery">
<li data-tags="Web Design, Logo Design, Print Design"><a class="fancybox" rel="group" href="img/1.jpg"><img src="img/1.jpg"></a></li>
<li data-tags="Logo Design"><a class="fancybox" rel="group" href="img/2.jpg"><img src="img/2.jpg"></a></li>
<li data-tags="Web Design"><a class="fancybox" rel="group" href="img/3.jpg"><img src="img/3.jpg"></a></li>
<li data-tags="Print Design"><a class="fancybox" rel="group" href="img/4.jpg"><img src="img/4.jpg"></a></li>
<li data-tags="Logo Design, Print Design"><a class="fancybox" rel="group" href="img/5.jpg"><img src="img/5.jpg"></a></li>
</ul>
</div>
<hr>
<footer>
<div class="container">
<p></p>
</div>
</footer>
</section>
<script src="js/jquery.js"></script>
<script src="js/jquery.quicksand.js"></script>
<script src="js/fancybox/jquery.fancybox.pack.js"></script>
<script src="js/fancybox/jquery.fancybox-buttons.js"></script>
<script src="js/fancybox/jquery.fancybox-media.js"></script>
<script src="js/fancybox/jquery.fancybox-thumbs.js"></script>
<script src="js/script.js"></script>
<script>
$(document).ready(function(){
$(".fancybox").fancybox();
});
</script>
</body>
javascript file:
$(document).ready(function(){
var items = $('gallery li'),
itemsByTags = {};
items.each(function(i){
var elem = $(this),
tags = elem.data('tags').split(',');
elem.attr('data-id',i);
$.each(tags,function(key,value){
value= $.trim(value);
if(!(value in itemsByTags)){
itemsByTags[value] = [];
}
//add image to array
itemsByTags[value].push(elem);
});
});
//create all items option
createList('All Items', items);
$.each(itemsByTags, function(k, v){
createList(k, v);
});
//click handler
$('#navbar a').live('click',function(e){
var link = $(this);
//add active class
link.addClass('active').siblings().removeClass('active');
$('#gallery').quicksand(link.data('list').find('li'));
e.preventDefault();
});
$('#navbar a:first').click();
//create the lists
function createList(text,items){
var ul = $('<ul>',{'class':'hidden'});
$.each(items, function(){
$(this).clone().appendTo(ul);
});
ul.appendTo('#gallery');
var a = $('<a>',{
html:text,
href:'#',
data:{list:ul}
}).appendTo('#navbar');
}
});

Adjusting live() to on() can be done as follows: currently you have a statement like this:
$('#navbar a').live('click',function(e){ ...
and, as you already found out, live() is deprecated as of jQuery version 1.7.
Adjusting this to on() means to let the static navbar delegate the click event to a tags that are children of the navbar, even if they are added later:
$('#navbar').on('click', 'a', function(e){..
The on() is bound to an element that is already in the DOM when the page is loaded and delegates events to child elements even if they are dynamically added later.
For reference: http://api.jquery.com/on/

Related

Avoiding Redundant Functions in Navigation Sidebar

I'm very new to web development stuff so I'm having trouble googling the correct terms here.
The sidebar navigation is working, but the scripts are ugly and redundant.
Is there a way to clean this up? Like store the link id and html file location in an array and just have one script that does the lookup?
I don't need "code for me", just a nudge in the right direction.
Example:
<!DOCTYPE html>
<html>
<link href="./styles/main_style_sheet.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#navigation_link_1').click(function(){
$('#content_area').load('location_1.html');
});
});
</script>
<script>
$(document).ready(function () {
$('#navigation_link_2').click(function(){
$('#content_area').load('location_2.html');
});
});
</script>
<script>
$(document).ready(function () {
$('#navigation_link_3').click(function(){
$('#content_area').load('location_3.html');
});
});
</script>
<script>
$(document).ready(function () {
$('#navigation_link_4').click(function(){
$('#content_area').load('location_4.html');
});
});
</script>
<body>
<div class="container">
<div id="concept-sidebar"">
<h4 style="text-indent: 0px;"> <strong> My Sidebar </strong></h4>
<div class="container" style="width:100%">
<div class="list-group">
<a id="navigation_link_1"
class="list-group-item custom"
> First Item </a>
<a id="navigation_link_2"
class="list-group-item custom"> Slowly Changing Dimensions (SCD) </a>
<a id="navigation_link_3"
class="list-group-item custom"> Important System Fields
</a>
<a id="navigation_link_4"
class="list-group-item custom"> Reference Data
</a>
</div>
</div>
</div>
</div>
</body>
</html>
There are multiple ways to solve this (and since you asked for a direction and not a solution I'll give give you a general instruction for one of the solutions:):
Instead of settings the click-event-handler on each element - select all the relevant elements and have a click event on all of them:
$('.list-group-item').click(function(){ ... })
The selection here is on all items that have the class list-group-item, which in your case is the <a> elements you are looking for.
Extract the relevant id from the <a> you have (for you can use regex for that, for example). Another option - use the data-* attribute and get the number from that attribute (<a data-id="1"> and $(el).data('id')).
Load the content based on the id you just got:
$('#content_area').load('location_' + id + '.html');

Javascript - populate a div with content from a hidden div using click buttons

I need some help. As you will see in my fiddle, I am attempting to use buttons to populate a single container div with content from multiple hidden divs, depending on which button is clicked. The problem I am having is, I don't know how to access the actual content in the hidden divs to populate the container div. As of now, I am using the id attributes for the hidden divs to demonstrate which div content I would like to display in the container.
I've seen a few other posts with link <a> attributes referencing hidden content, but none so far using a button element with click functionality to change div content.
jQuery(function ($) {
$('#button1').click(function () {
$('#info').empty();
$('#info').prepend('#option1');
});
$('#button2').click(function () {
$('#info').empty();
$('#info').prepend('#option2');
});
$('#button3').click(function () {
$('#info').empty();
$('#info').prepend('#option3');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-panel">
<ul id="button-column" style="list-style: none;">
<li class="buttons"><button id="button1">Button 1</button></li>
<li class="buttons"><button id="button2">Button 2</button></li>
<li class="buttons"><button id="button3">Button 3</button></li>
</ul>
</div>
<div id="info-div">
<div id="info"></div>
</div>
<div id="hiddenDivs" style="display:none;">
<div class="info" id="option1">Box</div>
<div class="info" id="option2">Google Drive</div>
<div class="info" id="option3">Box</div>
</div>
Here is my fiddle
Here's a version that uses jquery data attributes. It reduces the redundancy and complexity and can be configured easily.
<body>
<div class="button-panel">
<ul id="button-column" style="list-style: none;">
<li class="buttons"><button id="button1" data-link="option1">Button 1</button></li>
<li class="buttons"><button id="button2" data-link="option2">Button 2</button></li>
<li class="buttons"><button id="button3" data-link="option3">Button 3</button></li>
</ul>
</div>
<div id="info-div">
<div id="info">
</div>
</div>
<div id="hiddenDivs" style="display:none;">
<div class="info" id="option1">Box</div>
<div class="info" id="option2">Google Drive</div>
<div class="info" id="option3">Box</div>
</div>
</body>
<script>
$('.buttons button').click(function (){
$('#info').empty();
$('#info').html($("#" + $(this).data('link')).html());
});
</script>
Example : https://jsfiddle.net/yvsu6qfw/3/
It sounds like maybe you were looking for using the button itself to populate data built into the button with a data attribute or something? If so you can do something like this:
HTML
<div class="button-panel">
<ul id="button-column" style="list-style: none;">
<li class="buttons"><button data-info="Box">Button 1</button></li>
<li class="buttons"><button data-info="Google Drive">Button 2</button></li>
<li class="buttons"><button data-info="Box">Button 3</button></li>
</ul>
</div>
<div id="info-div">
<div id="info"></div>
</div>
jQuery
$(document).ready(function (){
$('#button-column button').click(function (){
$('#info').html($(this).attr('data-info'));
});
});
If you want the first button to load the content from the first hidden div etc. without relying upon using the id attributes, you can use the .index() method. When you pass this as an argument it will return the index value of the click event target in the collection $("#button-column .buttons :button"). Afterwards you can pass the index value to the .get() method to retrieve the corresponding element from the collection of hidden divs $("#hiddenDivs .info").
$().ready(function(){
$("#button-column .buttons :button").on("click", function(){
$('#info').empty();
var clickedIndex = $("#button-column .buttons :button").index(this);
var hiddenInfo = $("#hiddenDivs .info").get(clickedIndex);
$('#info').prepend( $(hiddenInfo).text() );
});
});
you can use html function, without parameter gets the content of the element
with parameter replaces the content with the string parameter
$(document).ready(function (){
$('#button1').click(function (){
$('#info').html( $('#option1').html() );
});
$('#button2').click(function (){
$('#info').html( $('#option2').html() );
});
$('#button3').click(function (){
$('#info').html( $('#option3').html() );
});
});
In your code example, you do for example:
$('#info').prepend('#option1');
What you instruct to do here, is adding a text string '#option1' to an element with ID info.
What you intend to do is prepending the content of ID option1 to the element with ID info. You could do something like this instead:
$('#info').prepend($('#option1').html());
Another approach could be (but I don't know if that's relevant for you) to not clone content (since it costs you repaints) but toggle the specific elements instead. For example:
$('#option1,#option2').hide();
$('#option3').hide();
And yet another one: use data-attributes on your buttons:
Button 1
Button 2
<div id="info">
</div>
And the JS:
$('.button').on('click', function(event) {
event.preventDefault();
$('#info').html($(event.currentTarget).attr('data-text'));
});
Don't repeat yourself! To get the number out of an ID replace with "" all that is not a number using RegExp \D.
Using number from ID
Than, to get the actual content you can use $("#option"+ num).html() or $("#option"+ num).text() methods:
jsFiddle demo
jQuery(function ($) {
$('.buttons button').click(function () {
var num = this.id.replace(/\D/g,"");
$("#info").html( $("#option"+ num).html() );
});
});
Target element using data-* attribute
Alternatively you can store inside a data-* attribute the desired target selector ID:
<button data-content="#option1" id="button1">Button 1</button>
and than simply:
jsFiddle demo
jQuery(function ($) {
$("[data-content]").click(function () {
$("#info").html( $(this.dataset.content).html() );
});
});
http://api.jquery.com/html/
http://api.jquery.com/text/
If the expectation is to get same indexed hidden div content, Then the below code should work.
$(document).ready(function (){
$('.buttons button').click(function (){
$('#info').empty();
var index = $('.buttons button').index($(this));
$('#info').html($('.info:eq('+index+')').html());
});
});

jQuery find closest

I'm trying to get the a href of an list item.
HTML
<div class="popup" style="display: none;">
<div class="product">
<div class="photo">
<a href="" class="sendkleur" id="link69"> <!-- href im trying to reach -->
<img id="product-collection-image-69" src="" alt="Test kleur" class="popup-image69">
</a>
</div>
<a href="" class="sendkleur" id="link69">
<strong>Test kleur</strong>
</a>
<span class="swatchLabel-category">Kleur:</span>
<p class="float-clearer"></p>
<div class="swatch-category-container" style="clear:both;" id="ul-attribute137-69">
<img onclick="listSwitcher();" src="" id="a137-32" class="swatch-category" alt="Beige" width="12px" height="12px" title="Beige">
<img onclick="listSwitcher();" src="" id="a137-36" class="swatch-category" alt="Zwart" width="12px" height="12px" title="Zwart">
</div>
<p class="float-clearer"></p>
</div>
</div>
There are multiple popups on the site and thats what makes it difficult. At first I used this code
var link = jQuery('.photo').find('a')[0].getAttribute("href");
But this ofcourse only returns the href of the first popup. Then I tried this code:
var link = jQuery('.photo').closest('a').attr("href");
But this returned undefined
Then I tried this:
var link = jQuery(this).closest('a').attr("href");
But that also returns undefined
Edit
Here is the whole jQuery code snippet
jQuery(document).ready(function(){
jQuery('.swatch-category-container img').click(function(){
var kleur = jQuery(this).attr('title');
var link = jQuery('.photo').find('a').attr("href");
console.log(link);
link += "?kleur="+kleur;
console.log(link);
jQuery('.photo').find('.sendkleur').attr("href", link);
});
});
Working from the .swatch-category-container img element, you can traverse the DOM to find the required a like this:
$('.swatch-category-container img').click(function() {
var link = $(this).closest('.popup').find('.photo a').prop('href');
// do something with link here...
});
If this is the .swatch-category-container img element then, the anchor is the previous to previous sibling of the ancestor swatch-category-container element
var link = jQuery(this).closest('.swatch-category-container').prev().prev().attr("href");
Since you said multiple popups, the idea would be like this.
1. Get all popups
2. From each popup in all popups
Get the photo href item
$('.popup').each(function() {
var hrefItem = $(this).find('.photo a').attr('href');
//Do your processing with href item
});

Use jQuery to show/toggle each element only showing one on screen at any particular moment

I have some links:
About
Portfolio
Resume
When I click 'About', I want the About element to show, but the Portfolio and Resume elements to be hidden (and so on through the pattern)...
My code is structured like this (clipped to the parts that are needed):
HTML:
<section id="attCatch">
<div class="container_12">
<h1 class="attCatchText">The name's Jake. I like to make things.</h1>
<nav id="topMainNav">
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Resume</li>
</ul>
</nav>
</div>
</section>
<section id="contentLoader">
<div class="container_12">
<section class="mn_pages">
<article class="about_page">
<h1>About stuff</h1>
</article>
<article class="portfolio_page">
<h1>Portfolio stuff</h1>
</article>
<article class="resume_page">
<h1>Resume stuff</h1>
</article>
</section>
</div>
</section>
jQuery:
$(document).ready(function(){
$('.mn_pages').hide();
var i = 0;
$('.topMainNav').each(function(){
$(this).click(function(){
$('.mn_pages:eq('+$(this).data('idf')+')').toggle('slow');
});
$(this).data('idf',i);
i++;
});
});
I thought my jQuery code would work, but this is the not the case.
Included JS fiddle; http://jsfiddle.net/MsYdJ/
May be this way:
FIDDLE FOR TRYOUT
$(function(){
$('.mn_pages').find('article').hide(); // <---HIDES ON PAGE LOAD
$('#topMainNav a').click(function(e){
e.preventDefault();
var page = $(this).text().toLowerCase();
$('.mn_pages').find('article').hide(); // <---OPENED ONE HIDES
$('[class="'+page+'_page"]').show(); //<------CLICKED ONE SHOWS
});
});
You can use the following selector to hide the articles on page load:
$('.mn_pages > article').hide();
Then the following to show/hide the correct element:
$('#topMainNav li').on('click', function(e) {
e.preventDefault();
$('.mn_pages > article').hide().eq($(this).index()).show();
});
Here's a fiddle
This is an implementation wherein you require the class/Id names to be constant, wand changing the name of the links any other time-This is the fiddle
$(document).ready(function () {
$('#contentLoader .mn_pages').children().hide();
$('#topMainNav li').each(function () {
var targetClass=($(this).children().attr("class")).replace("Link","_page");
$(this).bind("click",function(){
$("#contentLoader .mn_pages").children().hide();
$("#contentLoader .mn_pages ."+targetClass).show();
});
});
});

On .click() event to .get() page and replace .html() in jquery

I have div class="contentBlock" which is treated as the container for updating
<div class="contentBlock"></div>
I have a script that I wrote that doesnt work :c
$(document).ready(function(){
$('.postLink').on('click', function () {
$.get("page.php", function (data) {
$(".contentBlock").html(data);
});
});
});
I have a anchor html
<div class="box">
<a class="postLink" "href="#">
<h1 title="Light me up"></h1>
<div class="innerbox">
<figure><img src="http://cpsr-rspc.hc-sc.gc.ca/PR-RP/servlet/ShowImage?photoId=1789" /></figure>
<ul class="categorySelect">
<li class="print"></li>
<li class="video"></li>
<li class="web"></li>
</ul>
</div>
</a>
</div>
The page.php is just an img tag amd some lorem.
I've never worked with .get() I'm sure I'm using it incorrectly. Additionally, where would I add a transition for a loading .gif and a fadein when loaded?
<a class="postLink" "href="#">
Should be
<a class="postLink" href="#">
You had an extra quote.
$(document).ready(function(){
$(".postLink").on('click', function () {
// load in animation.gif here
$(".contentBlock").load("page.php", function() {
// end loading animation now
});
});
});
Using a load in jQuery is meant for exactly this purpose.
Here's the jQuery doc for load: http://api.jquery.com/load/

Categories