Dynamic jQuery Waypoints Loop - javascript

I'm struggling with the syntax for a loop that goes through and dynamically sets jQuery Waypoints.
Currently I have this code -
HTML Markup
For each 'process-anchor' I want to create a jQuery Waypoint
<div class="container">
<div class="process-anchor-1"></div>
<div class="process-anchor-2"></div>
<div class="process-anchor-3"></div>
<div class="process-anchor-4"></div>
<div class="process-anchor-5"></div>
</div>
<div class="image-list">
<div class="process-image"><img src="test.jpg"/></div>
<div class="process-image"><img src="test.jpg"/></div>
<div class="process-image"><img src="test.jpg"/></div>
<div class="process-image"><img src="test.jpg"/></div>
<div class="process-image"><img src="test.jpg"/></div>
</div>
Javascript Code (currently)
var process_fixed_anchor_1 = $('.process-anchor-1').waypoint({
handler: function(direction) {
$(".process-image-1").toggleClass("fade-in");
}
});
I want to run through and create waypoints however the amount of anchor DIV's may change. How could I edit the above code to be dynamic so I don't have to be specific every time?
Thanks,
DIM3NSION

Still just a bit unclear on what you're trying to accomplish, but here's how I would dynamically assign waypoints to a page given an unknown number of anchor divs:
Markup
I have added class="trigger-anchor" to your anchor divs with the hopes of finding a more approachable way to target those divs. Also put a common class on your process-image-* rather than letting them all be unique.
<div class="container">
<div class="process-anchor-1" class="trigger-anchor">
<div class="process-image"><img src="test.jpg"/></div>
</div>
<div class="process-anchor-2" class="trigger-anchor">
<div class="process-image"><img src="test.jpg"/></div>
</div>
<div class="process-anchor-3" class="trigger-anchor">
<div class="process-image"><img src="test.jpg"/></div>
</div>
<div class="process-anchor-4" class="trigger-anchor">
<div class="process-image"><img src="test.jpg"/></div>
</div>
<div class="process-anchor-5" class="trigger-anchor">
<div class="process-image"><img src="test.jpg"/></div>
</div>
</div>
JavaScript
I'll run an .each() on the elements where class="trigger-anchor" to build by waypoints. This way I don't have to declare var loops = 5; or anything like that.
<script type="text/javascript">
// Wait until our DOM is ready
$( document ).ready( function() {
// Keep Track of how many we make and store
// our instances in an array to access if
// we need to later
var anchors = array();
$( '.trigger-anchor' ).each( function() {
var tmp_instance = $( this ).waypoint({
handler: function(direction) {
$( this ).children('process-image').toggleClass("fade-in");
}
});
anchors.push( tmp_instance );
} );
} );
</script>
See if that helps to get you in the right direction.

According to Waypoints website http://imakewebthings.com/waypoints/guides/jquery-zepto/, you can accomplish the same thing as follows (waypoints will loop and fill your array with each instance). I used this method on my site.
//within your document.ready function
var anchors = array();
anchors = $( '.trigger-anchor' ).waypoint({
handler: function(direction) {
$(this).children('process-image').toggleClass("fade-in");
}
});
//ALTERNATE METHOD
//you can also include your handler in the waypoint call
anchors = $( '.trigger-anchor' ).waypoint(function(){
$(this).children('process-image').toggleClass("fade-in");
});

Related

How do i apply a function to only a specific div in a collection of divs generated by foreach loop?

When i click on SHOW MORE in one of the divs generated, in every div the footer div shows up with options Test1, Test2. I want the function to apply to the div im clicking on only. Help please :(
#foreach ($articles as $article)
<div class="row">
<div class="panel-heading">{{$article->title}}</div>
<div class="panel-body">{{$article->content}}</div>
<div class="panel-footer">
<div class="more" onclick="showPortals()">
Show More</div>
<div class="other_sources">Other Sources:
Test 1,
Test 2
<span class="less" onclick="hidePortals()">Show Less</span>
</div>
</div>
</div>
#endforeach
<script>
function showPortals() {
$(".other_sources").show();
$(".more").hide();
}
function hidePortals() {
$(".other_sources").hide();
$(".more").show();
}
</script>
Send the current element to the method
<div class="more" onclick="showPortals(this)">
<span class="less" onclick="hidePortals(this)">Show Less</span>
Use jquery to and hide/show the desired elements
function showPortals(element) {
var $panelFooter = $(element).closest('.panel-footer');
$panelFooter.find(".other_sources").show();
$panelFooter.find(".more").hide();
}
function hidePortals(element) {
var $panelFooter = $(element).closest('.panel-footer');
$panelFooter.find(".other_sources").hide();
$panelFooter.find(".more").show();
}
You can access the object you’re clicking via this object. You can pass it to your function:
<div class="more" onclick="showPortals(this)">
<span class="less" onclick="hidePortals(this)">Show Less</span>
Once you have the object representing your element (here, it will be div and span respectively), you can wrap it inside $ to get a jQuery object. Then, you can use .closest('.panel-footer') on the jQuery object to get your panel footer, and .find(selector) to find relevant objects inside the current panel-footer:
function showPortals(clickedElement) {
var $panelFooter = $(clickedElement).closest('.panel-footer');
$panelFooter.find(".other_sources").show();
$panelFooter.find(".more").hide();
}
function hidePortals(clickedElement) {
var $panelFooter = $(clickedElement).closest('.panel-footer');
$panelFooter.find(".other_sources").hide();
$panelFooter.find(".more").show();
}
However, onclick="hidePortals(this)" is not a recommended way of doing things because you’re mixing JavaScript with HTML. Instead, it’s recommended that you remove onclick="..." handlers and use jQuery’s .click handler, like this:
<script>
$(function() {
$('.more').click(function () {
var $panelFooter = $(this).closest('.panel-footer');
$panelFooter.find(".other_sources").show();
$panelFooter.find(".more").hide();
});
$('.less').click(function () {
var $panelFooter = $(this).closest('.panel-footer');
$panelFooter.find(".other_sources").hide();
$panelFooter.find(".more").show();
});
});
</script>
Change your selector to reflect each record's id.
#foreach ($articles as $article)
<div class="row">
<div class="panel-heading">{{$article->title}}</div>
<div class="panel-body">{{$article->content}}</div>
<div class="panel-footer">
<div class="more-{{$article->id}}" onclick="showPortals({{$article->id}})">
Show More</div>
<div class="other_sources-{{$article->id}}">Other Sources:
Test 1,
Test 2
<span class="less" onclick="hidePortals()">Show Less</span>
</div>
</div>
</div>
#endforeach
<script>
function showPortals(id) {
$(".other_sources-"+id).show();
$(".more-"+id).hide();
}
function hidePortals() {
$(".other_sources").hide();
$(".more").show();
}
</script>
Add a click event to every div:
One way:
$( document ).on( "click", 'div', doSomething);
But if you are trying on an specific id, you may change your selector.

jquery clone a link (once per div)

I have a set of divs, and need to clone the link from the top and insert into the last div (mobile-link). It is either cloning the links from all of the divs, and then inserting all of them at once, or if I use :eq(0), it's putting the first link into all of the divs.
<div class="course">Accounting</div>
<div class="start-date">1-1-2017</div>
<div class="credits">4</div>
<div class="location">Online</div>
<div class="mobile-link"></div>
<div class="course">Business</div>
<div class="start-date">1-1-2017</div>
<div class="credits">3</div>
<div class="location">Online/Campus</div>
<div class="mobile-link"></div>
<script>
$(".course a:eq(0)").clone().appendTo(".mobile-link");
</script>
What do I need to change to make this work properly?
You need to process each anchor separately:
$(".course").each(function() {
var myLink = $(this).find('a').clone();
$(this).nextAll('.mobile-link').first().append(myLink);
});
Demo fiddle
Append method can take a function as argument, and here it is appending to the each .mobile-link first <a> from his previous .course div
$(".mobile-link").append(function(){
return $(this).prevAll('.course:first').find('a:first').clone();
});
Check the below snippet
$(".mobile-link").append(function(i) {
return $(this).prevAll('.course:first').find('a:first').clone();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="course">Accounting
</div>
<div class="start-date">1-1-2017</div>
<div class="credits">4</div>
<div class="location">Online</div>
<div class="mobile-link"></div>
<div class="course">Business
</div>
<div class="start-date">1-1-2017</div>
<div class="credits">3</div>
<div class="location">Online/Campus</div>
<div class="mobile-link"></div>
I beleive that you should use last (If I understood question correctly):
var lastDiv = $(".mobile-link").last();
$(".course a:eq(0)").clone().appendTo(lastDiv);
Here is jsfiddle: fiddle

$().next() returning the same element multiple times

I tried to name the title as best I could. A little difficult for me to explain.
I'm having an issue with some code I'm writing (which runs in a widget on my wordpress site.) What I've written here emulates this issue. Just fyi I'm very new to jquery, JS, etc.
What I'm trying to do is set the variable "thumb" to the element after "widget-code". It works, however it's only finding that element ("thumb-class") in "wordpress-post1"
The console output is:
wordpress-post1
wordpress-post1
wordpress-post1
But it should be:
wordpress-post1
wordpress-post2
wordpress-post3
This is the actual code
<div class="wordpress-post1">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post2">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post3">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("#widget-code").next();
console.log(thumb[0].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
I'm going to try and clarify a little more:
This code is placed in an html widget which the wordpress theme I'm using provides. It hooks into each post. This is the only place I can put code, and this is the only code I've written. (I haven't altered the theme's files in any way.)
I have no control over the name of the classes or IDs. And they're dynamic. An unlimited number of posts could exist. Therefore I can't hardcode anything.
In order for this code to work correctly it'll need to find the sibling of the "widget-code" element in only the post it's running from.
This is the link to the code on JSFiddle: http://jsfiddle.net/pattnvy3/
Would appreciate any help on the matter.
If you want a nasty hack, try
<div class="wordpress-post1">
<div id="widget-code">
<script>
$(document).ready(function(){
var c = window['widget-code-counter'] || 0;
window['widget-code-counter'] = ++c;
var className = 'wordpress-post' + c;
console.log(className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
Demo: Fiddle
It will give the container class wordpress-post1, then you can use it to find any of the descendant element.
As per the immediate comments, it is invalid markup to use an id for multiple elements. That said, changing your id to a class such that:
<div class="wordpress-post[some-number-here]">
<div class="widget-code">
</div>
<div class="thumb-class">
</div>
</div>
would allow you to to a jQuery selector like so:
$('.widget-code').each(function (){
var thumb = $(this).next();
console.log(thumb[0].parentElement.className);
});
However, if I may make a recommendation, I would say that you tag each of your wordpress-post divs with the class "wordpress-post" and then have a more specific id which is the value you want to print.
Then it would look like this:
<div id="wordpress-post[some-number-here]" class="wordpress-post">
<div class="widget-code">
</div>
<div class="thumb-class">
</div>
</div>
and your javascript like this (with jQuery):
$('.widget-code').each(function (){
var post = $(this).closest('.wordpress-post');
console.log(post.attr('id'));
});
or even simpler:
$('.wordpress-post').each(function (){
console.log($(this).attr('id'));
});
depending on the needs you have. If you have any questions as to what you need, feel free to comment and I will get back to you as soon as I can.
A pure javascript method:
This is just a workaround since you have no control over ids or classes, this will target all div elements on the page, loop through them and search for any that contains wordpress-post in the class name.
window.onload=function(){
var posts=document.getElementsByTagName('div');
for(var i=0; i<posts.length; i++){
if(posts[i].className.indexOf("wordpress-post")> -1){
console.log(posts[i].className);
//Snippet Use
alert(posts[i].className);
}
}}
<div class="wordpress-post1">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
<div class="wordpress-post2">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
<div class="wordpress-post3">
<div id="widget-code"></div>
<div class="thumb-class"></div>
</div>
If you have any questions, please leave a comment below and I will get back to you as soon as possible.
I hope this helps. Happy coding!
This can help if you want to have multiple IDs:
$(document).ready(function(){
$("[id^=widget-code]").each(function(){
console.log(this.parentElement.className);
});
});
But, still multiple same Ids are not recommended.
FIDDLE
Update: Declare a global variable var i=0; and keep increment it like :
<div class="wordpress-post1">
<div id="widget-code">
<script>
var i=0;
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post2">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
<div class="wordpress-post3">
<div id="widget-code">
<script>
$(document).ready(function(){
var thumb = $("[id^=widget-code]").next();
console.log(thumb[i++].parentElement.className);
});
</script>
</div>
<div class="thumb-class">
</div>
</div>
DEMO

Run .each() based on elements within specific tab

I've got a layout with something to this effect:
<div id="issueWidgets">
<div class="column">
<div class="portlet" id="boxIssues">
<div class="portlet-header">Some Title</div>
<div class="portlet-content">Some content</div>
</div>
</div>
<div class="column">
<div class="portlet" id="boxStats">
<div class="portlet-header">Some Stats Title</div>
<div class="portlet-content">Some Stats content</div>
</div>
</div>
</div>
<div id="projectWidgets">
<div class="column">
<div class="portlet" id="boxProjects">
<div class="portlet-header">Some Title</div>
<div class="portlet-content">Some content</div>
</div>
</div>
</div>
<div id="userWidgets">
<div class="column">
<div class="portlet" id="boxUsers">
<div class="portlet-header">Some Title</div>
<div class="portlet-content">Some content</div>
</div>
</div>
<div class="column">
<div class="portlet" id="boxUsers2">
<div class="portlet-header">Some Title</div>
<div class="portlet-content">Some content</div>
</div>
</div>
</div>
And on and on...Each main div serves as a jquery ui tab.
So basically I've got tabs (as divs with the following IDs: issueWidgets, projectWidgets, and userWidgets). These divs contain some portlet divs (these are just divs that act as widgets within each column (div class=column).
I've got code that looks for each class with name column to create some cookie information like so:
// function that writes the list order to a cookie
function saveOrder() {
$(".column").each(function(index, value){
var colid = value.id;
var cookieName = "cookie-" + colid;
// Get the order for this column.
var order = $('#' + colid).sortable("toArray");
// For each portlet in the column
for ( var i = 0, n = order.length; i < n; i++ ) {
// Determine if it is 'opened' or 'closed'
var v = $('#' + order[i]).find('.portlet-content').is(':visible');
// Modify the array we're saving to indicate what's open and
// what's not.
order[i] = order[i] + ":" + v;
}
$.cookie(cookieName, order, { path: "/", expiry: new Date(2016, 1, 1)});
});
}
The issue I am having is this runs for every element with class name column. So basically it goes out to issueWidgets and finds each column, and goes to projectWidget and finds any element with class=column, and finally to userWidgets and also finds any element with class=column and runs the above code.
I want to limit it to run based on the its parent widget div. So for instance I'd want it to run only on issueWidgets when I am looking at the issueWidgets tab. Remember these are actually tabs (jquery ui). If I'm in the projectWidgets tab I'd want to find all elements with class=column but ONLY on the projectWidgets tab not all the other tabs...etc etc.
So basically my function should take in the tab either issueWidgets, projectWidgets, userWidgets and work .each only located within those tabs.
edit
I'm not sure how to modify this to use find(), since the original code within document ready looks like this:
$(".column").sortable({
connectWith: ".column",
handle: ".portlet-header",
cancel: ".portlet-toggle",
placeholder: "portlet-placeholder ui-corner-all",
stop: function () { saveOrder(); }
});
$(".portlet")
.addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
.find(".portlet-header")
.addClass("ui-widget-header ui-corner-all")
.prepend("<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>")
.end()
.find(".portlet-content");
restoreOrder();
$(".portlet-header .ui-icon").hover(
function () { $(this).addClass("ui-icon-hover"); },
function () { $(this).removeClass('ui-icon-hover'); }
);
$(".portlet-toggle").click(function () {
var icon = $(this);
icon.toggleClass("ui-icon-minusthick ui-icon-plusthick");
icon.closest(".portlet").find(".portlet-content").toggle();
saveOrder();
});
Access to the parent of that element and compare.
$(".column").each(function(index, value){
// If isn't the parent you're looking for..
if($(this).parent().attr('id') != 'projectWidgets'){
continue;
}
// the rest of your code
}
EDIT: According to the answers below, new code:
I'm assuming that the code you post (var selectedTabIndex = $('#tabs').tabs('option', 'active');) gives the HTML content, am I right?
If so, use instead something like this:
$tabSelected = $('#tabs').tabs('option', 'active');
and all you have to do is find the .column.
$tabSelected.find('.column').each(function(index, value){
});
EDIT 2: According to the jQuery Tab documentation:
Since the activate event is only fired on tab activation, it is not
fired for the initial tab when the tabs widget is created. If you need
a hook for widget creation use the create event.
So, take care, you might need create event also. The below code should do the trick.
$('#tabs').tabs({
activate: function(event, ui){
$(this).find('.column').each(function(i, value){
});
}
});

Getting class contains in a very simple Jquery plugin

I'm experimenting with Jquery plugins. (please note I'm a beginner) and I've made a very simple plugin. this works if I set the selector to ('div') but when I try to make it so it only selects the divs with a class that contains "object" it fails. what am I doing wrong? I'm not getting any errors.
javascript:
(function( $ ) {
$.fn.Duplo = function() {
return this.filter("div[class*='object']").clone().appendTo('body');
};
}( jQuery ));
$(document).ready(function(){
$( ".negen" ).Duplo();
});
html:
<body>
<div class="row">
<div class="col-md-12 col-sm-12 twaalf">
</div>
</div>
<div class="container">
<div class="col-md-3 col-sm-3 drie">
</div>
<div class="col-md-9 col-sm-9 negen">
<div class="object"></div>
<div class="object2"></div>
<div class="object3"></div>
<div class="object4"></div>
</div>
</div>
</body>
My html contains four divs with the classes: object, object1, object2, object3 Also .negen is the div wich contains all of these.
Thanks :)
If you expect to filter .negen elements which contains some specific elements with class containing object, then use:
this.filter(":has(div[class*='object'])").clone().appendTo('body');
This could be written as:
return this.has("div[class*='object']").clone().appendTo('body');
If you want to clone elements object, then use:
return this.find("div[class*='object']").clone().appendTo('body');
You have to change your selector statement
"("div[class*='object']")" this part
check this
http://api.jquery.com/category/selectors/
Try this.
return this.find(".object").clone().appendTo('body');
Fiddle Demo

Categories

Resources