I have a loop in which I am calling rec_append() recursively, apparently the first pass alone works, then the loop stops.
I have an array of 4 elements going into that $.each loop but I see only the first element going into the function recursively. Help!
I switched it for a element.forEach but that gives me only the second element and I am stuck, is there a better solution to process a tree of elements? My array is a part of a tree.
var data = JSON.parse(JSON.stringify(result))
var graph = $(".entry-point");
function rec_append(requestData, parentDiv) {
var temp_parent_details;
$.each(requestData, function (index, jsonElement) {
if (typeof jsonElement === 'string') {
//Element construction
//Name and other details in the form of a : delimited string
var splitString = jsonElement.split(':');
var details = document.createElement("details");
var summary = document.createElement("summary");
summary.innerText = splitString[0];
details.append(summary);
temp_parent_details = details;
parentDiv.append(details);
var kbd = document.createElement("kbd");
kbd.innerText = splitString[1];
summary.append(' ');
summary.append(kbd);
var div = document.createElement("div");
div.className = "col";
details.append(div);
var dl = document.createElement("dl");
div.append(dl);
var dt = document.createElement("dt");
dt.className = "col-sm-1";
dt.innerText = "Path";
div.append(dt);
var dd = document.createElement("dd");
dd.className = "col-sm-11";
dd.innerText = splitString[2];
div.append(dd);
var dt2 = document.createElement("dt");
dt2.className = "col-sm-1";
dt2.innerText = "Type";
div.append(dt2);
var dd2 = document.createElement("dd");
dd2.className = "col-sm-11";
dd2.innerText = splitString[1];
div.append(dd2);
} else {
$.each(jsonElement, function (jsonElementArrIndx, jsonChildElement) {
rec_append(jsonChildElement, temp_parent_details); //Only 1 pass works, rest skip
});
}
});
}
rec_append(data, graph);
Sample data:enter image description here
Related
I have this in Jquery all works:
$(document).ready(function() {
$("#checktable td:nth-child(1)").click(function(event){ // This line I need converted
event.preventDefault();
var $td = $(this).closest('tr').children('td'); //This line I need converted
var tid = $td.eq(0).text();
var tdate = $td.eq(1).text();
var tdescribe = $td.eq(2).text();
var wd = $td.eq(3).text();
var dep = $td.eq(4).text();
// ... more code
I need a similar thing in javascript, above only first td is clicked.
My javascript code so far:
function addRowHandlers() {
var table = document.getElementById("checktable2");
var rows = table.getElementsByTagName('tr');
var tid = '';
var tdate = '';
var tdescribe = '';
var wd = '';
var dep = '';
var tisclr = '';
for (var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].onclick = function() {
tid = table.rows[this.i].cells[0].innerText;
tdate = table.rows[this.i].cells[1].innerHTML;
tdescribe = table.rows[this.i].cells[2].innerHTML;
wd = table.rows[this.i].cells[3].innerHTML;
dep = table.rows[this.i].cells[4].innerHTML;
// ... etc more code
The javascript works but any td can be clicked, I am after only:
The first td clicked
Then get parent row
Then all child td's
I have been over dozens of StackOverflow posts and other sites as well... Thanks
And how do I add the event.preventDefault() to regular JS in such a case.
You'd bind the handler to the first .cell.
rows[i].cells[0].onclick = function () {
And then in the handler, access the .parentNode of this to get the row.
And since you're not closing over any variables except those in the function itself (and outside that function, of course), I'd just use a single handler instead of recreating it in the loop.
function addRowHandlers() {
var table = document.getElementById("checktable2");
var rows = table.getElementsByTagName('tr');
var tid = '';
var tdate = '';
var tdescribe = '';
var wd = '';
var dep = '';
var tisclr = '';
for (var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].cells[0].onclick = handler;
}
function handler() {
var row = this.parentNode;
tid = this.innerText;
tdate = row.cells[1].innerHTML;
tdescribe = row.cells[2].innerHTML;
wd = row.cells[3].innerHTML;
dep = row.cells[4].innerHTML;
// etc more code
}
}
I'd probably use a loop to get the desired content too. Maybe like this:
function handler() {
var row = this.parentNode;
var props = ["tid", "tdate", "tdescribe", "wd", "dep"];
var content = props.reduce(function(obj, key, i) {
obj[key] = row.cells[i][i ? "innerHTML" : "innerText"];
return obj;
}, {});
// etc more code
}
Now instead of variables, you have properties of the content object.
I have a JavaScript Win Pivot Application
Into the Hub I am retrieving some information:
function initPages(options) {
for (var i = 0; i < options.length ; i++) {
var menuItem = options[i];
menuItem.showBanner = (i == 0);
definePages(options);
}
}
and in a .Js file I have the definePages function created:
functions.js:
function definePages(item) {
var action = item[0];
var animation = item[1];
var scyfy = item[2];
var localmovies = item[3];
var clasic = item[4];
var comedy = item[5];
var biography = item[6];
var drama = item[7];
var kids = item[8];
var musical = item[9];
var romantic = item[10];
var suspense = item[11];
var horror = item[12];
var art = item[13];
var personalities = item[14];
var history = item[15];
var society = item[16];
}
Now, in my section 1 I initialize the page by calling another function there:
ready: function (element, options) {
// TODO: Inicializar la página aquí.
options = options || {};
initMovies();
},
function initMovies() {
var element = document.getElementById("movieContainer");
//var movies = ??????????????????????????
//console.log(movies);
//it keeps going
}
I need to be able to retrive, in that var movies, the var action, from the functions.Js or, which is the same, the items[0]...
However, if I call a function in functions.Js, which is defined in section1Page, it won´t work...
I can call functions and pass data from anywhere to functions.Js, but not the other way around...
Any ideas on what should I do? Thanks!!!
I fixed it... I created a global var in function.Js and I get the info from the array in each section later on:
function definePages(item) {
tooSleepyToThink = item;
}
section1Page:
function initMovies() {
var elemento = document.getElementById("movieContainer");
console.log(tooSleepyToThink[0].text);
}
I'm getting HTML from a forum url, and parsing the post count of the user from their profile page. I don't know how to write the parsed number into the Google spreadsheet.
It should go account by account in column B till last row and update the column A with count.
The script doesn't give me any errors, but it doesn't set the retrieved value into the spreadsheet.
function msg(message){
Browser.msgBox(message);
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update Table', 'updatePosts')
.addToUi();
}
function getPostCount(profileUrl){
var html = UrlFetchApp.fetch(profileUrl).getContentText();
var sliced = html.slice(0,html.search('Posts Per Day'));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
return postCount;
}
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var accountSheet = spreadSheet.getSheetByName("account-stats");
var statsLastCol = statsSheet.getLastColumn();
var accountCount = accountSheet.getLastRow();
var newValue = 0;
var oldValue = 0;
var totalNewPosts = 0;
for (var i=2; i<=accountCount; i++){
newValue = parseInt(getPostCount(accountSheet.getRange(i, 9).getValue()));
oldValue = parseInt(accountSheet.getRange(i, 7).getValue());
totalNewPosts = totalNewPosts + newValue - oldValue;
accountSheet.getRange(i, 7).setValue(newValue);
statsSheet.getRange(i,statsLastCol).setValue(newValue-todaysValue);
}
if(showAlert==false){
return 0;
}
msg(totalNewPosts+" new post found!");
}
function valinar(needle, haystack){
haystack = haystack[0];
for (var i in haystack){
if(haystack[i]==needle){
return true;
}
}
return false;
}
The is the first time I'm doing something like this and working from an example from other site.
I have one more question. In function getPostCount I send the function profileurl. Where do I declare that ?
Here is how you get the URL out of the spreadsheet:
function getPostCount(profileUrl){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var thisSheet = ss.getSheetByName("List1");
var getNumberOfRows = thisSheet.getLastRow();
var urlProfile = "";
var sliced = "";
var A_Column = "";
var arrayIndex = 0;
var rngA2Bx = thisSheet.getRange(2, 2, getNumberOfRows, 1).getValues();
for (var i = 2; i < getNumberOfRows + 1; i++) { //Start getting urls from row 2
//Logger.log('count i: ' + i);
arrayIndex = i-2;
urlProfile = rngA2Bx[arrayIndex][0];
//Logger.log('urlProfile: ' + urlProfile);
var html = UrlFetchApp.fetch(urlProfile).getContentText();
sliced = html.slice(0,html.search('Posts Per Day'));
var postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
Logger.log('postCount: ' + postCount);
A_Column = thisSheet.getRange(i, 1);
A_Column.setValue(postCount);
};
}
You're missing var in front of one of your variables:
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
That won't work. Need to put var in front. var postCount = ....
In this function:
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
There is no array named arguments anywhere in your code. Where is arguments defined and how is it getting any values put into it?
When I try var a = ar_url2.concat(ar_desc2); to join my arrays into one it returns null. I'm sure it's trivial but I spent a few hours stuck on this now and an explanation as why this is happening would be great. In my code bellow I tried while(ar_url2.length)a.push(ar_url2.shift()); and it returns same null...
function agregar() {
var i = 0,
textarea;
var ar_desc = [];
while (textarea = document.getElementsByTagName('textarea')[i++]) {
if (textarea.id.match(/^desc_([0-9]+)$/)) {
ar_desc.push(textarea.id);
}
}
var desc_count_demo = document.getElementById('desc_count').value;
var desc_count = desc_count_demo - 1;
i = 0;
var ar_desc2 = [];
var campo = null;
while (i <= desc_count) {
campo = document.getElementById(ar_desc[i]).value;
ar_desc2[ar_desc[i]] = campo;
i++;
}
i = 0;
var input;
var ar_url = [];
while (input = document.getElementsByTagName('input')[i++]) {
if (input.id.match(/^url_([0-9]+)$/)) {
ar_url.push(input.id);
}
}
var url_count_demo2 = document.getElementById('url_count').value;
var url_count2 = url_count_demo2 - 1;
i = 0;
var ar_url2 = [];
while (i <= url_count2) {
campo = document.getElementById(ar_url[i]).value;
ar_url2[ar_url[i]] = campo;
i++;
}
// var a = Array.prototype.concat.call(ar_url2, ar_desc2);
while (ar_url2.length) a.push(ar_url2.shift());
function url(data) {
var ret = [];
for (var d in data)
ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
return ret.join("&");
}
window.open('alta1.php?'+url(a));
}
EDIT: If I pass to function url(ar_url2) or url(ar_desc2) the returned values in the URL are
http://localhost/proj1/alta1.php?url_0=inpit&url_1=input
and
http://localhost/proj1/alta1.php?desc_0=input&desc_1=input
But still cannot merge both into one...
One thing I see is your ar_url Array is filled by:
while(input=document.getElementsByTagName('input')[i++]){
if(input.id.match(/^url_([0-9]+)$/)){
ar_url.push(input.id);
}
}
Since you the putting the whole id in the array, it will be filled with things like: 'url_0', 'url_1', 'url_2', etc...
Later you do:
ar_url2[ar_url[i]] = campo;
When you index into ar_url, you get out the 'url_XXX' strings. That means you are setting the 'url_XXX' properties on ar_url2 instead of filling in the elements of the array.
Try changing your second loop to:
while(input=document.getElementsByTagName('input')[i++]){
var result;
if(result = input.id.match(/^url_([0-9]+)$/)){
ar_url.push(+result[1]);
}
}
To use the value captured in the ([0-9]+) portion of the RegExp instead of the entire 'url_XXX' string.
i got an anchor in the DOM and the following code replaces it with a fancy button. This works well but if i want more buttons it crashes. Can I do it without a for-loop?
$(document).ready(buttonize);
function buttonize(){
//alert(buttonAmount);
//Lookup for the classes
var button = $('a.makeabutton');
var buttonContent = button.text();
var buttonStyle = button.attr('class');
var link = button.attr('href');
var linkTarget = button.attr('target');
var toSearchFor = 'makeabutton';
var toReplaceWith = 'buttonize';
var searchButtonStyle = buttonStyle.search(toSearchFor);
if (searchButtonStyle != -1) {
//When class 'makeabutton' is found in string, build the new classname
newButtonStyle = buttonStyle.replace(toSearchFor, toReplaceWith);
button.replaceWith('<span class="'+newButtonStyle
+'"><span class="left"></span><span class="body">'
+buttonContent+'</span><span class="right"></span></span>');
$('.buttonize').click(function(e){
if (linkTarget == '_blank') {
window.open(link);
}
else window.location = link;
});
}
}
Use the each method because you are fetching a collection of elements (even if its just one)
var button = $('a.makeabutton');
button.each(function () {
var btn = $(this);
var buttonContent = btn.text();
var buttonStyle = btn.attr('class');
var link = btn.attr('href');
var linkTarget = btn.attr('target');
var toSearchFor = 'makeabutton';
var toReplaceWith = 'buttonize';
var searchButtonStyle = buttonStyle.search(toSearchFor);
...
};
the each method loops through all the elements that were retrieved, and you can use the this keyword to refer to the current element in the loop
var button = $('a.makeabutton');
This code returns a jQuery object which contains all the matching anchors. You need to loop through them using .each:
$(document).ready(buttonize);
function buttonize() {
//alert(buttonAmount);
//Lookup for the classes
var $buttons = $('a.makeabutton');
$buttons.each(function() {
var button = $(this);
var buttonContent = button.text();
var buttonStyle = button.attr('class');
var link = button.attr('href');
var linkTarget = button.attr('target');
var toSearchFor = 'makeabutton';
var toReplaceWith = 'buttonize';
var searchButtonStyle = buttonStyle.search(toSearchFor);
if (searchButtonStyle != -1) {
newButtonStyle = buttonStyle.replace(toSearchFor, toReplaceWith);
button.replaceWith('<span class="'
+ newButtonStyle
+ '"><span class="left"></span><span class="body">'
+ buttonContent
+ '</span><span class="right"></span></span>');
$('.buttonize').click(function(e) {
if (linkTarget == '_blank') {
window.open(link);
} else window.location = link;
}); // end click
} // end if
}); // end each
}