How to capture JSON export and send to URL - javascript

I added the code you suggested, thanks, but still not seeing anything on the targeted wordpress page- http://rpssolar.com/?page_id=1822. I think I am missing login information= or something else??
This is the code now:
// Includes functions for exporting active sheet or all sheets as JSON object (also Python object syntax compatible).
// Tweak the makePrettyJSON_ function to customize what kind of JSON to export.
var FORMAT_ONELINE = 'One-line';
var FORMAT_MULTILINE = 'Multi-line';
var FORMAT_PRETTY = 'Pretty';
var LANGUAGE_JS = 'JavaScript';
var LANGUAGE_PYTHON = 'Python';
var STRUCTURE_LIST = 'List';
var STRUCTURE_HASH = 'Hash (keyed by "id" column)';
/* Defaults for this particular spreadsheet, change as desired */
var DEFAULT_FORMAT = FORMAT_PRETTY;
var DEFAULT_LANGUAGE = LANGUAGE_JS;
var DEFAULT_STRUCTURE = STRUCTURE_LIST;
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "Export JSON for this sheet", functionName: "exportSheet"},
{name: "Export JSON for all sheets", functionName: "exportAllSheets"},
{name: "Configure export", functionName: "exportOptions"},
];
ss.addMenu("Export JSON", menuEntries);
}
function exportOptions() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setTitle('Export JSON');
var grid = app.createGrid(4, 2);
grid.setWidget(0, 0, makeLabel(app, 'Language:'));
grid.setWidget(0, 1, makeListBox(app, 'language', [LANGUAGE_JS, LANGUAGE_PYTHON]));
grid.setWidget(1, 0, makeLabel(app, 'Format:'));
grid.setWidget(1, 1, makeListBox(app, 'format', [FORMAT_PRETTY, FORMAT_MULTILINE, FORMAT_ONELINE]));
grid.setWidget(2, 0, makeLabel(app, 'Structure:'));
grid.setWidget(2, 1, makeListBox(app, 'structure', [STRUCTURE_LIST, STRUCTURE_HASH]));
grid.setWidget(3, 0, makeButton(app, grid, 'Export Active Sheet', 'exportSheet'));
grid.setWidget(3, 1, makeButton(app, grid, 'Export All Sheets', 'exportAllSheets'));
app.add(grid);
doc.show(app);
}
function makeLabel(app, text, id) {
var lb = app.createLabel(text);
if (id) lb.setId(id);
return lb;
}
function makeListBox(app, name, items) {
var listBox = app.createListBox().setId(name).setName(name);
listBox.setVisibleItemCount(1);
var cache = CacheService.getPublicCache();
var selectedValue = cache.get(name);
Logger.log(selectedValue);
for (var i = 0; i < items.length; i++) {
listBox.addItem(items[i]);
if (items[1] == selectedValue) {
listBox.setSelectedIndex(i);
}
}
return listBox;
}
function makeButton(app, parent, name, callback) {
var button = app.createButton(name);
app.add(button);
var handler = app.createServerClickHandler(callback).addCallbackElement(parent);;
button.addClickHandler(handler);
return button;
}
function makeTextBox(app, name) {
var textArea = app.createTextArea().setWidth('100%').setHeight('200px').setId(name).setName(name);
return textArea;
}
function exportAllSheets(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetsData = {};
for (var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
var rowsData = getRowsData_(sheet, getExportOptions(e));
var sheetName = sheet.getName();
sheetsData[sheetName] = rowsData;
}
var json = makeJSON_(sheetsData, getExportOptions(e));
return displayText_(json);
}
function exportSheet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rowsData = getRowsData_(sheet, getExportOptions(e));
var json = makeJSON_(rowsData, getExportOptions(e));
return displayText_(json);
}
function getExportOptions(e) {
var options = {};
options.language = e && e.parameter.language || DEFAULT_LANGUAGE;
options.format = e && e.parameter.format || DEFAULT_FORMAT;
options.structure = e && e.parameter.structure || DEFAULT_STRUCTURE;
var cache = CacheService.getPublicCache();
cache.put('language', options.language);
cache.put('format', options.format);
cache.put('structure', options.structure);
Logger.log(options);
return options;
}
function makeJSON_(object, options) {
if (options.format == FORMAT_PRETTY) {
var jsonString = JSON.stringify(object, null, 4);
} else if (options.format == FORMAT_MULTILINE) {
var jsonString = Utilities.jsonStringify(object);
jsonString = jsonString.replace(/},/gi, '},\n');
jsonString = prettyJSON.replace(/":\[{"/gi, '":\n[{"');
jsonString = prettyJSON.replace(/}\],/gi, '}],\n');
} else {
var jsonString = Utilities.jsonStringify(object);
}
if (options.language == LANGUAGE_PYTHON) {
// add unicode markers
jsonString = jsonString.replace(/"([a-zA-Z]*)":\s+"/gi, '"$1": u"');
}
return jsonString;
}
var JSON_DESTINATION_URL = 'http://rpssolar.com/?page_id=1822';
function sendJson_(json) {
var options = {
"contentType":"application/json",
"method" : "post",
"payload" : json
};
UrlFetchApp.fetch(JSON_DESTINATION_URL, options);
}function displayText_(text) {
var app = UiApp.createApplication().setTitle('Exported JSON');
app.add(makeTextBox(app, 'json'));
app.getElementById('json').setText(text);
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.show(app);
return app;
}
// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - columnHeadersRowIndex: specifies the row number where the column names are stored.
// This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData_(sheet, options) {
var headersRange = sheet.getRange(1, 1, sheet.getFrozenRows(), sheet.getMaxColumns());
var headers = headersRange.getValues()[0];
var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getMaxRows(), sheet.getMaxColumns());
var objects = getObjects_(dataRange.getValues(), normalizeHeaders_(headers));
if (options.structure == STRUCTURE_HASH) {
var objectsById = {};
objects.forEach(function(object) {
objectsById[object.id] = object;
});
return objectsById;
} else {
return objects;
}
}
// getColumnsData iterates column by column in the input range and returns an array of objects.
// Each object contains all the data for a given column, indexed by its normalized row name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - rowHeadersColumnIndex: specifies the column number where the row names are stored.
// This argument is optional and it defaults to the column immediately left of the range;
// Returns an Array of objects.
function getColumnsData_(sheet, range, rowHeadersColumnIndex) {
rowHeadersColumnIndex = rowHeadersColumnIndex || range.getColumnIndex() - 1;
var headersTmp = sheet.getRange(range.getRow(), rowHeadersColumnIndex, range.getNumRows(), 1).getValues();
var headers = normalizeHeaders_(arrayTranspose_(headersTmp)[0]);
return getObjects(arrayTranspose_(range.getValues()), headers);
}
// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
// - data: JavaScript 2d array
// - keys: Array of Strings that define the property names for the objects to create
function getObjects_(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty_(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
// Returns an Array of normalized Strings.
// Arguments:
// - headers: Array of Strings to normalize
function normalizeHeaders_(headers) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
var key = normalizeHeader_(headers[i]);
if (key.length > 0) {
keys.push(key);
}
}
return keys;
}
// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
// - header: string to normalize
// Examples:
// "First Name" -> "firstName"
// "Market Cap (millions) -> "marketCapMillions
// "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader_(header) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum_(letter)) {
continue;
}
if (key.length == 0 && isDigit_(letter)) {
continue; // first character must be a letter
}
if (upperCase) {
upperCase = false;
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty_(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise.
function isAlnum_(char) {
return char >= 'A' && char <= 'Z' ||
char >= 'a' && char <= 'z' ||
isDigit_(char);
}
// Returns true if the character char is a digit, false otherwise.
function isDigit_(char) {
return char >= '0' && char <= '9';
}
// Given a JavaScript 2d Array, this function returns the transposed table.
// Arguments:
// - data: JavaScript 2d Array
// Returns a JavaScript 2d Array
// Example: arrayTranspose([[1,2,3],[4,5,6]]) returns [[1,4],[2,5],[3,6]].
function arrayTranspose_(data) {
if (data.length == 0 || data[0].length == 0) {
return null;
}
var ret = [];
for (var i = 0; i < data[0].length; ++i) {
ret.push([]);
}
for (var i = 0; i < data.length; ++i) {
for (var j = 0; j < data[i].length; ++j) {
ret[j][i] = data[i][j];
}
}
return ret;
}

Instead of displaying the text via the displayText_() function, define a new function which POSTS the JSON to your destination.
var JSON_DESTINATION_URL = 'http://requestb.in/1gngj131';
function sendJson_(json) {
var options = {
"contentType":"application/json",
"method" : "post",
"payload" : json
};
UrlFetchApp.fetch(JSON_DESTINATION_URL, options);
}
If you still want to see the popup of text, just call this function before you call displayText_().
I'm assuming you want to POST this data. If you want to use another HTTP method, see the "method" section and related examples in the docs:
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app

Related

How to get a cell in a range by the value of the cell?

I have a google sheets table and have this google apps script:
//function formatReport(){
// let sheet = SpreadsheetApp.getActiveSpreadsheet();
// let header = sheet.getRange('A1:C1');
// header.setBackground('#eeeeee')
//}
function getCellByValue(cValue){
}
var sheet = SpreadsheetApp.getActiveSpreadsheet();
console.log(sheet.getRange('D2:D1001').getCellByValue('#bongo').toString());
const doGet = (event = {}) => {
const { parameter } = event;
const { type = 'badrequest' } = parameter;
if (type == 'get'){
let select = '3';
var name = sheet.getRange('A' + select).getValue();
var icon = sheet.getRange('B' + select).getValue();
var message = sheet.getRange('C' + select).getValue();
}
let jsonTempl = {
'type': type,
'name': name,
'icon': icon,
'message': message
};
let myJSON = JSON.stringify(jsonTempl);
return ContentService.createTextOutput(myJSON).setMimeType(ContentService.MimeType.JSON);
};
function doPost(e) {
return true;
}
I need to get a cell from a range by only using the value of the cell. For example if I had a range A1:A3, with the values being 'first, second, third', I would want to get second in the range by only using the name 'second';
The Example you posted in your comment:
function findInRange(range, findtext) {
let ranger = sheet.getRange(range);
for (var tick = 0; tick > ranger.getValues().length; tick++) {
if (ranger.getValues()[tick] == findtext) {
var out = tick;
}
console.log(ranger.getvalues()[tick]);
}
}
After experimenting I found the answer
function findInRange(range,findtext){
let ranger = sheet.getRange(range);
var tickr = 0;
while(tickr < ranger.getValues().length){
if (ranger.getValues()[tickr] == findtext){
var out = tickr;
}
tickr += 1;
}
return out;
}
In the range parameter, you just input the range, then the text is a string for the text looked for. It returns the number in that range if it was found. If it was not found then it outputs undefined.

Javascript group URLs by domain and directory

How can I group the URLs from a sorted list by domain and directory?
If two URLs have the same directory (just the first one after domain), then they should be grouped in an array;
Those URLs whose first directory is different, but have the same domain, should be grouped in an array;
For example, the URLs from this list:
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"]
Should be grouped as follows:
var group_url = [
["https://www.facebook.com/impression.php/f2e61d9df/?lid=115","https://www.facebook.com/plugins/like.php?app_id=5",],
["https://www.facebook.com/tr/a/?id=228037074239568","https://www.facebook.com/tr/b/?ev=ViewContent"],
["http://www.marvel.com/abc?f=33","http://www.marvel.com/videos"],
["http://www.marvel.com/games?a=11","http://www.marvel.com/games?z=22"]
]
I wrote some code but only managed to group the URLs by domain:
var group_url = [];
var count = 0;
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/?id=228037074239568",
"https://www.facebook.com/tr/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"]
for(i = 0; i < url_list.length; i++) {
if(url_list[i] != "") {
var current = url_list[i].replace(/.*?:\/\//g, "");
var check = current.substr(0, current.indexOf('/'));
group_url.push([])
for(var j = i; j < url_list.length; j++) {
var add_url = url_list[j];
if(add_url.indexOf(check) != -1) {
group_url[count].push(add_url);
url_list[j] = "";
}
else {
break;
}
}
count += 1;
}
}
console.log(JSON.stringify(group_url));
It seems like you want to group the URLs by domain+dir, but if they end up being alone in their group, to then regroup those by domain only.
For that you can use this script (ES5):
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"];
// Group the URLs, keyed by domain+dir
var hash = url_list.reduce(function (hash, url) {
// ignore protocol, and extract domain and first dir:
var domAndDir = url.replace(/^.*?:\/\//, '').match(/^.*?\..*?\/[^\/?#]*/)[0];
hash[domAndDir] = (hash[domAndDir] || []).concat(url);
return hash;
}, {});
// Regroup URLs by domain only, when they are alone for their domain+dir
Object.keys(hash).forEach(function (domAndDir) {
if (hash[domAndDir].length == 1) {
var domain = domAndDir.match(/.*\//)[0];
hash[domain] = (hash[domain] || []).concat(hash[domAndDir]);
delete hash[domAndDir];
}
});
// Convert hash to array
var result = Object.keys(hash).map(function(key) {
return hash[key];
});
// Output result
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
NB: I did not use ES6 as you mentioned ES5 in comments, but consider using ES6 Map for such a hash, which is better suited for the job.
urllistextended=url_list.map(function(el){return el.split("://")[1].split("/");});//remove protocol, split by /
var obj={};
for(var index in urllistextended){
var el=urllistextended[index];
obj[el[0]]=obj[el[0]]||{};
obj[el[0]][el[1]]=obj[el[0]][el[1]]||[];
obj[el[0]][el[1]].push(url_list[index]);
}
Use like this:
obj["www.facebook.com"];//{plugins:[],tr:[]}
obj["www.facebook.com"]["tr"];//[url1,url2]
http://jsbin.com/qacasexowi/edit?console enter "result"
I would recommend using the excellent URI.js library which offers great ways to parse, query and manipulate URLs: http://medialize.github.io/URI.js/
For example to work with the path (what you are referring to as directory) you could easily do the following (taken straight from the api docs):
var uri = new URI("http://example.org/foo/hello.html");
// get pathname
uri.pathname(); // returns string "/foo/hello.html"
// set pathname
uri.pathname("/foo/hello.html"); // returns the URI instance for chaining
// will encode for you
uri.pathname("/hello world/");
uri.pathname() === "/hello%20world/";
// will decode for you
uri.pathname(true) === "/hello world/";
// will return empty string for empty paths, but:
URI("").path() === "";
URI("/").path() === "/";
URI("http://example.org").path() === "/";
The rest should be easy going.
I suggest to use an object and group by domain and by the first string after the domain. Then iterate the tree and reduce it to the wanted structure.
This solution works with unsorted data.
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115", "https://www.facebook.com/plugins/like.php?app_id=5", "https://www.facebook.com/tr/a/?id=228037074239568", "https://www.facebook.com/tr/b/?ev=ViewContent", "http://www.marvel.com/abc?f=33", "http://www.marvel.com/games?a=11", "http://www.marvel.com/games?z=22", "http://www.marvel.com/videos"],
temp = [],
result;
url_list.forEach(function (a) {
var m = a.match(/.*?:\/\/([^\/]+)\/?([^\/?]+)?/);
m.shift();
m.reduce(function (r, b) {
if (!r[b]) {
r[b] = { _: [] };
r._.push({ name: b, children: r[b]._ });
}
return r[b];
}, this)._.push(a);
}, { _: temp });
result = temp.reduce(function (r, a) {
var top = [],
parts = [];
a.children.forEach(function (b) {
if (b.children.length === 1) {
top.push(b.children[0]);
} else {
parts.push(b.children);
}
});
return top.length ? r.concat([top], parts) : r.concat(parts);
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This does exactly what you need:
var url_list = ["https://www.facebook.com/impression.php/f2e61d9df/?lid=115",
"https://www.facebook.com/plugins/like.php?app_id=5",
"https://www.facebook.com/tr/a/?id=228037074239568",
"https://www.facebook.com/tr/b/?ev=ViewContent",
"http://www.marvel.com/abc?f=33",
"http://www.marvel.com/games?a=11",
"http://www.marvel.com/games?z=22",
"http://www.marvel.com/videos"];
var folderGroups = {};
for (var i = 0; i < url_list.length; i++) {
var myRegexp = /.*\/\/[^\/]+\/[^\/\?]+/g;
var match = myRegexp.exec(url_list[i]);
var keyForUrl = match[0];
if (folderGroups[keyForUrl] == null) {
folderGroups[keyForUrl] = [];
}
folderGroups[keyForUrl].push(url_list[i]);
}
var toRemove = [];
Object.keys(folderGroups).forEach(function(key,index) {
if (folderGroups[key].length == 1) {
toRemove.push(key);
}
});
for (var i = 0; i < toRemove.length; i++) {
delete folderGroups[toRemove[i]];
}
//console.log(folderGroups);
var domainGroups = {};
for (var i = 0; i < url_list.length; i++) {
//Check if collected previously
var myRegexpPrev = /.*\/\/[^\/]+\/[^\/\?]+/g;
var matchPrev = myRegexpPrev.exec(url_list[i]);
var checkIfPrevSelected = matchPrev[0];
debugger;
if (folderGroups[checkIfPrevSelected] != null) {
continue;
}
//Get for domain group
var myRegexp = /.*\/\/[^\/]+/g;
var match = myRegexp.exec(url_list[i]);
var keyForUrl = match[0];
if (domainGroups[keyForUrl] == null) {
domainGroups[keyForUrl] = [];
}
domainGroups[keyForUrl].push(url_list[i]);
}
//console.log(domainGroups);
var finalResult = {};
$.extend(finalResult, folderGroups, domainGroups);
console.log(Object.values(finalResult));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to fill divs with imgs dynamically?

http://jsfiddle.net/84nv2dmL/
I'm trying to get these images of letters to display in order. I tried creating divs dynamically and filling them with the img, but that didn't work. How can I get these letters to display in order?
jsfiddle code:
function getQueryStringVar(name){
var qs = window.location.search.slice(1);
var props = qs.split("&");
for (var i=0 ; i < props.length;i++){
var pair = props[i].split("=");
if(pair[0] === name) {
return decodeURIComponent(pair[1]);
}
}
}
function getLetterImage(tag){
var flickerAPI = "https://www.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
return $.getJSON( flickerAPI, {
tags: tag,
tagmode: "all",
format: "json"
})
.then(function (flickrdata) {
//console.log(flickrdata);
var i = Math.floor(Math.random() * flickrdata.items.length);
var item = flickrdata.items[i];
var url = item.media.m;
return url;
});
}
$(document).ready(function() {
var name = getQueryStringVar("name") || "Derek";
var str = "letter,";
var searchtags = new Array()
for (var i = 0; i < name.length; i++) {
//console.log(str.concat(searchtags.charAt(i)));
searchtags[i] = str.concat(name.charAt(i));
}
for (var j = 0; j < name.length; j++){
var request = getLetterImage(searchtags[j]);
request.done(function(url) {
$("body").append("<img src="+ url + "></img>");
//var ele = document.createElement("div");
//ele.setAttribute("class", "img" + j--);
//document.body.appendChild(ele);
//$("<img src="+ url +"></img>").appendTo("img"+j);
});
}
//$("#img"+i).html("<img src="+ url + "></img>");
});
You basically need to keep track of the order that you are appending your images to the DOM, and make sure that they are in sync with the letters in the name. Created a fiddle with a fix. Comments are in line:
http://jsfiddle.net/84nv2dmL/2/
function getQueryStringVar(name) {
var qs = window.location.search.slice(1);
var props = qs.split("&");
for (var i = 0; i < props.length; i++) {
var pair = props[i].split("=");
if (pair[0] === name) {
return decodeURIComponent(pair[1]);
}
}
}
function getLetterImage(tag) {
var flickerAPI = "https://www.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
return $.getJSON(flickerAPI, {
tags: tag.char,
tagmode: "all",
format: "json"
})
.then(function(flickrdata) {
//console.log(flickrdata);
var i = Math.floor(Math.random() * flickrdata.items.length);
var item = flickrdata.items[i];
var url = item.media.m;
// return an object with url AND index
return {
ind: tag.ind,
img: url
};
});
}
$(document).ready(function() {
var name = getQueryStringVar("name") || "Derek";
var urls = new Array(name.length); // array or URLs, in correct order
var urlCounter = []; // keeps count or URLs received
var str = "letter,";
var searchtags = new Array();
for (var i = 0; i < name.length; i++) {
searchtags[i] = {
char: str.concat(name.charAt(i)),
ind: i
};
}
for (var j = 0; j < name.length; j++) {
var request = getLetterImage(searchtags[j]);
request.done(function(url) {
// when request is done, place image url in 'urls' array, in the correct order
urls[url.ind] = url.img;
// push object to the counter array, just to keep count
urlCounter.push(url);
// check if all image urls have been collected
checkComplete();
});
}
function checkComplete() {
// if the number of URLs received is equal
// to the number of characters in the name
// append the images from the ordered array
if (urlCounter.length == name.length) {
for (var k = 0; k < urls.length; k++) {
$("body").append("<img src=" + urls[k] + "></img>");
}
}
}
});
$("#div_id").append("<img src="+ url + "></img>");
Here div_id is the id you gave to the div.
Append adds img tag with source src to it.
Please give the html code too along with the script to help understand the problem better

Filtering an array of Objects in javascript

I'm really new to JS, and I'm now stuck on a task, hope someone can guide me through it.
I have an Array of Objects, like this one:
var labels = [
// labels for pag 1
{pageID:1, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]},
// labels for pag 2
{pageID:2, labels: [
{labelID:0, content:[{lang:'eng', text:'Txt1 Eng'}, {lang:'de', text:'Txt1 De:'}]},
{labelID:1, content:[{lang:'eng', text:'Txt 2 Eng:'}, {lang:'de', text:'Txt2 De:'}]},
{labelID:2, content:[{lang:'eng', text:'Txt 3 Eng:'},{lang:'de', text:'Txt 3 De:'}]}
]}
]
What I am trying to do is write a function to return me an array of labels (Objects) for a specific page and a specific lang. By calling this function specifying pageID 1 and lang eng, I'm basically trying to build an array like this one:
var desideredArray = [
{labelID:0, text:'Txt1 Eng'},
{labelID:1, text:'Txt1 Eng'},
{labelID:2, text:'Txt2 Eng'}
]
Now, I'm trying to write the function to retrieve/build the new array:
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
// simpleLabelObject.text = ?????
results[i] = simpleLabelObject;
}
console.log (results);
};
...but how can I access the right value (the one corresponding the lang selected) in the content property?
You can use the same technique as the one used to keep the matching page: the filter method.
this.getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function( obj ) {
return obj.pageID == numPage;
});
var contentFilter = function(obj){ return obj.lang === lang};
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(contentFilter);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
console.log (desiredResults);
};
I didn't do bound checks because in your code you assumed there is always a matching element, but it would probably be wise to do it.
And if you want to avoid creating two closures each time the function is called, you can prototype an object for that:
var Filter = function(numPage, lang) {
this.numPage = numPage;
this.lang = lang;
};
Filter.prototype.filterPage = function(obj) {
return obj.pageID === this.numPage;
}
Filter.prototype.filterLang = function(obj) {
return obj.lang === this.lang;
}
Filter.prototype.filterLabels = function(labels) {
var result = labels.filter(this.filterPage, this);
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i=0; i<tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var matching = tempResult[i].content.filter(this.filterLang, this);
simpleLabelObject.text = matching[0].text;
desiredResults[i] = simpleLabelObject;
}
return desiredResults;
}
console.log(new Filter(1, "eng").filterLabels(labels));
Just filter again:
var getLabelsForPageAndLang = function (numPage, lang) {
// this part filters the main object and selects the object with pageID == numPage
var result = labels.filter(function (obj) {
return obj.pageID == numPage;
});
var tempResult = result[0].labels;
var desiredResults = []; // here I want to store the new objects
for (var i = 0; i < tempResult.length; i++) {
var simpleLabelObject = {};
simpleLabelObject.labelID = tempResult[i].labelID;
var lg = tempResult[i].content.filter(function (lg) {
return lg.lang == lang;
});
simpleLabelObject.text = lg[0].text;
desiredResults.push(simpleLabelObject);
}
console.log(desiredResults);
};
http://jsfiddle.net/9q5zF/
A rather 'safe' implementation for cases when pages have the same pageID and multiple contents with the same lang:
this.getLabelsForPageAndLang = function(numPage, lang) {
var result = [];
var pages = labels.filter(function( obj ) {
return obj.pageID === numPage;
});
for (var p = pages.length - 1; p >= 0; p--) {
var page = pages[p];
for(var i = page.labels.length - 1; i >= 0; i--) {
var labelId = page.labels[i].labelID;
for (var j = page.labels[i].content.length - 1; j >= 0; j--){
if (page.labels[i].content[j].lang === lang) {
result.push({labelID: labelId, test: page.labels[i].content[j].text});
}
}
}
}
console.log(result);
}
Fiddle: http://jsfiddle.net/6VQUm/

How to dynamically access nested Json object

I am trying to populate my input fields based on the retrieved JSON object. The field names in my form would be something like:
fullName
account.enabled
country.XXX.XXXX
The function should return something like below for the above fields
aData["fullName"]
aData["account"]["enabled"]
aData["country"]["XXX"]["XXXX"]
How should I write my a function that returns a matching JSON entry for a given HTML field's name ?
you could use the attached method that will recursively look for a given path in a JSON object and will fallback to default value (def) if there is no match.
var get = function (model, path, def) {
path = path || '';
model = model || {};
def = typeof def === 'undefined' ? '' : def;
var parts = path.split('.');
if (parts.length > 1 && typeof model[parts[0]] === 'object') {
return get(model[parts[0]], parts.splice(1).join('.'), def);
} else {
return model[parts[0]] || def;
}
}
and you can call it like that :
get(aData, 'country.XXX.XXXX', ''); //traverse the json object to get the given key
Iterate over the form elements, grab their names, split on '.', then access the JSON Object?
Something like:
var getDataValueForField = function (fieldName, data) {
var namespaces = fieldName.split('.');
var value = "";
var step = data;
for (var i = 0; i < namespaces.length; i++) {
if (data.hasOwnProperty(namespaces[i])) {
step = step[namespaces[i]];
value = step;
} else {
return (""); // safe value
}
}
return (value);
};
var populateFormFields = function (formId, data) {
var fields = document.querySelectorAll('#' + formId + ' input');
for (var i = 0; i < fields.length; i++) {
fields[i].value = getDataValueForField(fields[i].name, data);
}
};
populateFormFields('myForm', fetchedFromSomeWhere());

Categories

Resources