I'm very new in javascript and I try to find problem for a week.
My example code like below (all are in a html page in head tag)
//example function 1
function randomString(len, charSet) {
charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.substring(randomPoz,randomPoz+1);
}
return randomString;
}
//example function 2
function tests(randomString) {
alert(randomString);
}
//example function 3 pull data from JSON to div id test
$(document).ready(function() {
$.getJSON("http://www.test.com/get_json_data.php?", {
cat_id: "3",
type:'GET',
dataType: 'json',
}, function(data) {
$.each(data.items, function(i, item) {
$('#test').append('<img src="http://www.test.com/images/'+item.image+'"/>');
if (i == 10) return false;
});
});
});
My Problem is I wan to insert var from JSON for example "item.id" in to "onclick" what's I tried to do is below
onclick="tests(randomString(5)+item.id)"
the result I wan to see is alert 5 random chars and include item.id at the end for example
xIyax33 (33 is item.id)
TwQpu34 (34 is item.id)
AERim35 (35 is item.id)
But always show error "item is not defined"
How can I change the code to insert var from JSON ?
You need to add one more parameter in your randomString() function called id which will fetch the item.id. And you need to append it to your randomString.
function randomString(len,id, charSet) {//See second param
charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.substring(randomPoz, randomPoz + 1);
}
return randomString+id; //+id
}
And change your append to
$('#test').append('<img src="http://www.test.com/images/'+item.image+'"/>');
Related
I have a simple script written to hash a cell, however it doesn't work within and array formula, and I am having a hard time figure out how to add that functionality.
function SHA256 (input) {
var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input);
var txtHash = '';
for (i = 0; i < rawHash.length; i++) {
var hashVal = rawHash[i];
if (hashVal < 0) {
hashVal += 256;
}
if (hashVal.toString(16).length == 1) {
txtHash += '0';
}
txtHash += hashVal.toString(16);
}
return txtHash;
}
Within Google Sheets, the above script allows me to hash using SHA526(A2)
I would like to be able to hash an entire column by using SHA256() within an array formula. =ArrayFormula(SHA256(A2:A))
The error I get is
"Exception: The parameters (DigestAlgorithm,number[]) don't match the method signature for Utilities.computeDigest. (line 2)."
Any direction would be greatly appreciated!
Google Apps Script - Custom Functions Documentation
In order to use an array you need to map the input. Using a simple else if you can test if the input is an array or a single value.
function SHA256 (input) {
if(input.map) {
return input.map(SHA256);
} else {
var rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input);
var txtHash = '';
for (i = 0; i < rawHash.length; i++) {
var hashVal = rawHash[i];
if (hashVal < 0) {
hashVal += 256;
}
if (hashVal.toString(16).length == 1) {
txtHash += '0';
}
txtHash += hashVal.toString(16);
}
return txtHash;
}
}
say if I have csv file with :
Heading 1 , Heading 2 , Heading 3
Value 1 , Value2 , Value 3
All I want is to create a map that stores Heading 1 as a key and Heading 2 as value;
like map.set(value1 , value2)
How do I do this while I read the file in javascript ?
function processData(allText) {
var allTextLines = allText.split("\r");
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
console.log(data[0]);
map1.set(data[0] , data[1]);
}
}
so far I tried to do this . But it doesn't work. It doesn't read the file at all. Any help is appreciated.
Thanks
If you have a series of items separated by commas (,), the you can iterate the String and explode or split the items. This can be done with Vanilla JavaScript. The magic part is the for() loop; iterating it by 2 instead of by 1, which is most commonly seen.
$(function() {
var myString = "Header 1,Value 1,Header 2,Value 2,Header 3,Value 3";
var parts = myString.split(",");
var myData = {};
for (var i = 0; i < parts.length; i += 2) {
myData[parts[i]] = parts[i + 1];
}
console.log(myData);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If your file has multiple lines, and the first line is Headers, for example:
Header 1,Header 2,Header 3
Value 1,Value 2,Value 3
Value 4,Value 5,Value 6
You'll have to treat it differently. When it's brought into JS, it will be one big String, and you will have to first split it by End Of Line (EOL). This will create an Array of Strings that must be iterated. You will want to make an Array of Keys and then a Matrix of Values.
Since the file is Local, you will need to first get the File from the User. This is discussed here: How to read data From *.CSV file using javascript? and here: Reading in a local csv file in javascript? You will have to determine the best method for yourself.
One way is to use a File Input. There are drawbacks and caveats due to security and browsers, but it might work.
$(function() {
var fileInput = $("#getFile");
function toObj(keys, vals) {
var obj = {};
for (var i = 0; i < keys.length; i++) {
obj[keys[i]] = vals[i];
}
return obj;
}
function stringToObject(str, header) {
if (header == undefined) {
header = false;
}
var lines = str.split("\n");
var k = [],
m = [];
if (header) {
k = lines.splice(0, 1);
k = k[0].split(",");
}
$.each(lines, function(i, el) {
if (el.length) {
m.push(el.split(","));
}
});
if (k.length) {
var r = [];
$.each(m, function(i, el) {
r.push(toObj(k, el));
});
return r;
} else {
return m;
}
}
function readFile() {
var reader = new FileReader();
reader.onload = function() {
var newData = stringToObject(reader.result, $("#header").prop("checked"));
console.log(newData);
$("#out").html("<pre>" + reader.result + "</pre>");
};
reader.readAsBinaryString(fileInput[0].files[0]);
};
fileInput.change(readFile);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="file input">
<input type="checkbox" id="header" checked="checked"> <label>CSV Header</label><br />
<input type="file" id="getFile" />
</div>
<div id="out"></div>
I try to load contents of the CSV file into the array of JavaScript objects. Unfortunately, structure of data is not flat, so to mitigate that, I use dot-separated property names as column headers in CSV file. Example CSV file looks as follows:
codes.code1,codes.code2,codes.code3,codes.code4,info.description.text,info.description.language
49074202,64,1443,1416,Test description: 49074202 64 1443 1416,EN
81905948,10,9721,5411,Test description: 81905948 10 9721 5411,EN
87262350,86,7050,4775,Test description: 87262350 86 7050 4775,EN
The object structure I would like to end up with looks like
{
codes: {
code1: "49074202",
code2: "64",
code3: "1443",
code4: "1416"
},
info: {
description: {
text: "Test description: 49074202 64 1443 1416",
language: "EN"
}
}
}
Following code can be used to recreate the problem (using CSV file with contents posted above).
<html>
<body>
<form>
<input type="file" id="files" onchange="loadFromFile()" />
<script>
function loadFromFile() {
var selectedFile = document.getElementById('files').files[0];
var reader = new FileReader();
reader.onload = loadRowsFromFile;
reader.readAsText(selectedFile);
};
function loadRowsFromFile(e) {
var rows = e.target.result.split("\n");
if (!rows || rows.length === 0) {
return;
}
var headers = rows[0].split(",");
var loadedData = [];
for (var i = 1; i < rows.length; i++) {
var columns = rows[i].split(",");
var rowData = {};
for (var j = 0; j < headers.length; j++) {
placeElementInHierarchy(rowData, headers[j], columns[j]);
}
loadedData.push(rowData);
}
console.log(loadedData);
}
function placeElementInHierarchy(rowData, propertyPath, value) {
var path = propertyPath.split(".");
var obj = rowData;
for (var i = 0; i < path.length; i++) {
if (i === path.length - 1) {
obj[path[i]] = value;
} else {
if (!obj[path[i]]) {
obj[path[i]] = {};
}
obj = obj[path[i]];
}
}
}
</script>
</form>
</body>
</html>
File parsing works properly, data is loaded correctly into the structure. However, for some reason the last processed property name is quoted. Structure of all rows I obtain looks like that:
{
codes: {
code1: "49074202",
code2: "64",
code3: "1443",
code4: "1416"
},
info: {
description:{
text: "Test description: 49074202 64 1443 1416",
"language": "EN"
}
}
}
The only lead I have right now is that if I remove the 'language' column from CSV file, then 'text' is being quoted instead - so the last processed property is for some reason quoted. Thanks in advance!
EDIT: Fixed mistakes in the expected structure.
EDIT2: What is interesting, following code (skipping file upload part), doesn't show such symptoms
<html>
<body>
<form>
<script>
(function() {
var csvData = 'codes.code1,codes.code2,codes.code3,codes.code4,info.description.text,info.description.language\n' +
'49074202,64,1443,1416,Test description: 49074202 64 1443 1416,EN\n' +
'81905948,10,9721,5411,Test description: 81905948 10 9721 5411,EN\n' +
'87262350,86,7050,4775,Test description: 87262350 86 7050 4775,EN';
loadRowsFromFile(csvData);
})();
function loadRowsFromFile(csvData) {
var rows = csvData.split("\n");
if (!rows || rows.length === 0) {
return;
}
var headers = rows[0].split(",");
var loadedData = [];
for (var i = 1; i < rows.length; i++) {
var columns = rows[i].split(",");
var rowData = {};
for (var j = 0; j < headers.length; j++) {
placeElementInHierarchy(rowData, headers[j], columns[j]);
}
loadedData.push(rowData);
}
console.log(loadedData);
}
function placeElementInHierarchy(rowData, propertyPath, value) {
var path = propertyPath.split(".");
var obj = rowData;
for (var i = 0; i < path.length; i++) {
if (i === path.length - 1) {
obj[path[i]] = value;
} else {
if (!obj[path[i]]) {
obj[path[i]] = {};
}
obj = obj[path[i]];
}
}
}
</script>
</form>
</body>
</html>
Okay. As you can see in screen above, your problem is generated by Carriage Return character \r on end of every line in the file. You can remove all your empty characters from string using
trim()
or you can use regexp to cut out just this type of characters.
Example is done here:
How to remove all line breaks from a string?
Display only new updates of JSON data, iterated with each value item in its own paragraph tag using jQuery/javascript.
If each item in the array inside the info key already is outputted in its own <p> tag; do not continue the loop but wait until there is a new item.
This is my JSON:
{
"info": [
"Hello world,",
"how are you doin?",
"Its not going to well for me unfortunately."
]
}
With this jQuery script:
function updatelog() {
$.getJSON("/static/_info",
function(data) {
$.each(data, function(key, item) {
var value = "";
var i;
for (i = 0; i < item.length; i++) {
value += item[i];
$("div").add('<p>' + value + '</p>').appendTo(document.body);
}
});
});
}
var interval = window.setInterval(updatelog, 2000);
With this I get all the items but it doesn't stop iterating. I have searched the interwebs so much that my enter key has lost all hope for salvation. I guess this is pretty easy, but I'm a beginner and also not a javascript coder and i'm ready to pull my hair off. Thanks in advance.
You could take text of all p elements and push it to new array and then check if it includes values from your object
var data = JSON.parse('{"info":["Hello world,","how are you doin?","Its not going to well for me unfortunately."]}'),
pText = [];
$('p').each(function() {
pText.push($(this).text());
});
data.info.forEach(function(el) {
if (!pText.includes(el)) {
$('body').append('<p>' + el + '</p>');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hello world,</p>
You can generate a hash from every list-item and use it as id in the div elements. Everytime you retrieve the data you check if the corresponding id exists. If it exists then the item is already present in your page so you don't have to append it again.
function updatelog() {
$.getJSON("/static/_info",
function(data) {
$.each(data, function(key, item) {
var i;
for (i = 0; i < item.length; i++) {
var value = item[i];
var hashCode = value.hashCode();
if(!$("body").find("#" + hashCode).length){
$("div")
.attr("id", hashCode)
.add('<p>' + value + '</p>')
.appendTo(document.body);
}
}
});
});
}
var interval = window.setInterval(updatelog, 2000);
You can use this implementation for the hashCode function.
Generate a Hash from string in Javascript/jQuery
String.prototype.hashCode = function() {
var hash = 0, i, chr, len;
if (this.length === 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
ANSWERED
Thanks to everyone that has replied on this post. Thanks to Kevin (Best Solution for the loop) and thanks to Deepak for the sort functionality.
I am going to try find a pagination solution for this data on the site, but any further help would be appreciated.
Thanks again all!
ORIGINAL QUIESTION
I am hoping that you can help me out. I have a JSON feed (which I have validated and is working perfectly on http://jsonlint.com/). I have set up the page on my side and I can parse one result no problem. Thing is there are many results in the feed and I need the jQuery to return all the results. The example I am showing here has 11 results, but some of the other pages have up to 300 results. So this is a two part question.
My scripting knowledge is being able to change given code, but writing it myself is not possible (I am in the process of teaching myself though)
How do I return all the results?
How do I paginate the results, say 15 per page?
I am using the Cross Domain Ajax plugin by JAMES PADOLSEY to pull the data - is this the right terminology even?
The jQuery code I am using is:
jQuery.noConflict()(function($) {
$(document).ready(function($) {
$.ajax({
type: 'GET',
url: "http://dealer.mustek.co.za/public-content-api.html?content=dealers&province=limpopo",
success: function(response) {
var headline = $(response.responseText).text()
var json_obj = $.parseJSON(headline); //parse JSON
console.log(json_obj);
var output = '';
for (var i = 0; i < json_obj.user_id; i++)
output += "<div class='dealer'>";
output += "<dl>";
output += "<dt>Company Name</dt>"
output += "<dd>" + json_obj[i].company_name + "</dd>"
output += "<dt>Company Description</dt>"
output += "<dd>" + json_obj[i].company_description + "</dd>";
output += "<dt>Email Address</dt>"
output += "<dd>" + json_obj[i].company_email + "</dd>";
output += "<dt>Contact Number</dt>"
output += "<dd>" + json_obj[i].contact_number + "</dd>";
output += "<dt>Website URL</dt>"
output += "<dd>" + json_obj[i].website_url + "</dd>";
output += "<dt>City</dt>"
output += "<dd>" + json_obj[i].city_suburb + "</dd>";
output += "<dt>Physical Address</dt>"
output += "<dd>" + json_obj[i].physical_address + "</dd>";
output += "</dl>"
output += "<p>"
output += "</div>";
$('#dealer_limpopo').html(output);
},
});
});
});
And I am pulling the div into a test html page http://thegearbox.co/thisisatest/.
As you can see there is no problem with feed, all is working perfectly, just need that pesky line to loop through all the data. Currently the
for (var i = 0; i < json_obj.user_id; i++)
is not doing the job.
Any help would be super appreciated!
PS. is there any way to sort the data alphabetically, or am I just being cheeky asking for so much? :)
UPDATE
A HUGE thank you to everyone that has commented so far. I have used #Kevin's solution below to show all the data using
for (var i = 0; i < json_obj.length; i++)
I am using #Deepak's solution to sort the data alphbetically:
json_obj.sort(function compare(a,b) {
if (a.company_name < b.company_name)
return -1;
if (a.company_name > b.company_name)
return 1;
return 0;
});
Can anyone help with the pagination?
The for loop should iterate once for each item in the [] json_obj. In Javascript an array contains an inherit property length. The value of the length property indicates how many elements are contained within the array. Adding this to for loop tells it to iterate once per element in the array.
Change the loop to:
for (var i = 0; i < json_obj.length; i++){
//code omitted
}
$.ajax({
type: "GET", timeout: 60000, cache: false, dataType: "jsonp", url: strURL + "&callback=?",
success: function (response) {
objAttributes = response.Attributes;
var List = "";
if (objAttributes != null) {
var iLoop = 0;
var xLoop = 0;
for (iLoop = 0; iLoop < objAttributes.Product.length; iLoop++) {
if (List.length > 0) List = List + ":";
List = List + objAttributes.Product[iLoop].ID;
List = List + "_" + objAttributes.Product[iLoop].ITEM;
}
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
This code may help you.
You should use jquery's for-each loop.
if your json response object is an array.
$.each( json_obj, function(index, value) {
// process the value
// append value.company_name, value.company_email etc. to output.
});
And, to sort your data on company name.
json_obj.sort(function compare(a,b) {
if (a.company_name < b.company_name)
return -1;
if (a.company_name > b.company_name)
return 1;
return 0;
});
your "json_obj" is an array.
change
for (var i = 0; i < json_obj.user_id; i++)
to
for (var i = 0; i < json_obj.length; i++) {
Since in your case json_obj seems to be a list so,
json_obj.user_id is undefined.
try this if you have single list.
for (var i = 0; i < json_obj[0].user_id; i++)
or else use
$.each(json_obj,function(data,index){
//your html code here
})
Hope it helps...
Here is a way to sort your data :
json_obj.sort(function (a, b) {
if (a.company_name > b.company_name) { return 1; }
if (a.company_name < b.company_name) { return -1; }
return 0;
});
Then you may replace the for loop with jQuery.map() to get the output :
var output = jQuery.map(json_obj, function (row) {
// build your HTML here
return '<div>' + row.company_name + '</div>';
});
Finally :
$('#dealer_limpopo').html(output.join('')); // don't forget to join :)
"All in one" answer :
var headline = $(response.responseText).text()
var json_obj = $.parseJSON(headline); //parse JSON
json_obj.sort(function (a, b) {
if (a.company_name > b.company_name) { return 1; }
if (a.company_name < b.company_name) { return -1; }
return 0;
});
return jQuery.map(json_obj, function (row) {
return [
'<div class="dealer">',
'<dl>',
'<dt>Company Name</dt>',
'<dd>', row.company_name, '</dd>',
'<dt>Company Description</dt>',
'<dd>', row.company_description, '</dd>',
'<dt>Email Address</dt>',
'<dd>', row.company_email, '</dd>',
'<dt>Contact Number</dt>',
'<dd>', row.contact_number, '</dd>',
'<dt>Website URL</dt>',
'<dd>', row.website_url, '</dd>',
'<dt>City</dt>',
'<dd>', row.city_suburb, '</dd>',
'<dt>Physical Address</dt>',
'<dd>', row.physical_address, '</dd>',
'</dl>',
'</div>'
];
}).join('');