Limit number of Dynamic list Items in a Function - javascript

I would like to achieve 2 things with this Code I have been working on so not sure if to separate the Questions:
JS:
function listPosts(data) {
postlimit =
var output='<ul data-role="listview" data-filter="true">';
$.each(data.posts,function(key,val) {
output += '<li>';
output += '<a href="#devotionpost" onclick="showPost(' + val.id + ')">';
output += '<h3>' + val.title + '</h3>';
output += '<p>' + excerpt + '</p>';
output += '</a>';
output += '</li>';
}); // go through each post
output+='</ul>';
$('#postlist').html(output);
} // lists all the posts
Questions:
1: I would like to limit the number of Dynamic List Posts returned to 8
2: While I limit the displayed items, I want to add a 'More...' text at the bottom so another set of 8 items is appended to already displayed list.
I am already trying out some codes but was hoping to get some guidance

function listPosts(data, postlimit) {
var $output = $('<ul class="posts" data-role="listview" data-filter="true">');
$.each(data.posts,function(key, val) {
$("<li>", {id: "post_" + val.id})
.append([
$("<h3>", {text: val.title}),
$("<p>", {text: val.excerpt})
])
.appendTo($output);
return (postlimit-- > 1);
});
$('#postlist').empty().append($output);
}
// exemplary delegated event handler
$(document).on("click", "ul.posts h3", function () {
$(this).show();
});
later ...
listPosts(data, 8);
Notes:
from $.each() you can return true or false. If you return false, the loop stops.
Try not to build HTML from concatenated strings. This is prone to XSS vulnerabilities that are easy to avoid. jQuery gives you the tools to build HTML safely.
Generally, for the same reason, try to avoid working with .html(), especially if you already have DOM elements to work with.
Don't use inline event handlers like onclick. At all. Ever.

I am answering you on basis of pure logic and implementation of logic. there could be API stuff for it , but I don't really know. Secondly; It would be a good solution to find some jQuery plugin if you don't have any problems with using jQuery.
call the function onMoreClick() upon clicking the More... html item
var end = 8;
var start = 1;
function onMoreClick()
{
start = end
end = end+8;
listPosts(data)
}
function listPosts(data) {
postlimit =
var output='<ul data-role="listview" data-filter="true">';
var i = start;
$.each(data.posts,function(key,val) {
if(i<end && i >=start){
output += '<li>';
output += '<a href="#devotionpost" onclick="showPost(' + val.id + ')">';
output += '<h3>' + val.title + '</h3>';
output += '<p>' + excerpt + '</p>';
output += '</a>';
output += '</li>';
i++;
}
}); // go through each post
output+='</ul>';
$('#postlist').html(output);
} // lists all the posts

Related

JSON data is undefined but appears in console log

I am accessing the following JSON data at:
http://veratech.co.nz/blog/?json=1
When I try to access the "url" property that sits within an array on line 4 of the code below, I get an undefined error. Even though it will appear in console.log (line 13) with console.log(val.attachments[0].url);.
Code below:
$.each(data.posts, function(index, val){
output += '<li>';
output += '<a href="#blogpost" onclick = showPost(' + val.id + ')">';
output += '<img src="' + val.attachments[0].url + '" alt="">';
output += '<h3>' + val.title + '</h3>';
//Here we shorten the paragraph to 60 characters.
var str = val.excerpt;
var paraInfo = str.slice(0, 60);
output += '<p>' + paraInfo + '</p>';
//Closing off the the closing html tags
output += '</a>';
output += '</li>';
console.log(val.attachments[0].url);
});//Go through each post
Advice would be greatly appreciated
I think there's something else wrong.
I downloaded the json manually, and wrote this code:
HTML:
Urls:
<ul id="foo">
</ul>
JavaScript:
function extractUrls(data) {
var $foo = $('#foo');
$.each(data.posts, function (i, p) {
$foo.append($('<li></li>').text(p.attachments[0].url));
});
}
var jsonData = { /* code omitted for brevity */ };
extractUrls(jsonData);
My output was:
Urls:
<ul id="foo">
<li>http://veratech.co.nz/blog/wp-content/uploads/2014/03/martial.jpg</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/12/grave.jpg</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/12/GTA5.jpg</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/10/miyagi.jpg</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/08/htc-box.png</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/08/scaffold1.jpg</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/07/barriera.png</li>
<li>http://veratech.co.nz/blog/wp-content/uploads/2013/06/tv.jpg</li>
</ul>
Note: You should be able to replace the var jsonData = line with:
$.get('http://veratech.co.nz/blog/', { json: 1 }, extractUrls, 'json');
Anyway; can't see what's wrong with your code? Are you sure this is the issue?
PS: I even added the following inside the $.each loop:
if (!p.attachments[0].url) {
alert(p.id + ' has undefined url!');
}
And did not see any alert...
See code running in a jsFiddle here

in wordpress request.open('GET', 'data.json',true); not working. why?

Hi i am making a WordPress plugin that can bring the names of products from json file if someone writes products name into the search bar. But i think data.json is not getting by Ajax in WordPress. its path defining syntax error i guess.
$.getJSON('data.json', function(data)
following is complete scripting code and it was working fine in PHP website but not in WordPress.:
`jQuery('#search').keyup(function(){
var searchField = jQuery('#search').val();
var myExp = RegExp(searchField,"i");
jQuery.getJSON('data.json', function(data){
var output= '<ul class="SearchResult">';
jQuery.each(data, function(key, val){
if((val.name.search(myExp) != -1) || (val.category.search(myExp) != -1)){
output += '<li>';
output += '<h2>' + val.name + '</h2>';
output += '<img src="images/'+val.image+'.jpg" alt="sorry for image"/>';
output += '<p>' + val.category + '</p>';
output += '</li>';
}
});
output += '</ul>';
$('#update').html(output);
});
});
`
1: the file "data.json" should be in the root of your folder along with the wp-config.php file
2: check your .htaccess if you can access the "data.json" file
3: in wordpress the jquery version, you only can use jQuery instead of $ , so i can see you are using $("#update") , change it to jQuery("#update")
jQuery('#update').html(output);

'no image' icon while outputting AJAX-delivered content [duplicate]

This question already has answers here:
How to show Page Loading div until the page has finished loading?
(13 answers)
Closed 8 years ago.
I use AJAX requests to retrieve data from mySQL (link), after that I build a sequence of post. Every post has a feature image. So while in process of outputting the posts, the visitor sees 'no image' sign:
.
This lasts for a bit of second, but looks bad.
How can I prevent this sign from showing, or subtitute with a loading spin?
jQuery part for outputting the results
function postsBuilder(posts){
var contents ='';
$.each(posts, function(k, field){
if(field.link[field.link.length-1] == '/') {field.link = field.link.slice(0, field.link.length-1)};
contents += '<div class="post-container">';
//here I output the feature image
contents += "<div class='col_1'><div class='post_image'><img src='/images/icons/id_" + field.id + ".png'></div></div>";
contents += "<div class='col_2'><div class='post_name'><a class='post_name_link' target='blank' href=http://" + field.link + ">" + field.name + "</a></div>";
contents += "<div class='post_link'>" + field.link + "</div>";
contents += "<div class='post_content'>Content: " + field.content + "</div>";
if ( field.video.indexOf('you') >-1 ) {contents += "<div class='post_video'><a data-toggle='lightbox' href=" + field.video + ">Video</a></div>";}
contents += "</div></div><br />";
});
return contents;
}
One of examples when the function is called
$.ajax({cache:false,
url:str,
beforeSend: function() { $('#loadingDiv').show(); },
complete: function() { $('#loadingDiv').hide(); },
dataType :'json'})
.done(function(result){
var i, j, m=0;
var div_content="";
div_content += "<div><b>Category: ".concat(result[0].category).concat("</b></div>");
posts_array = [];
for (i=0,j=result.length; i<j; i+=size) { // slice whole JSON result into portions of at maximum 'size' posts in each
posts_array.push(result.slice(i, i+size));
m++;
}
div_content += postsBuilder(posts_array[0]);
...
$("#content").html(div_content);
});
Use the error event for images:
$(document).on('error', 'img', function () {
$(this).hide();
// or $(this).css({visibility:"hidden"});
});
Check out How to silently hide "Image not found" icon when src source image is not found

Javascript Script parsing values onto JSP page

So I have a Javascript script (don't judge it, i've barely used the technology before and this is in need of a tidy!)
$(document).ready(function()
{
retrieveComments();
});
function retriveComments(){
videoID = readCookie("currentVideoID");
$.get("https://gdata.youtube.com/feeds/api/videos/" +videoID+ "/comments", function(d){
$(d).find("entry").each(function(){
var $entry = $(this);
var author = $entry.attr("author");
var comment = $entry.find("content").text();
var html = '<div class="videoComments">';
html += '<p class="author">" + author + "</p>';
html += '<p class="comment"> " + comment + "</p>';
html += '</div>';
};
$('#comments').append(html);
});
And I wish to retrieve the values author and content (comment), and display it on the page. Examples I have found over the course of the day have shown 2 seperate files one with the script in and one a .jsp with the page content in, then class tags (?) corresponding to the last line (in my case #comments).
Seeing as I don't need any other content than just the data I've retrieved and the content I've built in the script, I have this:
<div id="comments"> </div>
but it doesn't display, and I can't see what I have different hin my case.
My whole page looks like:
<script type="text/javascript">
var videoID = readCookie("currentVideoID");
$(document).ready(function()
{
retrieveComments();
});
function retriveComments(){
videoID = readCookie("currentVideoID");
$.get("https://gdata.youtube.com/feeds/api/videos/" +videoID+ "/comments", function(d){
$(d).find("entry").each(function(){
var $entry = $(this);
var author = $entry.attr("author");
var comment = $entry.find("content").text();
var html = '<div class="videoComments">';
html += '<p class="author">" + author + "</p>';
html += '<p class="comment"> " + comment + "</p>';
html += '</div>';
};
$('#comments').append(html);
});
});
</script>
<h1>TEST</h1>
<div id="comments"> </div>
Any ideas how I can get that HTML to display?
Not sure what the readCookie function does (I assume it reads a cookie), but here it is without all the syntax errors and working:
$(document).ready(retriveComments);
function retriveComments() {
$.get("https://gdata.youtube.com/feeds/api/videos/jofNR_WkoCE/comments", function (d) {
$(d).find("entry").each(function (_, entry) {
var author = $(entry).find("author name").text(),
comment = $(entry).find("content").text();
html = '<div class="videoComments">';
html += '<p class="author">' + author + '</p>';
html += '<p class="comment">' + comment + '</p>';
html += '</div>';
$('#comments').append(html);
});
});
}
FIDDLE

Things are happening outside my for loop before its done (javascript)

I'm sure I've seen this before and know the answer to it but after 12 hours... my mind is complete mush.
I have a for loop in which I am trying to concatenate onto a string so that AFTER I can complete the string (thus completing a nice little table) that I had hoped to then insert into my html and show the user.
However, the things at the end of my function (after my for loop) are getting called before the for loop ever does....
function getEntries() {
$('#entryTotalsDiv').html('<img src="images/ajax-loader.gif" /> ... retrieving form totals.');
var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" +
"<tbody>"
//Get rows ONE at a time.
var countNumber = 1;
for (var frm = 0; frm < numberOfForms; frm++) {
$.post('ajax/getEntries.aspx',
{
'formNumber': frm
},
function (data) {
entryTotalsTable += "<tr><td>" + data[0].formName + "</td><td>" + data[0].formHash + "</td><td>" + data[0].formEntryCount + "</td></tr>";
//Now go and update the Form Retrieval div -- add 1 to the frm Number
$('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
countNumber++;
});
}
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
If you notice, I wanted to close up the Table html at the end, but this gets called before my for loop is finished, thus screwing up my string...
?
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
A solution could be to save every response in an array and test in every callback whether the current count is equal to the total count. Something like:
var countNumber = 1,
allData = [];
function runWhenFinished() {
if(countNumber === numberOfForms) {
var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" + "<tbody>";
for(var i = 0, l = allData.length; i < l; i++) {
entryTotalsTable += "<tr><td>" + allData[i].formName + "</td><td>" + allData[i].formHash + "</td><td>" + allData[i].formEntryCount + "</td></tr>";
}
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');
}
}
for(var frm = 0; frm < numberOfForms; frm++) {
(function(frm) {
$.post('ajax/getEntries.aspx',{'formNumber': frm}, function (data) {
allData[frm] = data[0];
countNumber++;
$('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
runWhenFinished();
});
}(frm));
}
I'm sure this can still be improved, but you get the idea.
If you really make 70 requests then you might want to rethink your strategy anyway. 70 simultaneous requests is a lot.
E.g. you could make one request and prove the minimum and maximum number of that should be retrieved / updated / whatever the method is doing.
$.post is asynchronous, meaning that it's firing off all the requests in the loop as fast as it can, and then exiting the loop. It doesn't wait for a response. When the response comes back, your row function is then called... but by then, all the posts have been sent on their way.
See the answers to this question here...
How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
You'll need to change from $.post to $.ajax

Categories

Resources