Extend Div smoothly without lagging - javascript

On button click, I am fetching data from database using codeigniter and a div is being appended with the fetched data. Problem is that while the data is of high volume, it takes time and the webpage is lagging. What should I do to resolve this issue?
My code is given below.
$("#get_spare_list").click(function() {
$("body").css("cursor", "progress");
var ht = "";
$.ajax({
url: "<?php echo base_url('Spare/get_all_spare_json'); ?>",
type: 'POST',
dataType: 'json',
data: {"param1": 'value1'},
})
.done(function(data) {
var no = 1;
var ht = "<table class='table'><thead><tr><th>No</th><th>Name</th><th>Code</th><th>Min qty</th><th>uni</th><th>Group</th><th>Sub Category</th><th>Part Number</th><th>Location</th><th>Image</th><th >Tyre</th><th>Back</th></tr></thead>";
$.each(data, function(key, val) {
ht +="<tr>"+"<td>"+no+"</td>"+"<td>"+val.name+"</td>"+"<td>"+val.code+"</td>"+"<td>"+val.min_qty+"</td>"+"<td>"+val.unit+"</td>"+"<td>"+val.group+"</td><td>"+val.sub_category+"</td><td>"+val.part_number+"</td><td>"+val.location+"</td>";
if (val.image) {
ht += "<td><a target='_blank' href='"+"<?php echo base_url('../uploads/'); ?>/"+val.image+"'><button class='fa fa-picture-o'></button></a></td>";
}else{
ht += "<td></td>";
}
ht +="<td>"+val.tyre+"</td>";
ht += "<td>";
if (val.reusable == 1) {
ht +="yes";
}else{
ht+="no";
};
ht += "</td>";
ht += "<td><button class='btn edit btn-info btn-xs' data-toggle='modal' data-target='#editModel' data-id='"+val.id+"' data-name='"+val.name+"' data-code='"+val.code+"' data-min_qty='"+val.min_qty+"' data-unit='"+val.unit+"' data-group='"+val.group+"' data-sub_category='"+val.sub_category+"' data-part_number='"+val.part_number+"' data-location='"+val.location+"' data-tyre_number='"+val.tyre+"' data-back='"+val.reusable+"'><span class='fa fa-edit'></span></button></td>";
ht += "</tr>";
no++;
});
$("#js_res").append(ht);
$("body").css("cursor", "default");
})
.fail(function() {
alert("error");
$("body").css("cursor", "default");
});
});
jQuery should append data to the div smoothly without lagging and hanging of web page.

When the browser receives a response, the callback function passed to .done() is added to JavaScript's event loop queue.
While the data is being processed, it blocks JavaScript's event loop to process further tasks. Even the stuff like handling mouse input is blocked meanwhile. If the data being processed is too big, this becomes more observable to the end user.
You can divide the data retrieved into chunks and push them to the event loop separately by calling setTimeout() on them. Source: Cooperation part of You Don't Know JS: Async & Performance
Here is how it can work for your code below, the callback function passed to .done() and a helper function:
function(data) {
var ht = "<table class='table'><thead><tr><th>No</th><th>Name</th><th>Code</th><th>Min qty</th><th>uni</th><th>Group</th><th>Sub Category</th><th>Part Number</th><th>Location</th><th>Image</th><th >Tyre</th><th>Back</th></tr></thead>";
$("#js_res").append(ht);
processData(data, 1);
$("body").css("cursor", "default");
}
function processData(data, no) {
var chunk = data.splice(0, 100);
var ht = "";
$.each(chunk, function(key, val) {
ht +="<tr>"+"<td>"+no+"</td>"+"<td>"+val.name+"</td>"+"<td>"+val.code+"</td>"+"<td>"+val.min_qty+"</td>"+"<td>"+val.unit+"</td>"+"<td>"+val.group+"</td><td>"+val.sub_category+"</td><td>"+val.part_number+"</td><td>"+val.location+"</td>";
if (val.image) {
ht += "<td><a target='_blank' href='"+"<?php echo base_url('../uploads/'); ?>/"+val.image+"'><button class='fa fa-picture-o'></button></a></td>";
}else{
ht += "<td></td>";
}
ht +="<td>"+val.tyre+"</td>";
ht += "<td>";
if (val.reusable == 1) {
ht +="yes";
}else{
ht+="no";
};
ht += "</td>";
ht += "<td><button class='btn edit btn-info btn-xs' data-toggle='modal' data-target='#editModel' data-id='"+val.id+"' data-name='"+val.name+"' data-code='"+val.code+"' data-min_qty='"+val.min_qty+"' data-unit='"+val.unit+"' data-group='"+val.group+"' data-sub_category='"+val.sub_category+"' data-part_number='"+val.part_number+"' data-location='"+val.location+"' data-tyre_number='"+val.tyre+"' data-back='"+val.reusable+"'><span class='fa fa-edit'></span></button></td>";
ht += "</tr>";
no++;
});
$("#js_res").append(ht);
if (data.length > 0) {
setTimeout(function(){
processData(data, no);
}, 0);
}
}

Another solution would be to use a web worker for handling the creation of these table rows.
A web worker can't edit the DOM but you can pass the data to the web worker. The worker can then create the html string and pass it back to the main JS thread which can then append it.
var myWorker = new Worker('create-table.js');
// after successful ajax call, hand data over to worker
myWorker.postMessage(data);
console.log('Message posted to worker');
inside the create-table.js we can then specify our worker:
onmessage = function(e) {
console.log('Message received from main script');
/*
This is just an example from mdn documentation
Obviously you should recreate your logic for creating your <tr> here
*/
var workerResult = 'Result: ' + (e.data[0]);
console.log('Posting message back to main script');
postMessage(workerResult);
}
In the main js file you can then react to the result of the worker like this:
myWorker.onmessage = function(e) {
$("#js_res").append(e.data)
console.log('Message received from worker');
}

Related

put html value into onClick()

var content;
function listReply2() {
$.ajax({
type: "get",
contentType: "application/json",
url: "${contextPath}/comment/listJson.do?bno=${article.articleNO}",
success: function(result) {
var output = "<table>";
for (let i in result) {
output += "<tr>";
output += "<td>" + result[i].writer;
output += "(" + changeDate(result[i].regdate) + ")</td>";
output += "<td >" + result[i].content + "</td>";
if (member_id != null) {
output += "<td><input type='button' id ='rno' value='mod' onclick='commentMod(result[i].content)'/>";
output += "<input type='button' value='delete' onclick=''/></td>";
}
output += "</tr>";
}
output += "</table>";
$("#comment").html(output);
}
});
I want to put HTML value result[i].content into onClick function so that I can move the value when I press the mod button.
How can I do this?
The problem is that functions generated by the HTML parser for onEventName attributes are not created in function scope. As a result,
onclick='commentMod(result[i].content)
will try to find result and i in global scope rather than in the function scope of the success handler. A solution that involves generating table elements using document.createElement calls and adding event listeners in JavaScript could be devised but lacks the simplicity of HTML generation.
One way of generating the handlers in HTML could be to insert the value of result[i].content into the onclick attribute value after escaping it so as not to interfere with HTML parsing and then unescape the string before calling commentMod.
Note the snippet example simply uses escape and unescape since the string being encoded is not part of a URL.
"use strict";
let result = [{content: "I'm < than a teapot & > than a coffee \"jar\""}];
let i = 0;
let html = `<span onclick='alert(unescape("${escape(result[i].content)}"))'>Click Me</span>`;
document.body.innerHTML = html;
console.log( html);
Hence try replacing
output += "<td><input type='button' id ='rno' value='mod' onclick='commentMod(result[i].content)'/>";
with
output += `<td><input type='button' id ='rno' value='mod'
onclick='commentMod(unescape("${escape(result[i].content)}"))'/>`;

Fix Youtube api data pagination v3

I got a so far as good working youtube api data v3 search script but i was so in trouble with this script since days i think im blind it works and paginates everytime 2 entries. But there must be a failure in the js or html code should be easy but i cant figure out please help me. Demo Link is aviable under
Artist search Battle Rap Net Youtube Search
This is the Code so far i used please take a look at the demo link to understand the problem.
The Js Code:
var nextPageToken, prevPageToken;
var firstPage=true;
$(document).ready(function()
{
$('#searchbutton').click(function()
{
// Called automatically when JavaScript client library is loaded.
// alert('i am clicked');
gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
// Called automatically when YouTube API interface is loaded .
// Called automatically with the response of the YouTube API request.
// $('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page</button></div>");
// $('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page"+nextPageToken+"</button></div>");
});
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"prevPageButton\">Prev Page "+prevPageToken+"</button></div>");
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page "+nextPageToken+"</button></div>");
$('#nextPageButton').click(function()
{
// alert('i am clicked');
console.log(nextPageToken);
searchYouTubeApi(nextPageToken);
});
$('#prevPageButton').click(function()
{
// alert('i am clicked');
console.log(prevPageToken);
searchYouTubeApi(prevPageToken);
});
});
function onYouTubeApiLoad()
{
// See to get a key for your own applications.
gapi.client.setApiKey('MYAPICODE');
searchYouTubeApi();
}
function searchYouTubeApi(PageToken)
{
var searchText= $('#searchtext').val();
//$('#response').append("<div id=\"searching\"><b>Searching for "+searchText+"</b></div>");
$('#response').replaceWith("<div id=\"searching\"><b>Searching for "+searchText+"</b></div>");
// Use the JavaScript client library to create a search.list() API call to Youtube's "Search" resource
var request = gapi.client.youtube.search.list(
{
part: 'snippet',
q:searchText,
maxResults:2,
pageToken:PageToken
});
// Send the request to the API server,
// and invoke onSearchRepsonse() with the response.
request.execute(onSearchResponse);
// $('#response').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page return from request execute method is: "+nextPageToken+"</button></div>");
}
function onSearchResponse(response)
{
var responseString = JSON.stringify(response, '', 2);
var resultCount = response.pageInfo.totalResults;
nextPageToken=response.nextPageToken;
prevPageToken=response.prevPageToken;
// document.getElementById('response').innerHTML += responseString;
//$('#response').append("<div id=count><b>Found "+resultCount+" Results.</b></div>");
$('#count').replaceWith("<div id=count><b>Found "+resultCount+" Results.</b></div>");
//$('#searching').append("<div id=length><b>Length "+response.items.length+" </b></div>");
for (var i=0; i<response.items.length;i++)
{
//store each JSON value in a variable
var publishedAt=response.items[i].snippet.publishedAt;
var channelId=response.items[i].snippet.channelId;
var title=response.items[i].snippet.title;
var description=response.items[i].snippet.description;
var thumbnails_default=response.items[i].snippet.thumbnails.default.url;
var thumbnails_medium=response.items[i].snippet.thumbnails.medium.url;
var thumbnails_high=response.items[i].snippet.thumbnails.high.url;
var channelTitle=response.items[i].snippet.channelTitle;
var liveBroadcastContent=response.items[i].snippet.liveBroadcastContent;
var videoID=response.items[i].id.videoId;
//var firstPage=true;
// console.log(thumbnails_default);
//A HTTP call to this URL with videoID will give all XML info of that video:
//http://gdata.youtube.com/feeds/api/videos?q=videoID
// console.log(videoID);
//replace the first search button with a 'more' button
//$('button').replaceWith("<button type='button' id=More"+i+">More...</button>");
if(firstPage===true)
{
//print the stored variables in a div element
$('#snipp').append("<div id=T><b>Title:</b> "+title+"</div><div id=C><b>Channel ID: </b>"+channelId+"</div><div id=D><b>Description </b>"+description+"</div><div id=P><b>Published on: </b>"+publishedAt+"</div><div id=CT><b>Channel Title: </b>"+channelTitle+"</div><a id=linktoVid href='http://www.youtube.com/watch?v="+videoID+"'><img id=imgTD src=\""+thumbnails_default+"\"/></a><br/><br/><a id=linktoVid1 href='http://www.youtube.com/watch?v="+videoID+"'><video id=vidTD width=\"320\" height=\"240\" controls poster="+thumbnails_default+"><source src='http://www.youtube.com/watch?v="+videoID+">Your browser does not support the video tag.</video></a><br/><br/>");
}
else
{
$('#T').replaceWith("<div id=T><b>Title:</b> "+title+"</div>");
$('#C').replaceWith("<div id=C><b>Channel ID: </b>"+channelId+"</div>");
$('#D').replaceWith("<div id=D><b>Description </b>"+description+"</div>");
$('#P').replaceWith("<div id=P><b>Published on: </b>"+publishedAt+"</div>");
$('#CT').replaceWith("<div id=CT><b>Channel Title: </b>"+channelTitle+"</div>");
$('#linktoVid').replaceWith("<a id=linktoVid href='http://www.youtube.com/watch v="+videoID+"'><img id=imgTD src=\""+thumbnails_default+"\"/></a><br/><br/><a id=linktoVid1 href='http://www.youtube.com/watch?v="+videoID+"'><video id=vidTD width=\"320\" height=\"240\" controls poster="+thumbnails_default+"><source src='http://www.youtube.com/watch?v="+videoID+">Your browser does not support the video tag.</video></a><br/><br/>");
}
// $('#snipp').append("<div id=C"+i+">Channle ID: "+channelId+"</div><br/>");
//link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=76TlUlPZQfQ&feature=youtube_gdata'/>
}
// $('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\" onclick=\"alert('Hello world!')\">Next Page "+nextPageToken+"</button></div>");
// return nextPageToken;
firstPage=false;
}
The HTML:
<body>
<div id="search">
<input type="text" value="eureka" id="searchtext"><button type="button" id="searchbutton">Find</button>
</div>
<button type="button">Search Me...</button>
<pre id="response">
</pre>
<pre id="count"></pre>
<pre class="vID"></pre>
<div id="snipp">
<div id=T0
</div>
<br/><br/><br/>
</body>
After create a jsfiddle with your code, I could check the pagination is working correctly.
The problem you're facing lies in your HTML code (most specific: in how you're building your HTML code).
My humble advice is that "instead of using append", re-creates the HTML that renders the current page.
Also, just after all controls loaded in the screen, the "prevPageButton" and "nextPageButton" buttons shows undefined.
For this situation, change these lines:
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"prevPageButton\">Prev Page " + prevPageToken + "</button></div>");
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page " + nextPageToken + "</button></div>");
For this:
if (prevPageToken == undefined) {
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"prevPageButton\">Prev Page</button></div>");
} else {
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"prevPageButton\">Prev Page " + prevPageToken + "</button></div>");
}
if (nextPageToken == undefined) {
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page</button></div>");
} else {
$('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\">Next Page " + nextPageToken + "</button></div>");
}
After a few modifications, you can check here the updated and working jsfiddle.
The tl;dr version is as follows:
Logic for build the HTML code was replaced for set a variable that (in the for-loop) builds the HTML code.
At the end of the loop, the HTML is added directly to the div container called "snipp".
Removed other HTML unneccesary code.
This is the modified code:
HTML:
<div id="search">
<input type="text" value="eureka" id="searchtext"><button type="button" id="searchbutton">Find</button>
</div>
<button type="button">Search Me...</button>
<pre id="response">
</pre>
<pre id="count"></pre>
<pre class="vID"></pre>
<div id="snipp"></div>
JS:
function onSearchResponse(response) {
var responseString = JSON.stringify(response, '', 2);
var resultCount = response.pageInfo.totalResults;
nextPageToken = response.nextPageToken;
prevPageToken = response.prevPageToken;
$('#count').replaceWith("<div id=count><b>Found " + resultCount + " Results.</b></div>");
// This variable will save the HTML code in construction.
var HTML_CONTENT = "";
for (var i = 0; i < response.items.length; i++) {
//store each JSON value in a variable
var publishedAt = response.items[i].snippet.publishedAt;
var channelId = response.items[i].snippet.channelId;
var title = response.items[i].snippet.title;
var description = response.items[i].snippet.description;
var thumbnails_default = response.items[i].snippet.thumbnails.default.url;
var thumbnails_medium = response.items[i].snippet.thumbnails.medium.url;
var thumbnails_high = response.items[i].snippet.thumbnails.high.url;
var channelTitle = response.items[i].snippet.channelTitle;
var liveBroadcastContent = response.items[i].snippet.liveBroadcastContent;
var videoID = response.items[i].id.videoId;
// Buld the HTML to render at the current page.
HTML_CONTENT += "<div id='video_item'> " +
" <div id=T><b>Title:</b>" + title + "</div> " +
" <div id=C><b>Channel ID: </b>" + channelId + "</div> " +
" <div id=D><b>Description </b>" + description + "</div> " +
" <div id=P><b>Published on: </b>" + publishedAt + "</div> " +
" <div id=CT><b>Channel Title: </b>" + channelTitle + "</div> " +
" <a id='linktoVid' href='http://www.youtube.com/watch?v=" + videoID + "'><img id='imgTD' src='" + thumbnails_default + "' /></a><br/><br/><a id='linktoVid1' href='http://www.youtube.com/watch?v=" + videoID + "'><video id='vidTD' width=\"320\" height=\"240\" controls poster='" + thumbnails_default + "'><source src='http://www.youtube.com/watch?v=" + videoID + "'>Your browser does not support the video tag.</video></a><br/><br/> " +
"</div>";
}
// Post all HTML generated code (built in the previous for-loop).
document.getElementById('snipp').innerHTML = HTML_CONTENT;
// $('#search').append("<div id=\"page\"><button type=\"button\" id=\"nextPageButton\" onclick=\"alert('Hello world!')\">Next Page "+nextPageToken+"</button></div>");
// return nextPageToken;
firstPage = false;
}

I'm having issues with an API

I'm having issues with getting this API to work.
I have used the same code with Google Finance API and that works perfectly. The issue is that I can only get a small amount of stocks out, and in the long run, I need to run 12000 stocks through (if possible).
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
var temp = [];
$(document).ready(function(){
stockInformation();
setInterval(stockInformation, 5000);
});
function stockInformation()
{
$.ajax({
url:"https://api.website.com/public/user/token/stock/SDRL/quote",
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"quote"
});
var i = 0; var j = 0;var status = "";
quote = function(data){
var output = "<table>"
$.each(data, function(key, value){
if (value.l_cur > temp[j])
status = "<td style=color:green>Up</td>";
else if (value.l_cur < temp[j])
status = "<td style=color:red>Down</td>";
else
status = "<td>Same</td>";
j++;
output += "<tr><td>" + value.t + "</td><td>" + value.l_cur + "</td>" + status + "</tr>";
temp[i] = value.l_cur;i++;
})
output += "</table>";
$("#result").html(output);
}
}
</script>
<div id="result"></div>
This is what the API returns (not with the code above):
{"timestamp":"1503691321","datetime":"2017-08-25 16:02:01 (UTC)","price":"6.17","price change":"0.12","price pct change":"1.98","open":"6.09","volumn":"1852887","low":"6.00","high":"6.22","currency":"USD"}
Many of googles api's limit the number of requests you can make in a given amount of time. Sometimes even as low as 50 per month depending on the api and the type of request. Its doesn't look like there is anything wrong with the way you are using the api in your code.
You could get around that though potentially by paginating. Start with like 30 at a time then when your user clicks a next button or scrolls to the end of the page then go get the next 30.

Avoid duplicated function call in jquery?

I have build a function getuser() in which I recieve json data from php into javascript. I call this function when document gets ready. My problem is that I am also using jquery post for live updation of that record and for that reason I have to call that function getuser() again due to this it shows duplicate result. First when document gets ready socend on jquery post function.
HTML
<!--It has onclick event-->
<button type="submit" class="btn btn-primary modify" onclick="update_user()">UPDATE</button>
JQUERY
//This is function which gets json array from php
function getuser() {
$.get("getuser.php", function (data) {
var data = JSON.parse(data);
for (var i = 0, len = data.length; i < len; ++i) {
var student = data[i];
var slash = " / ";
$("#output").append("<tr><td>" + student.name + "</td><td>" + student.gender + "</td><td>" + student.age + "</td>" +
"<td>" + student.city + "</td><td><a href='#' style='text-decoration: none' class='update' id='" + student.id + "' onclick='reply_click(this.id)'>Update</a>" + slash + "<a style='text-decoration: none' href='#'>Delete</a></td></tr>");
}
});
}
//when document gets ready it will show the record
if($(document).ready()) {
// getuser();
getuser();
}
//This is jquery post. When I click button (in html section) it will get form values and sent to php page
//in return it will call getuser() function again which results of duplicate display of record
$(document).ready(function(){
$('.modify').click(function() {
var gender = '';
if($('.male').is(':checked')){
gender='Male';
}else{
gender='Female';
}
$.post("update.php",
{name: $('.name').val(),gender:gender,city:$('.city').val(),age:$('.age').val(),id:$('.id').val()},
function (data) {
//here is the function call again
getuser();
}
);
});
});
Kindy tell me that is there any way I avoid second call in post function and the record gets update without function call again.I need to avoid duplicate result. Thanks in advance!
First off, you need to read the docs on jquery document ready, and learn the difference between a function reference and actually calling a function. document.ready expects you to pass in a function definition to be called when the page is ready. It doesn't actively tell you if the page is ready, the first way you're calling it. The second way you're calling it is actually correct.
Second, replace $("#output").append with $("#output").html, which will update/replace the contents of that element every time, instead of just adding more and more.
Your if test will always return true because document.ready returns the JQuery object. So, you are always causing the call to getuser() to happen.
You can see the return value from document.ready() here:
console.log($(document).ready());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is an incorrect usage of document.ready(). You don't need to write a test for document.ready, just write a callback function for that event and let the browser do it correctly for you.
Read the docs on document.ready()
Solution:
This:
//when document gets ready it will show the record
if($(document).ready()) {
// getuser();
getuser();
}
Should be this:
//when document gets ready it will show the record
$( document ).ready(getuser);
Or even:
$(getuser);
As for you getting the results a second time, just overwrite the old results instead of appending them.
This: $("#output").append(...
Should be: $("#output").html(...
All of you thanks for your suggestions. I have found the solution here by just adding $("#tbody").html(''); in getuser() before loop. Here is the code which works fine for me
function getuser() {
$.get("getuser.php", function (data) {
var data = JSON.parse(data);
$("#tbody").html('');//newly added
for (var i = 0, len = data.length; i < len; ++i) {
var student = data[i];
var slash = " / ";
$("#output").append("<tr><td>" + student.name + "</td><td>" + student.gender + "</td><td>" + student.age + "</td>" +
"<td>" + student.city + "</td><td><a href='#' style='text-decoration: none' class='update' id='" + student.id + "' onclick='reply_click(this.id)'>Update</a>" + slash + "<a style='text-decoration: none' href='#'>Delete</a></td></tr>");
}
});
}
All of you thanks again!

querying parse in javascript

this is a complete noob question, but I am brand new to javascript and web development, so please bear with me :)
I have objects in a Parse class that I want to list on a website. I want to iterate through these objects and list them (I am in an html file).
Here is my code:
<script>
Parse.initialize("XXXXXXX");
var Post = Parse.Object.extend("Post");
function getPosts() {
var query = new Parse.Query(Post);
query.find({
success: function(results){
var output = "";
for (var i in results) {
var title = results[i].get("activityTitle");
console.log("ok now");
output += "<div class=\"row container-post\">
<div class=\"col-md-4 col-sm-6\">
<div class=\"post-container\">
<div class=\"post-content no-padding\">
<img src=\"assets/image-portfolio-02.jpg\" alt=\"danish personal blog template\"></div>
<div class=\"post-content\">";
output += title;
output += "</div></div></div></div>";
}
$("#list-posts").html(output);
}, error: function(error) {
console.log("Query Error:"+error.message);
}
});
}
getPosts();
</script>
Once you have your results, literally start building your content. Say we have this on the HTML side:
<div class="results target"></div>
then we can do this on the JS side:
<script type="text/javascript">
Parse.initialize(...);
new Parse.Query(Post).find({
success: function(results) {
buildResultHTML(results);
}
});
function buildResultHTML(data) {
var container = document.querySelector("div.results.target");
data.forEach(function(entry) {
container.appendChild(buildHTMLRow(entry));
});
}
function buildHTMLRow(data) {
// there are a million ways to do this. Usually, you use a templating
// library to make live easier. Let's roll one:
var outer = document.createElement("div");
var img = document.createElement("img");
var url = data.imagelinkwhatever;
// safety first: is this a real http:// or https:// link? If not, DON'T USE IT
img.src = url.indexOf("http") === 0 ? url : "";
var p = document.createElement("p");
p.textContent = data.textwhatever;
// note: also NEVER use .innerHTML if your data can come from "not you".
// It's an instant XSS exploit waiting to happen. See below.
outer.appendChild(img);
outer.appendChild(p);
return outer;
}
</script>
But, as the code says: you typically want to use a templating library instead, so you don't have to worry about things like messy JS creation of DOM elements, user content security, etc.
And security is important: if that Parse result can give you something like this:
{
imgurlwhatever: "javascript:alert('lol')",
textwhatever: "<script>alert('lol');</script>"
}
then your page, if it uses blind img.src=... and p.innerHTML=..., will happily execute that JS. That sounds silly, but alert('lol') is a placeholder: if we can get that to run, we can also get things like "call another site's url using an XHR, with the content of document.cookies as url query parameters" and suddenly shit gets real(tm).
ok, I finally figured it out. Here is the code:
<script>
Parse.initialize("XXXXXXXXXXXXXX");
var Post = Parse.Object.extend("Post");
function getPosts() {
var query = new Parse.Query(Post);
query.find({
success: function(results){
var output = "";
for (var i in results) {
var title = results[i].get("activityTitle");
console.log("ok now");
var img = ""
var file = results[i].get("Bild");
var url = file.url();
img = "<img src='"+url+"'>";
output += "<div class=\"container\">";
output += "<div class=\"row\">";
output += "<div class=\"col-md-4\">";
output += "<div class=\"post-container\">";
output += "<div class=\"post-content no-padding\">";
output += img;
output += "</div>";
output += "<div class=\"post-content\">";
output += title;
output += "</div";
output += "</div>";
output += "</div>";
output += "</div>";
output += "</div>";
}
$("#list-posts").html(output);
}, error: function(error) {
console.log("Query Error:"+error.message);
}
});
}
getPosts();
</script>
And just above the javascript code, in the HTML, I just put:
<p id="list-posts">
</p>
This gets the objects from parse, and lists them out for me in the format I wanted. thanks for the suggestions though. For anyone else who may need help in the future with something like this, this video (and others by the author) really helped me: https://www.youtube.com/watch?v=_fxh825Bnpg&index=4&list=PLoN_ejT35AEhbFswEKW36LxzyXJs7xCWS

Categories