find elements > get attribute > append to cousin - javascript

<div class="links">
<ul>
<li class="pdf"></li>
<li class="weiter">more</li>
</ul>
</div>
For each LI.weiter, I want to grab the link add sth and append it as PDF-Link:
var LinkMarkup = '<a href="';
$('.weiter A').each(function() {
LinkMarkup += $(this).attr('href') + '&type=999" target="_blank">PDF</a>';
$(this).closest('.pdf').append($(LinkMarkup));
});
Thanks a lot!

Close, the anchor is a child of the li, to you can use find. The .pdf is actually a sibling, but is also the previous element, so use .prev. You also need to build the actual a element and append:
$('.weiter').each(function() {
var href = $(this).find("a").attr('href') + "&type=999",
link = "<a href='" + href + "' target=_blank>PDF</a>";
$(this).prev('.pdf').append(link);
});

Related

Ajax loader script for multiple items

I have list element like this
<ol class="listItem">
<li id="#item-1" class="NewsFeedItem">
Example Url
<div class="attachedImage"></div>
</li>
<li id="#item-2" class="NewsFeedItem">
Example Url 2
<div class="attachedImage"></div>
</li>
<li id="#item-3" class="NewsFeedItem">
Example Url 3
<div class="attachedImage"></div>
</li>
...
</ol>
I want to use just one script to load content for each li. I wrote some code here but it isn't working
$('.NewsFeedItem').each(function() {
var id = $(this).get(0).id;
$('#' + id + '.attachedImage').load( $('#' + id + '.threadLink').attr('href') + ' .firstPost .messageText img' );
});
Where was I wrong?
Your code is fine, except at two points. To select the descendants, you need to separate the selectors by a space, which you are lacking in this line:
$('#' + id + ' .attachedImage').load( $('#' + id + ' .threadLink').attr('href') ...
A selector like #id.attachedImage will look for an element with ID as id, having a class attachedImage assigned to it.
If you want to select an element, having a class attachedImage assigned to it, and which is a descendant of an element of ID id, you need to write the selector as #id .attachedImage.
Edit 1:
Since the value in id already has a #, you need to remove the # from your selectors as well:
$( id + ' .attachedImage').load( $( id + ' .threadLink').attr('href') ...
Just Remove '#'
$( id + '.attachedImage').load( $( id + '.threadLink').attr('href') + '.firstPost .messageText img' );

Using $(this) within .each()

I have a series of elements laid out in HTML
I am trying to get the value of the href for each div with the class wsite-com-category-product-wrap and then use this to insert a new button with the same href.
My current code is inserting all the links (for items with the class .wsite-com-category-product-wrap) into themselves meaning that each element has about 10 links in now instead of just the one.
The code I have written to do this:
$(".wsite-com-category-product-wrap").each(function() {
var link = $(this).find("a").attr("href");
$("<a href=" + link + " class='custom-category-button'>Test</a>").insertAfter(".wsite-com-product-price");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wsite-com-category-product-wrap">
Link content
<div>more divs</div>
</div>
You can use a jquery object with .insertAfter, not just a string selector.
So, change this:
$("<a href=" + link + " class='custom-category-button'>Test</a>")
.insertAfter(".wsite-com-product-price");
to:
$("<a href=" + link + " class='custom-category-button'>Test</a>")
.insertAfter($(".wsite-com-product-price", this));
I found that with the insertAfter I needed to add in something ensuring it was only being added to $(this).
I used a new variable insertHere to make it simpler:
$(".wsite-com-category-product-wrap").each(function() {
var link = $( this ).find("a").attr("href");
var insertHere = $(this).find(".wsite-com-product-price");
$( "<a href=" + link +" class='custom-category-button'>Test</a>" ).insertAfter( insertHere );
});

How to set different <a href> and <img src> dynamically in divs with same class name?

I have an array of objects(each that are made up of image link and link). As I access each of them I would like to make a new div each time and add a different image link and link.
<div class="igo_product"
<a href>
link1
<img class="igo_product_image" src="imglink1">
</div>
<div class="igo_product"
<a href>
link2
<img class="igo_product_image" src="imglink2">
</div>
<div class="igo_product"
<a href>
link3
<img class="igo_product_image" src="imglink3">
</div>
Currently the only way I can place different images and links is by creating different class names by concatenating indexes at the end each time.
$.each(items, function (index, value) {
$(".igo_boxbody").append('<div class="igo_product' + index + '"<a><img class="igo_product_image' + index + '"></a></div>')
$(".igo_product" + index + "a").attr('href', value["link"].toString());
$(".igo_product_image" + index).attr('src', value["image_link"] );
});
However, $(".igo_product" + index + "a").attr('href', value["link"].toString()); does not correctly set my href...I'm assuming it's my way I'm concatenating the class, index, and a but I'm slightly stuck on what else I can do. Also, is there a better way to do this? I would rather keep the class name the same so that I can apply styles to all these classes easier.
How about this:
$.each(items, function (index, value) {
$(".igo_boxbody").append('<div class="igo_product"<a href="'+value["link"].toString()+'"><img class="igo_product_image" src="'+value["image_link"]+'"></div>');
});
There is an error:
$(".igo_boxbody").append('<div class="igo_product' + index + '"<a><img class="igo_product_image' + index + '"></a></div>')
//-----------------------------------------------------------^---no closing of div >
so change to this:
$(".igo_boxbody").append('<div class="igo_product' + index + '"><a><img class="igo_product_image' + index + '"></a></div>')
Should go for this:
$.each(items, function (index, value) {
var el = '<div class="igo_product"' + index
+ '><a href="'+value["link"]
+'"><img class="igo_product_image' + index
+ '" src="'+value["image_link"]+'"></a></div>'
$(".igo_boxbody").append(el);
});
By no means I intend to imply the following is better, but just to mention the option: you can use jquery to create html objects outside the DOM (e.g. $('<div>') creates a new div) and set their properties/attributes/classes/etc through those objects (also before adding them to the DOM).
The advantage is that you don't have to delve into the strings to catch those closing tags:
$('.igo_boxbody').append(items.map(function(value, index){
return $('<div>').addClass('igo_product').append(
$('<a>').attr('href', value.link).append(
$('<img>').attr('src', value.image_link).addClass('igo_product_image' + index)
)
);
}));
Fiddle

slideToggle() doesn't push elements created with jquery append() down

I do have a problem using slideToggle(). The following DOM elements won't be pushed down, they just overlap. I tried a lot of versions. I do create the tags with jquery getting a JSON from which I fill in the tag content, so I iterate over the JSON to create the HTML tags for each element :
var project_infos = '';
jQuery(document).ready(function(){
$.getJSON('project.json', function(data){
project_infos += '<div class=\"row\">'
+ '<div class=\"span3\">'
+ '<div class=\"well\">'
+ '<div>'
+'<ul class=\"nav nav-list sidebar-list\">';
for( var i = 0; i < data.length; i ++ ) {
var project_name = data[i]["item"];
project_infos += '<li>'
+'<label class=\"tree-toggler nav-header\">'
+'<i class=\"fa fa-arrow-right\"></i>' + project_name + '</label>'
+'<ul class=\"nav nav-list tree\">'
+'<li><label class=\"tree-toggler nav-header\">Katalogue</label></li>'
+'<li>'
+'<ul class=\"nav nav-list tree\">'
+'<li>Link</li>'
+'<li>Link</li>'
+'<li>Link</li>'
+'</ul>'
+'</li>'
+'<li><label class=\"tree-toggler nav-header\">History</label></li>'
+'<li><label class=\"tree-toggler nav-header\">Whole project</label></li>'
+'</ul>'
+'</li>';
}
project_infos += '</ul></div></div></div></div>';
$('#tree').append(project_infos);
$('.tree-toggler').click(function () {
$(this).parent().children('ul.tree').slideToggle('slow');
});
});
});
EDIT : screenshot of html output.
screenshot html output
Thanks in advance!
Use
find() instead of children()
$(this).parent().find('ul.tree').slideToggle('slow');
children() will only search for first level child elements.
I just reset all css styles for my div and finally it worked. I already defined styles for the sidebar and for the ul and li tags. One of the styles was the problem. It kept the elements from toggle down in the sidebar.
Thanks for your time!

Wrap each list array in a Tag

I am trying to get each Post lists wrapped in the href so it can be clicked on. Basically when I try to click on each Posts, it does not work until I hover my mouse close to the top of each posts before it works.
Below is my code and also an image of what I mean:
JS:
function getPosts(data) {
var $output = $('<ul class="posts" data-role="listview" data-filter="true">')
$.each(data.posts,function(i, val) {
$('<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).appendTo($output);
if ( i == 3 ) return false;
// return (postlimit-- > 1);
});
$('#postlist').empty().append($output);
}
function showPost(id) {
$('#mypost').html('<span class="img_spin">Loading post...</span>');
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
var posts='';
posts += '<h3>' + data.post.title + '</h3>';
posts += data.post.content;
$('#mypost').html(posts);
});
}
Image:
If you look at the image, when i hover my mouse close to the top edge of the Post, then the URL at the bottom shows and that works but any where else does not work.
From looking at the Chrome Elements tab in this demo the JavaScript is generating invalid HTML because of mismatched closing elements.
Using an example posts of var posts = { "posts" : [ {"id":"1", "title":"lorem", "excerpt":"foo"}, {"id":"2", "title":"ipsum", "excerpt":"bar"} ] }
This '<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>' is resulting in the broken first child of the following <li>:
<li>
<a href="#devotionpost" onclick="showPost(1)" < a></a>
<h3>lorem</h3>
<p>foo</p>
</li>
Depending on exactly what you want to wrap in the anchor element, you could just build the post <li> like in this updated demo or see code below:
$.each(data.posts,function(i, val) {
$output.append('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
});
Or if you want to have a little less string concatenation, you could use .wrapInner()
$.each(data.posts,function(i, val) {
var $post = $('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
$post.wrapInner('');
$output.append($post);
});
Or keeping your .append() approach:
$.each(data.posts,function(i, val) {
var $post = $('<li/>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).wrapInner('');
$output.append($post);
});
Note: The string concatenation approach, combined with a single .append() is the best performing code.
By the looks of it, your lists are floating. You should use a clearfix technique to make "A" element box include the list. You also should know that by standard "A" elements are not allowed to contain block elements and as far as internet explorer 9 (didn't check in 10 or 11) "A" will not work the way you intended.
Possible workaround:
<div style="position:relative">
<ul>
<li></li>
<ul>
<a style="position:absolute;display:block;top:0;bottom:0;left:0:right:0;" href="#"></a>
<div>

Categories