I Have the following in my HTML:
<div class="item" id="item_1">
Content
</div>
<div class="item" id="item_2">
Content
</div>
<div class="item" id="item_3">
Content
</div>
<!--CONTENT BLOCK 1-->
<div class="item w100" id="content_1">
Story
</div>
<!--/CONTENT BLOCK 1-->
<div class="item" id="item_4">
Content
</div>
<div class="item" id="item_5">
Content
</div>
<!--CONTENT BLOCK 2-->
<div class="item w100" id="content_2">
Story
</div>
<!--/CONTENT BLOCK 2-->
<div class="item" id="item_6">
Content
</div>
<!--CONTENT BLOCK 3-->
<div class="item w100" id="content_3">
Story
</div>
<!--/CONTENT BLOCK 3-->
The content blocks are hidden, only visible when an item is clicked.
I had this working fine as an unresponsive layout but now I've made the website responsive and the javascript needs to function slightly differently as each item width is different (it's a boxed grid layout).
This is the javascript:
// Open Link in Content Block
jQuery(document).ready(function($){
$('.contentLink').click(function(event){
var itemID=$(event.target).closest(".storyLink").attr("id");
showBlock(itemID);
document.location.hash = itemID;
return false;
});
});
function showBlock(targetID){ //load content and open dialog
var $url = "ss_storyboard/"+targetID+".html";
if (targetID == 'Sarah')
{
loadStory("#content_1", 500, targetID);
}
else if ((targetID == 'item_1') || (targetID == 'item_2') || (targetID == 'item_3'))
{
loadStory("#content_2", 1700, targetID);
}
else if (targetID == 'item_4' || targetID == 'item_5')
{
loadStory("#content_3", 2200, targetID);
}
else if (targetID == 'item_6' || targetID == 'item_7')
{
loadStory("#content_4", 2750, targetID);
}
else{
return false;
}
I was thinking I could do something like this:
jQuery(document).ready(function($){
$('.contentLink').click(function(event){
var itemID=$(event.target).closest(".storyLink").attr("id");
var contentID= $(event.target).next(".w100").attr("id");
showBlock(itemID, contentID);
document.location.hash = itemID;
return false;
});
});
But jquery's .next() only works within the content set. Is there a way to find find the next class the comes after a clicked class in a document??
Another way I though I could do this is to detect where the line break of the items ends (ie. when the items wrap to a new line), and append the content block in dynamically after this....I'm just not sure how to go about calculating where the break would be. All the item widths use percentages that differ for a number of media queries matching the different screen widths.
Final answer
Measure available area
function measureWidths(){
var container = document.getElementById("container"),
containerRectObject = container.getBoundingClientRect(),
containerRight = 0;
containerRight = containerRectObject.right;
return containerRight;
}
Go trought each storyLink and certain data-attribute if it's last of row.
This uses containerRight -value from previous function.
$(".storylink").each(function(key, value) {
$(this).append("<h2>Storylink no: " + key + "</h2>");
$(this).attr("data-open", "false");
$(this).attr("data-target", "content-" + key).append("<em>My data-target is 'content-" + key + "'</em>");
storyLinkRectObject = this.getBoundingClientRect();
storyLinkRight = storyLinkRectObject.right;
if(storyLinkRight == containerRight){
$(this).attr("data-row",dataRow);
$(this).attr("data-endOfRow",dataRow);
dataRow++;
}else{
$(this).attr("data-row",dataRow);
}
});
On click, dynamically move contentBlock after last storylink on the row.
//Destroy previous content of dynamicContentBlock
$(".dynamicContentBlock").html("");
$(".dynamicContentBlock").append(storyContent);
console.log(currentRow);
$(".dynamicContentBlock").insertAfter($("*[data-endOfRow='"+currentRow+"']"));
$(".dynamicContentBlock").show("slow");
Check the whole code HERE
I improved my answer based on your comment. Now the code checks if window width is small or not and if it's small (mobile), it does the following.
toggle clicked .storyLink larger (optional)
get wanted .storyBlock, based on assigned data-attributes (new)
use insertAfter() -jQuery method to move selected .storyBlock-node
after clicked .storyLink (new)
show wanted content(your code)
Notice:
I added some custom data-attributes on .storyLinks, .storyblocks
and to .story-elements. (only to first set of links)
I added .story for each .storyLink just to make things more clear to myself. Stories are now shown based on class "open".
CodePen
You can find code here
OLD ANSWER
If I understood you right, then this might help you.
Assigining data-targets (or similar), you can easily detect what content block to show on click.
I used .toggle() -jQuery method, but if you don't want to hide content block on second click, then you can just use .show() instead.
Hope this helps!
CodePen
Related
I've been searching all over the internet for this one, and either the suggestions don't seem to apply, or I'm not using the right terminology to describe what I'm wanting to do, so nothing comes up.
Here's the long story:
On our Home Page, we have a section called "Industries". In this section, there are a few choices, "Government", "Manufacturing", "Energy", "Health Care", etc. A visitor to our site can click on one of those choices and it will take them to our Product Filter Page. I would like to have it so that if they clicked on "Manufacturing", that the option would already be chosen on the Product Filter Page, so they only see our products that are available for the Manufacturing Industry.
I am not a coder by any means, but I have been able to take code that I find on forums, and slightly modify it to make it work on our site, to achieve other functionality that we've wanted. But I can't seem to find anything that makes any sense to me that would allow me to modify it to work for us in this case.
Here is the code that makes up the drop-down list on the Product Filter Page, that relates to the Industries that could be chosen:
<div class="dv-dropdown">
<div class="caption">All Industries</div>
<div class="list">
<div class="item df-button">All Industries</div>
<div class="item df-button dfc-retail">Retail</div>
<div class="item df-button dfc-construction">Construction</div>
<div class="item df-button dfc-warehousing">Warehousing</div>
<div class="item df-button dfc-manufacturing">Manufacturing</div>
<div class="item df-button dfc-government">Government</div>
<div class="item df-button dfc-energy">Energy</div>
<div class="item df-button dfc-automotive">Automotive</div>
<div class="item df-button dfc-printing">Printing</div>
<div class="item df-button dfc-healthcare">Health Care</div>
</div>
</div>
I'm not sure what exactly I could include for the Javascript that is on the page, as it is from a purchasable plugin - Divi Filter - and I'm pretty sure that this will need custom script to get it to work.
This is my first post, so please let me know if you need anything else from me. I am currently in the process of creating the site, so it's not exactly live. Thus, if there's any reference to URL links, please just make use of a generic site example, and I can replace it as needed.
Thank you all in advance for your help, and I will do my best to respond to any questions you may have, but please keep in mind my inexperience with coding.
EDIT:
Here is a snippet of the Javascript used for filtering the classes:
var activeClasses = [];
jQuery(function() {
jQuery('.dv-dropdown .df-button').on('click', function() {
// get number of dropdown
var dvIndex = jQuery(this).closest(".dv-dropdown").index(".dv-dropdown");
/* remove class */
if (activeClasses[dvIndex] != "") {
jQuery('.dv-dropdown:not(:eq(' + dvIndex + ')) .df-button').each(function() {
jQuery(this).removeClass(activeClasses[dvIndex]);
});
activeClasses[dvIndex] = "";
}
// get button classes
var filterClasses = jQuery(this).attr('class').split(/\s+/);
// remove all classes except dfc-
filterClasses = jQuery.grep(filterClasses, function(element) {
return element.indexOf("dfc-") === 0;
});
// remove all other active classes from button
jQuery.each(activeClasses, function( index, value ) {
if(index !== dvIndex) {
filterClasses = filterClasses.filter(e => e !== activeClasses[index]);
}
});
if (filterClasses[0] != undefined) { // undefined if you click on all, because no class then just remove
activeClasses[dvIndex] = filterClasses[0];
jQuery('.dv-dropdown:not(:eq(' + dvIndex + ')) .df-button').each(function() {
jQuery(this).addClass(activeClasses[dvIndex]);
});
}
// add active button class dv-activebutton
jQuery.each(activeClasses, function( index, value ) {
// remove classes
jQuery(".dv-dropdown:eq(" + index + ") .df-button").removeClass("dv-activebutton");
// add it to active element
if(value !== "" && typeof value !== 'undefined') {
jQuery(".dv-dropdown:eq(" + index + ") .df-button." + value).addClass("dv-activebutton");
}
else {
jQuery(".dv-dropdown:eq(" + index + ") .df-button.dv-all").addClass("dv-activebutton");
Here is a snippet of the Javascript used for the dropdowns
jQuery(function() {
/* toggle open class */
jQuery('.dv-dropdown > .caption').on('click', function() {
jQuery(this).parent().toggleClass('open');
jQuery('.dv-dropdown > .caption').not(this).parent().removeClass('open');
});
/* make item active element and add to caption */
jQuery('.dv-dropdown > .list > .item').on('click', function() {
jQuery(this).siblings().removeClass('selected');
jQuery(this).addClass('selected').parent().parent().removeClass('open').children('.caption').text( jQuery(this).text() );
});
/* close dropdown if Esc is clicked on keyboard */
jQuery(document).on('keyup', function(evt) {
if ( (evt.keyCode || evt.which) === 27 ) {
jQuery('.dv-dropdown').removeClass('open');
}
});
/* on click remove, close dropdown */
jQuery(document).on('click', function(evt) {
if ( jQuery(evt.target).closest(".dv-dropdown > .caption").length === 0 ) {
jQuery('.dv-dropdown').removeClass('open');
The way I would do this is add a query string to the URL that the link takes you to. So if you clicked "Manufacturing" on the first page, it would append something like "?industry=Manufacturing" to the end of the URL for the product filter page. Then, on the product filter page you would write a javascript function get the value of the query param (window.location.search). This query param would be the "value" chosen for the dropdown.
Are you using any javascript frameworks? A snippet of the code you have for the product filter page would be helpful.
I have a number of divs floating in several rows. The divs contain text-previews and a link to slide down the full content (see http://jsfiddle.net/yDcKu/ for an example).
What happens now: When you slide down the content-div it opens right after the connected preview.
What I want to happen: Open the content-div after the last div in the row.
I assume the could be done by:
1. find out which div is the last one in the row of the activated preview,
2. add an id to this div and
3. append the content-div to this div.
I have a solution for steps 2 und 3 using jQuery but no guess how to do the first step.
I can manage to get the document width and the x- and y-value of each div but I have no idea how to find out which div has the highest x- as well the highest y-value and as well is in the row of the activated preview-div.
Any idea anyone? Thanks
Here is an example that does what you want. I simplified your code, so you don't have to manually ID every entry and preview.
http://jsfiddle.net/jqmPc/1/
It's a little complicated. Let me know if you have questions.
Basically, when the window is resized, the script goes through and finds the first preview in each row by finding the preview with the same left offset as the very first one. It then adds a class last to the entry before (previous row) and class first to this preview. I do css clear: left on both of these so that everything wraps normally when the entries open.
I made your code generic, without IDs:
<div class="preview">
<p>Some preview text <a class="trigger" href="#">…</a></p>
</div>
<div class="entry">
<div class="close_button">
<a class="close" href="#">×</a>
</div>
<p>Some content text.</p>
</div>
This makes you not have to write the same code over and over.
The open/close script:
$('.trigger').click(function() {
$('.openEntry').slideUp(800); // Close the open entry
var preview = $(this).closest('.preview'); // Grab the parent of the link
// Now, clone the entry and stick it after the "last" item on this row:
preview.next('.entry').clone().addClass('openEntry').insertAfter(preview.nextAll('.last:first')).slideDown(800);
});
// Use "on()" here, because the "openEntry" is dynamically added
// (and it's good practice anyway)
$('body').on('click', '.close', function() {
// Close and remove the cloned entry
$('.openEntry').slideUp(800).remove();
});
This could be simplified a bit I'm sure, especially if you were willing to reformat your html a little more, by putting the entry inside of the preview element (but still hidden). Here is a slightly simpler version, with the html rearranged:
http://jsfiddle.net/jqmPc/2/
(I also color the first and last element on the line so you can see what is going on)
You could just get the last div in the array after calling getElementsByTagName.
var divArray = wrapperDiv.getElementsByTagName("div");
if(divArray.length > 0)
var lastDiv = divArray[divArray.length-1];
else
console.log("Empty!");
i am not able to correctly understand your question, but if you want to find out last div element in the document then you can do something like this
$("div:last")
so this will give you last div of the document
Reference:
http://api.jquery.com/last-selector/
$([1,2]).each(function(idx,el) {
$("#entry" + el).hide().insertAfter("div.entry:last");
$("#trigger" + el).click(function() {
$("#entry" + el).slideDown('800');
});
$("#close" + el).click(function() {
$("#entry" + el).slideUp('800');
});
});
http://jsfiddle.net/yDcKu/11/
I got same problem as yours, and I have been redirected to this question. But I think the answer is too complicated to my need. So I made my own way. Supposedly, you get your div list from a JSON, you can do this:
product[0] = {id: "name1", text: "text1"}
product[1] = {id: "name2", text: "text2"}
product[2] = {id: "name3", text: "text3"}
private getLastElement(id, products) {
const getTop = (id) => $("#" + id).position().top;
let itemPos = getTop(id);
let itemIndex = products.map(x => x.id).indexOf(id);
let lastID = itemIndex;
while (lastID < products.length - 1) {
if (getTop(products[lastID + 1].id) > itemPos) break;
lastID++;
}
return products[lastID].id;
}
But you can also find out by gathering all id inside your wrapper.
It works by scanning next id's row position, and return the last id of the same row.
I was looking for the same but on a single element to add style on first and last elements. #Jeff B answer helped me so alter and use it for me on one element. So the search phrase 'Get the last div in a row of floating divs' and someone looking for the same, this code may helpful:
Fiddle: https://jsfiddle.net/kunjsharma/qze8n97x/2/
JS:
$(function() {
$(window).on('resize', function() {
var startPosX = $('.preview:first').position().left;
$('.preview').removeClass("first last");
$('.preview').each(function() {
if ($(this).position().left == startPosX) {
$(this).addClass("first");
$(this).prevAll('.preview:first').addClass("last");
}
});
$('.preview:last').addClass("last");
});
$(window).trigger('resize');
});
CSS:
.preview {
float: left;
}
HTML:
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>
(firstly I recommend seeing the related image)
I have 3 container having same class .container. Also, user can add child divs dynamically into the containers. The user will start adding divs (that is .parent) by clicking '.add' div inside each '.parent'.
The containers can have at max 3 div. If the user has added 3 divs already then the next div should go in the second container and so on. Once the last container(the third one) is full, an alert should pop up saying "You cannot add anymore divs."
I have two questions:
Using jquery how can I limit the number of '.parent' divs per container to 3. If the user tries to add another it is added to container 2 (unless container 2 has 3 child divs, then it would go to container 3)?
Once the container of page 3 is full (3 divs) an alert should pop up saying "You cannot add anymore divs".
The only snippet of code that I have is not working. Please help me with the code. I am novice in all this stuff.
Thanks in advance.
Related image: [1]: http://i.stack.imgur.com/zi78d.png
Sample code:
<html>// the containers
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>//divs that are supposed to be appended
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>
<div class="parent">
<div class="add"></div>
</div>. . .
</html>
.
<script>
var $pages = $('.container');
var child = '$('.add ').parent()';
$(".add").on('click', function () {
var childAdded = false;
$pages.each(function () {
var $container = $(this);
if ($container.children().length < 3) {
$container.append.('child');
childAdded = true;
return false;
}
});
if (!childAdded) {
alert("You can not add any more divs");
}
});
</script>
Several problems in your code
You want the instance of the parent class when you click on the button, not all .parent
You have syntax errors using quotes around jQuery objects that shouldn't be there.
Here's a simple approach using filter() method.
$(".add").on('click', function () {
/* filter $pages down to first available one with space */
var $page=$pages.filter(function(){
return $(this).children().length < 3;
}).first();
if( !$page.length ){ /* if no elements returned from filter, they are all full */
alert("You can not add any more divs");
}else{
/* get instance of parent based on button that was clicked which is "this" */
var $parent=$(this).closest('.parent');
$page.append( $parent );
}
});
DEMO
filter() API docs
You have to track the amount of divs you have added yourself. Then, use this information to determine which .container you should put it in. Something like this:
var added = 0;
...
$(".add").on('click', function () {
var target;
if(added<3) {
target = $pages[0];
} else if (added<6) {
target = $pages[1];
} else if (added<9) {
target = $pages[2];
} else {
alert("You can not add any more divs");
return
}
$(target).append($(this).parent());
added += 1;
I have the following div collection in my HTML. It's designed to dynamically replicate according to user interaction.
<div class="bill-item">
<!-- Section for a single item -->
<div class="bill-item-img">
<!-- Section for Item pic -->
</div>
<div class="bill-item-description">
<!-- Section for Item description and pricing -->
<div class="bill-item-name">
<p class="bill-item-name-left">Normal Cofee</p><p class="bill-item-name-right">170.00</p>
<div class="clear"></div>
</div>
<div class="bill-item-price">
<span>170.00 USD</span>
</div>
<div class="bill-item-amount">
<span>2</span>
</div>
</div>
<div class="bill-amount-selection">
<!-- Section where the increment & decrement of item amount goes -->
<a class="amount-increase" href="#"></a>
<a class="amount-decrease" href="#"></a>
</div>
</div>
This is the HTML Rendered image of the elements.
I've written the following script to increase the bill-item-amount span value.
$(".amount-increase").click(function(){
x+=1;
$(".bill-item-amount span").html(x);
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$(".bill-item-amount span").html(x);
}
});
This works great but, it updates the value of both the span elements. what I want is to catch the event of the clicked element (which I do now) and increase the span value of the respective span. How can I filter out which span to update using javascript.?
Something like $(this).parents('.bill-item').find('.bill-item-amount span') should select the right element.
Inside your callback this is assigned to the eventSource.
You should walk the dom tree from the clicked element up until you reach the .bill-item element and the go down to the .bill-item-amount span node
$(".amount-increase").click(function(){
var $span = $(this).parent().parent().find(".bill-item-amount span");
var x = $span.html();
x+=1;
$span.html(x);
});
$(".amount-decrease").click(function(){
var $span = $(this).parent().parent().find(".bill-item-amount span");
var x = $span.html();
if(!x<=0){
x-=1;
$span.html(x);
}
});
Hi dimal update your code:
$(".amount-increase").click(function(){
x+=1;
$(".bill-item-amount").html(x);
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$(".bill-item-amount").html(x);
}
});
dont add span inside the selector [ it changes entire span values]
$(".amount-increase").click(function(){
x+=1;
$("use ur increase span id here").html(x); //
});
$(".amount-decrease").click(function(){
if(!x<=0){
x-=1;
$("use ur decrease span id here").html(x);
}
});
Inside each function the selector $(".bill-item-amount span") will find all the <span> amounts in the document. You can walk the DOM to find the correct <span> using jQuery or plain JavaScript. You seem to be using jQuery functions so my answer also uses jQuery.
The following code combines the two actions into a single function that increases or decreases the amount based on the class name of the <a> clicked. I also added a return false so that the browser will not follow the href="#" on the anchor.
$('.bill-amount-selection').on('click', 'a', function(){
var change = this.className == 'amount-increase' ? 1 : -1
var $amount = $(this).closest('.bill-item').find('.bill-item-amount span')
var amount = parseInt($amount.html(), 10) + change
$amount.html(amount < 0 ? 0 : amount)
return false
});
The use of .on() means that jQuery v1.7+ is required. I can supply a compatible function with lower jQuery versions if necessary.
I have a number of divs floating in several rows. The divs contain text-previews and a link to slide down the full content (see http://jsfiddle.net/yDcKu/ for an example).
What happens now: When you slide down the content-div it opens right after the connected preview.
What I want to happen: Open the content-div after the last div in the row.
I assume the could be done by:
1. find out which div is the last one in the row of the activated preview,
2. add an id to this div and
3. append the content-div to this div.
I have a solution for steps 2 und 3 using jQuery but no guess how to do the first step.
I can manage to get the document width and the x- and y-value of each div but I have no idea how to find out which div has the highest x- as well the highest y-value and as well is in the row of the activated preview-div.
Any idea anyone? Thanks
Here is an example that does what you want. I simplified your code, so you don't have to manually ID every entry and preview.
http://jsfiddle.net/jqmPc/1/
It's a little complicated. Let me know if you have questions.
Basically, when the window is resized, the script goes through and finds the first preview in each row by finding the preview with the same left offset as the very first one. It then adds a class last to the entry before (previous row) and class first to this preview. I do css clear: left on both of these so that everything wraps normally when the entries open.
I made your code generic, without IDs:
<div class="preview">
<p>Some preview text <a class="trigger" href="#">…</a></p>
</div>
<div class="entry">
<div class="close_button">
<a class="close" href="#">×</a>
</div>
<p>Some content text.</p>
</div>
This makes you not have to write the same code over and over.
The open/close script:
$('.trigger').click(function() {
$('.openEntry').slideUp(800); // Close the open entry
var preview = $(this).closest('.preview'); // Grab the parent of the link
// Now, clone the entry and stick it after the "last" item on this row:
preview.next('.entry').clone().addClass('openEntry').insertAfter(preview.nextAll('.last:first')).slideDown(800);
});
// Use "on()" here, because the "openEntry" is dynamically added
// (and it's good practice anyway)
$('body').on('click', '.close', function() {
// Close and remove the cloned entry
$('.openEntry').slideUp(800).remove();
});
This could be simplified a bit I'm sure, especially if you were willing to reformat your html a little more, by putting the entry inside of the preview element (but still hidden). Here is a slightly simpler version, with the html rearranged:
http://jsfiddle.net/jqmPc/2/
(I also color the first and last element on the line so you can see what is going on)
You could just get the last div in the array after calling getElementsByTagName.
var divArray = wrapperDiv.getElementsByTagName("div");
if(divArray.length > 0)
var lastDiv = divArray[divArray.length-1];
else
console.log("Empty!");
i am not able to correctly understand your question, but if you want to find out last div element in the document then you can do something like this
$("div:last")
so this will give you last div of the document
Reference:
http://api.jquery.com/last-selector/
$([1,2]).each(function(idx,el) {
$("#entry" + el).hide().insertAfter("div.entry:last");
$("#trigger" + el).click(function() {
$("#entry" + el).slideDown('800');
});
$("#close" + el).click(function() {
$("#entry" + el).slideUp('800');
});
});
http://jsfiddle.net/yDcKu/11/
I got same problem as yours, and I have been redirected to this question. But I think the answer is too complicated to my need. So I made my own way. Supposedly, you get your div list from a JSON, you can do this:
product[0] = {id: "name1", text: "text1"}
product[1] = {id: "name2", text: "text2"}
product[2] = {id: "name3", text: "text3"}
private getLastElement(id, products) {
const getTop = (id) => $("#" + id).position().top;
let itemPos = getTop(id);
let itemIndex = products.map(x => x.id).indexOf(id);
let lastID = itemIndex;
while (lastID < products.length - 1) {
if (getTop(products[lastID + 1].id) > itemPos) break;
lastID++;
}
return products[lastID].id;
}
But you can also find out by gathering all id inside your wrapper.
It works by scanning next id's row position, and return the last id of the same row.
I was looking for the same but on a single element to add style on first and last elements. #Jeff B answer helped me so alter and use it for me on one element. So the search phrase 'Get the last div in a row of floating divs' and someone looking for the same, this code may helpful:
Fiddle: https://jsfiddle.net/kunjsharma/qze8n97x/2/
JS:
$(function() {
$(window).on('resize', function() {
var startPosX = $('.preview:first').position().left;
$('.preview').removeClass("first last");
$('.preview').each(function() {
if ($(this).position().left == startPosX) {
$(this).addClass("first");
$(this).prevAll('.preview:first').addClass("last");
}
});
$('.preview:last').addClass("last");
});
$(window).trigger('resize');
});
CSS:
.preview {
float: left;
}
HTML:
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>
<div class="preview">
<p>Some preview text</p>
</div>