Masonry why arranging in single column overlapping - javascript

I am using the appended function to append elements to an already initialized masonry instance, but all of my tiles are being laid out in a single column and many are overlapping. Can you see what I am doing wrong?
function placeNewsTiles(news){ //places news tiles
var length = (news.data.length > 20) ? 20 : news.data.length;
var $container = $('#news');
var elems ="";
for(var i = 0; i < length; i++){
elems += '<div class="pageNewsItem" id="'+ count + i + '">\
<div class="textWrap">\
<a href="' + news.data[i]._url + '">\
<strong>' + news.data[i]._title + '</strong>\
</a>\
<span class="source">' + news.data[i]._source + '</span>\
</div>\
<div class="imageWrap"></div>\
<div class="thumbsOverlay" style="display:none">\
<div class="thumbs">\
<div>\
<img src="../images/Thumbs-Up-2.png" />\
<img src="../images/Thumbs-Down-2.png" />\
</div>\
</div>\
</div>\
</div>';
getTileImage({total: news.count, i:count + "" + i, url:news.data[i]._url});
}
elems = $(elems);
$('#news').append(elems).imagesLoaded(function(){
$('#news').masonry( 'appended', elems, true );
});
newsPage = 0;
count++;
hoverTiles();
}
$(document).ready(function() {
newClock();
readyLogin();
var $container = $('#news');
//$container.imagesLoaded( function() {
$container.masonry({itemSelector: '.pageNewsItem'});
//});
obtainSearchQuery();
});

On this line, try triggering layout once items are appended:
$('#news').masonry( 'appended', elems, true ).masonry('layout');
I've seen examples with and without the extra .masonry() call, but it might work.

Related

Create second or next <li> under default <li> after reload page | jQuery, LocalStorage

I try to create LocalStorage data for My Folder Creation .
HTML :
This is my default li. I call it All audience folder's
<!-- Result goes here -->
<ul class="nav">
<li>
<div class="zf-folder" style="width: 232px;">
<div class="_tabFolder _itemPosition" style="height: 50px;border-bottom:1px groove; user-select: none;">
<div class="_sideFolder"></div>
<div class="_iconText" style="width: 215px">
<div class="ellipsis">
<div class="_1i5w">
<div class="_icon-col">
</div>
</div>
All Audiences<span class="hyperspan" style="position:absolute; width:100%; height:100%; left:0; top:0;"></span>
</div>
</div>
</div>
</div>
</li>
</ul>
jQuery :
var count = 1;
$(".submitButton").click(function() {
let label = count++;
// make a function that returns the DOM with updated count
function getNewList(foldername) {
var addFolder = '<li>' +
'<div class="zf-folder" style="width: 232px;">' +
'<div class="_tabFolder _itemPosition" style="height: 50px;border-bottom:1px groove; user-select: none;">' +
'<div class="_sideFolder"></div>' +
'<div class="_iconText" style="width: 215px">' +
'<div class="ellipsis">' +
'<div class="_iconFolder">' +
'<div class="_icon-col">' +
'</div>' +
'</div>' +
'<a href="#folder' + label +
'" data-toggle="tab" style="text-decoration: none;">' +
foldername + '<span class="hyperspan" style="width:100%; height:100%; left:0; top:0;"></span></a>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</li>';
return addFolder;
}
var inputan = $("#input_nameFolder").val();
// update the result array
var result = JSON.parse(localStorage.getItem("folderList"));
if (result == null) {
result = [];
}
let newfolderHTML = getNewList(inputan);
result.push({
folder: newfolderHTML
});
// save the new result array
localStorage.setItem("folderList", JSON.stringify(result));
// append the new li
$(".nav").append(newfolderHTML); // i want include myDiv
//clear input
$("#input_nameFolder").val('');
});
// on init fill the ul
var result = JSON.parse(localStorage.getItem("folderList"));
if (result != null) {
//get the nav reference in DOM
let nav = $(".nav");
//clear the html contents
nav.html('');
for (var i = 0; i < result.length; i++) {
var item = result[i];
$(".nav").append(item.folder);
}
}
How to adding new <li> tag under my default li (all audience)
after reload page/click run jsfiddle when user input a new value?
You can see after adding an input and reload web / jsfiddle, new input folder's (second li) overwrite all audience (first li).
JSFiddle
you just have to save the initial element upon initialization, see:
// on init fill the ul
var result = JSON.parse(localStorage.getItem("folderList"));
if (result != null) {
//get the nav reference in DOM
let nav = $(".nav");
//clear the html contents
nav.html('');
for (var i = 0; i < result.length; i++) {
var item = result[i];
$(".nav").append(item.folder);
}
} else {
//Save the "All Audiences" content upon empty folderList
let initialElement = [];
initialElement.push({
folder: $('ul.nav').html()
});
localStorage.setItem("folderList", JSON.stringify(initialElement));
}
See: JSFiddle

Paragraph numbers changing HTML JAVASCRIPT

I'm working with list which elements can be added with JS by the following code:
function getMovementButtons(size, articleId, articleTitle, articleType){
var lowerArticleType = articleType.toLowerCase();
var html = '<div>'+
'<span style="vertical-align: top">'+ size +
'<span style="vertical-align: top">.</span> '+
'</span>'+
'<span style="vertical-align: top" class="'+lowerArticleType+'-title displaying-'+lowerArticleType+'-id' + articleId +'">' + articleTitle + '</span>' +
'<input class="'+lowerArticleType+'-button-delete" type="button" value="' + '<%= LanguageUtil.get(pageContext, "global.action.delete")%>' + '" onclick="removeArticle(this,\''+articleType+'\')"/>' +
'<div class="'+lowerArticleType+'-div-move"><input class="'+lowerArticleType+'-button-up" type="button" value="" onclick="moveArticleUp(this,\''+articleType+'\')"/>' +
'<input class="'+lowerArticleType+'-button-down" type="button" value="" onclick="moveArticleDown(this,\''+articleType+'\')"/>' +
'</div>'+
'</div>';
return html;
I have a function removeArticleLine.
function removeArticleLine(button) {
var parentDiv = button.parentNode
var articleListDiv = parentDiv.parentNode;
articleListDiv.removeChild(parentDiv);
}
There is a problem, because if I delete an object paragraphs don't change their numbers. I would ask you to give me a hint how can I change these numbers with JS.
I'm adding working functions which can help us. It's moving everything properly:
function moveArticleUp(button, articleType) {
var articleDiv = button.parentNode.parentNode;
var parentDiv = articleDiv.parentNode;
var prevArticleDiv = articleDiv.previousElementSibling;
if (prevArticleDiv && prevArticleDiv.tagName == 'DIV') {
var articleIdValue = getArticleIdValue(articleType);
var ids = articleIdValue.split(',');
var articleId = getArticleIdFromArticleDiv(articleDiv, articleType);
var articleIdIndex = ids.indexOf(articleId);
swapPosition(ids, articleIdIndex, articleIdIndex - 1);
setArticleIdValue(articleType, ids.join());
removedArticleDiv = parentDiv.removeChild(articleDiv);
parentDiv.insertBefore(removedArticleDiv, prevArticleDiv);
console.log(articleIdIndex);
prevArticleDiv.firstElementChild.innerHTML = articleIdIndex + 1 + '<span style="vertical-align: top">.</span> ';
articleDiv.firstElementChild.innerHTML = articleIdIndex + '<span style="vertical-align: top">.</span> ';
}
}
function moveArticleDown(button, articleType) {
var articleDiv = button.parentNode.parentNode;
var parentDiv = articleDiv.parentNode;
var nextArticleDiv = articleDiv.nextElementSibling;
if (nextArticleDiv) {
var articleIdValue = getArticleIdValue(articleType);
console.log(articleIdValue);
var ids = articleIdValue.split(',');
var articleId = getArticleIdFromArticleDiv(articleDiv, articleType);
console.log(articleId);
var articleIdIndex = ids.indexOf(articleId);
console.log(articleIdIndex);
swapPosition(ids, articleIdIndex, articleIdIndex + 1);
setArticleIdValue(articleType, ids.join());
console.log(ids.join());
removedArticleDiv = parentDiv.removeChild(nextArticleDiv);
parentDiv.insertBefore(removedArticleDiv, articleDiv);
console.log(nextArticleDiv.firstElementChild.innerHTML);
console.log(articleDiv.firstElementChild.innerHTML);
nextArticleDiv.firstElementChild.innerHTML = articleIdIndex + 1 + '<span style="vertical-align: top">.</span> ';
articleDiv.firstElementChild.innerHTML = articleIdIndex + 2 + '<span style="vertical-align: top">.</span> ';
}
}
Let me add two screenshots of the displayed table:
http://imgur.com/a/EOfkk
http://imgur.com/a/R9oru
After you remove a line you should loop the array of elements and assign new numbers for them. The code was not tested, but it should works
function removeArticleLine(button) {
var parentDiv = button.parentNode;
// getting the number of deleting div
var divNumber = parseInt(parentDiv.firstChild.textContent);
var articleListDiv = parentDiv.parentNode;
articleListDiv.removeChild(parentDiv);
// we need to loop elements after deleted div, because elements before did not change theit number
for (var i = 0 || divNumber; i < articleListDiv.children.length; i++) {
//changing number
articleListDiv.children[i].firstElementChild.innerHTML = (i + 1) + '<span style="vertical-align: top">.</span> ';
}
}

I have this code that works in JSFiddle but not on my site

I want to create a new button every time the post button is clicked and each new button should have its own counter. This works in JSFiddle but not when I use it.
$(function() {
$('.input_button').on('click', function() {
text = $('.input_text').val();
var btn = $("<button></button>");
btn.text("Like!");
$("body").append(btn);
btn.after("<span class='clicks'></span>")
var clicks = 0;
btn.click(function() {
clicks++;
$(this).next(".clicks").html(clicks);
});
if (text != undefined) {
post = '<div class="post test--post">' + '<img src="photo.JPG" width="20" height="25" alt=""/>' + '<p><span>jaleelg: </span></p>' + text +
'<p>Clicks: <a id="clicks">0</a></p>' + "<br>" + Date() + " " + '</div>';
new_post = $('.post_feed').append($(post))
new_post = $('.post_feed').append($(btn))
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<h3 id="feed">My Posts</h3>
<section class="post_feed test--post_feed">
</section>
</section>
<input class="input_text test--input_text" type="text">
<button type="submit" class="input_button test--input_button">Post</button>
<div id="clicks">
</div>
You have to change in this:
btn.click(function() {
clicks++;
$(this).next(".clicks").html(clicks);
});
Like this:
btn.click(function() {
$('.clicks').html(function(i, val) { return val*1+1 });
});
This pen works:
http://codepen.io/anon/pen/ygRxOq?editors=0010
$(function() {
$("body").on("click",".like",function(e) {
clicks = $(e.target.parentElement).find("#clicks").text() / 1 + 1;
$(e.target.parentElement).find("#clicks").text(clicks);
});
$('.input_button').on('click', function() {
text = $('.input_text').val();
post = '<div class="post test--post">' +
'<img src="photo.JPG" width="20" height="25" alt=""/>' +
'<p><span>jaleelg: </span></p>' + text +
'<p>Clicks: <a id="clicks">0</a></p>' +
'<br>' + Date() + '<br>'+
'<button class="like">Like!</button>'+
'</div>';
new_post = $('.post_feed').append($(post));
});
});

How to prevent auto tag closure in jQuery append()?

Because of formatting reasons I'm trying to nest every third result from my json file to be nested in a div class "row".
I figured this would be an easy thing to do but everytime I try jQuery closes my tags.
Proper layout should be
<div class="row">
<div class="four columns"></div>
<div class="four columns"></div>
<div class="four columns"></div>
</div>
Here is my code:
var sexIcon = '';
var typeIcon = '';
var divClassRow = ' <div class="row"> ';
var divClassRowEnd = ' </div><div class="row"> ';
$(document).ready(function(){
$.getJSON("scripts/pets.json", function(jsonData){
$.each(jsonData, function(object, value){
if (value.sex=='female'){
sexIcon = 'images/female-active.png';
}
else {
sexIcon = 'images/male-active.png';
};
if (value.type=='dog'){
typeIcon = 'images/dog-sm.png';
}
else {
typeIcon = 'images/cat.png';
}
$('.columns:first-child').before(divClassRow);
$.each($('.columns:nth-child(4n)'), function(){
$(this).after(divClassRowEnd);
});
$(".cards").append(
'<div class="four columns '+ value.type +' '+ value.sex +' '+ value.size +'">'+
'<div class="card-header"><h3>'+value.name+'</h3><img src="'+typeIcon+'" alt=""><img src="'+sexIcon+'" alt=""></div>'+
'<div class="card-content">'+
'<img src="'+value.photo+'" alt="">'+
'<p><b>Breed:</b> '+value.breed+'</p>'+
'<p><b>Sex:</b> '+value.sex+'</p>'+
'<p><b>Age:</b> '+value.age+'</p>'+
'<p><b>Time at Rescue:</b> '+value.time+'</p>'+
'<p> '+value.about+'</p>'+
'<br>'+
'<button class="button-primary u-full-width">Find Out more!</button>'+
'</div></div>'
); /*END APPEND*/
});/*END EACH*/
});/*END GETJSON*/
}); /* Document Ready */
Any ideas on what I can do? Or perhaps how to do this better.
Use wrapAll()
var list=$('.four');
for(var i = 0; i < list.length; i+=4) {
list.slice(i, i+4).wrapAll("<div class='row'></div>");
}
demo

Masonry sometimes lays out in one column straight line

I have masonry initialized on some "tiles" that include an image. Most of the time I am not having issues but sometimes the tiles lay out in one column when there should be 3 columns. Do you have any idea what the issue might be?
On ready initialization:
$(document).ready(function() {
var $container = $('#news');
$container.masonry({
itemSelector: '.pageNewsItem',
transitionDuration: 0
});
$container.masonry( 'on', 'layoutComplete', function( msnryInstance, laidOutItems ) {debounced = true;} )
});
Dynamically append tiles:
var count = 0;
function placeNewsTiles(news){ //places news tiles
var length = (news.data.length > 20) ? 20 : news.data.length;
var elems ="";
for(var i = 0; i < length; i++){
elems += '<div class="pageNewsItem inactive" id="'+ count + i + '">\
<div class="outerTextWrap">\
<div class="textWrap">\
<a href="' + news.data[i]._url + '">\
<strong>' + news.data[i]._title + '</strong>\
</a>\
<span class="source">' + news.data[i]._source + '</span>\
</div>\
</div>\
<div class="imageWrap"></div>\
<div class="thumbsOverlay" style="display:none">\
<div class="thumbs">\
<div>\
\
\
</div>\
</div>\
<div class="title">\
<div>\
<a href="' + news.data[i]._url + '">\
<div class="theTitle">Read Article</div>\
</a>\
</div>\
</div>\
</div>\
</div>';
getTileImage({total: news.count, i:count + "" + i, url:news.data[i]._url});
}
elems = $(elems);
$('#news').append(elems).imagesLoaded(function(){
//for(var i = 0; i < length; i++) $('.pageNewsItem').removeClass('inactive'); //$('.pageNewsItem').show(1000);
$('#news').masonry( 'appended', elems);
});
newsPage = 0;
count++;
hoverTiles();
}
getTileImage function is called to conduct an ajax call to obtain the tile image. Masonry layout happens on complete:
var cnt = 0;
function getTileImage(args){
var _t = localStorage.getItem("token"),
url = args.url,
i = args.i;
$.ajax({
type: "GET",
url: apiHost+'/api/tileImg?url=' + url + '&token='+_t,
dataType: "json",
success: function(data) {
var img = (data && data.image.src) ? data.img.src : (data && data.image) ? data.image: "";
if(img.indexOf("spacer") > -1|| img.indexOf("blank") > -1 || img === ""){ $('.pageNewsItem#' + i).hide(); }
else $('.pageNewsItem#' + i).find('.imageWrap').append('<img src="' + img + '" />');
},
error: function(e) {
if (e.status == 404) {
//need to get a new token
getToken(getTileImage, url);
}
}, complete: function(){
cnt++;
if ((cnt ==20) || cnt == args.total) {
var $container = $('#news');
$container.imagesLoaded( function() {
$container.masonry( 'layout' );
$('.pageNewsItem').removeClass('inactive');
//$('.pageNewsItem').show();
});
cnt = 0;
}
/*$('#news').imagesLoaded( function() {
$('.pageNewsItem#' + i + ' .thumbs').height($('.pageNewsItem#' + i).outerHeight() - $('.pageNewsItem#' + i + ' .title').height() - 5);
//$('.pageNewsItem').show();
});*/
}
});//end ajax call
}
CSS:
.pageNewsItem {
width: 33.333%;
padding: 10px;
min-height: 150px;
opacity: 1;
transition: opacity 1s ease;
}
#news {
margin-right: 20px;
margin-top: 25px;
}
Try using the console and manually initialize masonry:
$('#news').masonry();
If it is not working, masonry might be already initialized and therefore it's not repositioning the elements. In that case you have to remove masonry from the div and reinitialize it:
$('#news').masonry('destroy');
$('#news').masonry();

Categories

Resources