everyone.
I've just started using the mobifyjs toolkit and I've ran into a problem of combining two collections of elements into one.
On a page I'm trying to mobify there are two sets of links: with text and images. The HTML looks like the following:
<!-- links with text -->
<div id="products">
Product 1
Product 2
</div>
...
<!-- somewhere else on the page -->
<div id="productImages">
<img src="Product1.png />
<img src="Product2.png />
</div>
It needs to turn into the following:
<div class="items">
<div class="item">
<div class="img">
<img src="Product1.png />
</div>
<div class="title">
Product 1
</div>
</div>
<div class="item">
<div class="img">
<img src="Product2.png />
</div>
<div class="title">
Product 2
</div>
</div>
</div>
My current solution is to use map function, so in the mobify.konf I have something like the following:
'content': function(context) {
return context.choose(
{{
'templateName': 'products',
'products': function(){
return $('#productImages a').map(function() {
var href = $(this).attr('href') || '';
var div = $('<div class="item"><div class="img"></div><div class="title"></div></div>');
div.find('.img').append($(this).clone());
div.find('.title').append($('#products a[href="' + href + '"]').clone());
return div;
});
}
})
}
And the template is:
<div class="items">
{#content.products}
{.}
{/content.products}
</div>
This code does work but the approach itself is pretty ugly since I have to move a piece of markup code from the tmpl file into mobify.konf. Can anyone suggest a better solution?
The best way to do this sort of thing is to collect the relevant properties for your items (e.g. the product name, the image url and the link href) into a data structure in javascript, and then create a template for your new html structure in the .tmpl file. Something like
'products': function() {
var products = [],
$productLinks = $('#products a'),
$productImages = $('#productImages img')
len = $productNames.legnth;
for(var i = 0; i<len; i++) {
var $link = $productLinks.eq(i);
var $img = $productImages.eq(i);
products.push({name: $link.text(), href: $link.attr('href'), imgSrc: $img.attr('src')});
}
return products;
}
and then template it by iterating over the array items and inserting them into relevant places in the markup:
<div class="items">
{#content.products}
<div class="item">
<div class="img"><img src="{.imgSrc}" /></div>
<div class="title">{.name}</div>
</div>
{content.products}
</div>
Related
I wrote a function that dynamically creates a webpage for me based on a json database.
Now I want to add 2 functions:
If you click the like img (its got the id button) the like counter should increase on the webpage by 1. Pretty easy just a on(click) with jQuery variable++ and then .text(variable)
A sort function - based on the likes one item received, you should be able to sort it (most liked div first, 2nd, 3rd....
I can write it for each individually with individual variables when I give all the like buttons and outputs a separate id but I wanted to make it dynamic so if you add new data to json file it dynamically works with the like and sort function.
The likes are not saved anywhere for now.
Since sitting on it for 3h and google so much and so much stackoverflow I think I overloaded my brain with different stuff and now nothing seems to work ^^
function filmInsert(insert) {
$.each(film, function(i, data) { //.each statt loop
let box =
`<div class="boxwrapper">
<div class="imgbox">
<img src="${data.img}" alt="${data.titel}">
</div>
<div class="textbox">
<h3>${data.titel}</h3>
<p>${data.beschreibung}</p>
<p> <a id="button${data.id}">
<img src="img/budspencer_official.png"> Like
</a>
<span class="output${data.id}">${data.likes}</span>
</p>
</div>
</div>`;
insert.append(box);
});
}
I've added a container element for the boxwrapper items as I assume you have one and as it's better to have one instead of just adding the sorted items to the body of the HTML document.
$(document).on("click", ".textbox a", function() {
let likes = parseInt($(this).closest(".textbox").find("span").text());
$(this).closest(".textbox").find("span").text(likes + 1);
});
$("#sort").on("click", function() {
let divs = $(".boxwrapper")
let sorted = divs.sort(function(a, b) {
return $(a).find("span").text() < $(b).find("span").text() ? 1 : -1;
});
$(".container").html(sorted);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel</h3>
<p>Description</p>
<p> <a id="button1">
<img src="https://dummyimage.com/40x40/000/fff&text=1"> Like
</a>
<span class="output1">0</span>
</p>
</div>
</div>
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel 2</h3>
<p>Description 2</p>
<p> <a id="button2">
<img src="https://dummyimage.com/40x40/000/fff&text=2"> Like
</a>
<span class="output2">0</span>
</p>
</div>
</div>
</div>
<button id="sort">
Sort
</button>
I am trying to modify the links in my page using JavaScript. I can select the div and the a element but cannot change the href.
Shopify is using a for loop to generate these objects and need each object to have a different link.
Here is the HTML:
<div id="tri-banner-1" class="banner-element banner-1 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner01.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
<div id="tri-banner-2" class="banner-element banner-2 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner02.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
<div id="tri-banner-3" class="banner-element banner-3 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner03.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
Here is my JavaScript.
<script type="text/javascript">
$(window).bind("load", function() {
window.alert("Test");
var banner1 = document.getElementById("tri-banner-1");
var banner1Links = banner1.getElementsByTagName("a");
banner1Links.href="facebook.com";
});
</script>
banner1.getElementsByTagName("a"); returns an HTMLCollection . You should either select the element using the index ; e.g.;
// set `href` of first `a` element in `bannerLinks`
banner1Links[0].href = "facebook.com";
or iterate the collection
for (var i = 0; i < bannerLinks.length; i++) {
bannerLinks[i] = /* set `href` here */;
}
banner1Links gets an array value so you need to loop in that array and for every array element you pass the value
// instead of banner1Links.href="facebook.com";
for(var i = 0; i < banner1Links.length; i += 1){
banner1Links[i] = 'http://example.com';
}
Here is the code I have. This can not be changed, I have to work with the structure as is.
<div class="container">
<div class="contain_box">
<a href="something">
<img class="my_img" src="some_image">
</a>
<div class="variants">
<div class="var" rel="123" data="321"></div>
<div class="var" rel="1234" data="4321"></div>
</div>
</div>
<div class="contain_box">
<a href="something">
<img class="my_img" src="some_image">
</a>
<div class="variants">
<div class="var" rel="456" data="654"></div>
<div class="var" rel="4567" data="7654"></div>
</div>
</div>
<div class="contain_box">
<a href="something">
<img class="my_img" src="some_image">
</a>
<div class="variants">
<div class="var" rel="789" data="987"></div>
<div class="var" rel="7890" data="0987"></div>
</div>
</div>
</div>
What I need is when I click on one of the images it will pull the rel and the data from its first variant, add those attributes to the image tag. Right now I am trying this and I only get the undefined. I am using the undefined to clear out those variables from the current values.
$(document).on("click", '.my_img', function(e){
e.preventDefault();
data = undefined;
rel = undefined;
var new_rel = $('.var').attr('rel');
var new_data = $('.var').attr('data');
$('.my_img').attr('rel', new_rel);
$('.my_img').attr('data', new_data);
data = $(this).attr('variant');
rel = $(this).attr('rel');
}
Any insights or help would be awesome! Thanks in advance!
Find the parent container (.contain_box) relative to the clicked image, then the first variant from there:
Demo
$(document).on("click", '.my_img', function(e){
e.preventDefault();
var firstVariant = $(this).closest('.contain_box').find('.var').first();
data = firstVariant.attr('rel');
rel = firstVariant.attr('data');
$(this).attr({
data : data,
rel : rel
});
console.log(data);
console.log(rel);
});
I've been looking for an elegant solution for a day now and I am pretty new to jQuery.
I would like to get each .figure and assign them an inline style where the value is contained inside the child element via a custom data- attribute :
<div>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-01-thumbnail.png" src="images-01.png" />
</div>
<div class="content">
<h3>Sale</h3>
<h4>Discover our latest styles</h4>
</div>
</a>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-02-thumbnail.png" src="images-02.png" />
</div>
<div class="content">
<h3>Free Shipping</h3>
<h4>When you buy xxxxxx</h4>
</div>
</a>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-03-thumbnail.png" src="images-03.png" />
</div>
<div class="content">
<h3>Free Shipping</h3>
<h4>When you buy xxxxxx</h4>
</div>
</a>
</div>
In other words, the results would be :
...
<div class="figure" style="background: url(images-01-thumbnail.png);">
...
<div class="figure" style="background: url(images-02-thumbnail.png);">
...
<div class="figure" style="background: url(images-03-thumbnail.png);">
...
Also, I'm always ready something about jQuery so if you have any books about JavaScript or jQuery to suggest, that is always appreciated.
You can iterate over all .picture elements, find the image descendant and read its data attribute:
$('.figure').css('background', function() {
return 'url(' + $(this).children('img').data('thumbnail') + ')';
});
Some methods, like .css even accept functions so that you can iterate over the selected elements implicitly.
Reference: .css, .children, .data
you can iterate over each item with the class thumbnail and set the css property to the closet div.
$('.thumbnail').each(function() {
var $this = $(this),
$background = $this.data('thumbnail');
$this.closest('.figure').css({background : $background} )
});
This should work
$("[data-thumbnail]").each(function ()
{
var $this = $(this), url = $this.data("thumbnail");
$this.parents(".figure").css("background-image", 'url("' + url + '")');
});
How about this (Working code example: http://jsfiddle.net/jpbH2/2/):
var pathToImages = "/";
$(".figure img").each(function(){
$(this).parent().css({"background": "url(" + pathToImages + $(this).data('thumbnail') +")"})
});
Edit
I actually didn't notice the data-thumbnail. Edited my answer above
Okay, so I am in the process of recreating this feature:
http://www.w3.org/html/logo/#the-technology
I current have it so when you click on a link, it will add a class to the image that relates to that link (href="#one" on the <a> and then id="#one" on the <img>), however it is currently not going through each <a> tag and only one. And also it is not removing the class I requested.
Code follows:
JS
$(document).ready(function() {
var container = '#portfolio #text_container';
var img_container = '#portfolio #image_container';
$(container).children('a').bind('click', function() {
var this_attr = $(this).attr('href');
var this_img = $(img_container).find('img').attr('id');
if(this_attr == this_img) {
//$(img_container).find('img').hasClass('current').removeClass('current');
// ^^^ This line isn't working, any ideas? :/
$(img_container + ' img[id*="' + this_attr + '"]').addClass('current');
}
else {
alert(this_img + ' this img');
alert(this_attr + ' this attr');
}
});
});
And the HTML is as follows
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="current" id="#one" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" id="#two" />
</div>
<div id="text_container">
Item 1
Item 2
<p id="#one" class="current">A bunch of text!</p>
<p id="#two">The second bunch of text!</p>
</div>
</div>
Please let me know if you need any more information :)
rcravens fixed this with the following code..
JS
$(document).ready(function() {
$('#text_container a').click(function(evt) {
evt.preventDefault();
$('.current').removeClass('current');
var href = $(this).attr('href');
$("." + href).addClass('current');
});
And the HTML..
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="one current" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" class="two" />
</div>
<div id="text_container">
Item 1
Item 2
<p class="one current">A bunch of text!</p>
<p class="two">The second bunch of text!</p>
</div>
</div>
My interpretation of what you are trying to do is here:
http://jsfiddle.net/rcravens/wMhEC/
The code is changed a bit. You shouldn't have multiple elements with the same id.
Bob
The reason this isn't working:
if(this_attr == this_img)
is because this_attr is a URL and this_img is an ID attribute value.