Append array value to string - javascript

How can an array value (could be any number less than 20K) be appended to a string?
I'm trying to imitate :
if (form1.EActQ20 === undefined) { Q2B0 = 0; }
else (Q2B0 = document.form1.EActQ20.value);
var und = x < 20000;
var less1 = form1.EActQ1.und.toString();
var less2 = form1.EActQ2.und.toString();
var less3 = form1.EActQ3.und.toString();
var less4 = form1.EActQ4.und.toString();
if (less1 === undefined) { Q1B.und.toString() = 0; }
else (Q1B.und.toString() = document.less1.value); /// is now a value to get added in an equation
if (less2 === undefined) { Q2B.und.toString() = 0; }
else (Q2B.und.toString() = document.less2.value);
if (less3 === undefined) { Q3B.und.toString() = 0; }
else (Q3B.und.toString() = document.less3.value);
if (less4 === undefined) { Q4B.und.toString() = 0; }
else (Q4B.und.toString() = document.less4.value);
/// Revised Code Below
arr = [];
var und = 0; // some number below 2000
var less = form1["EActQ1" + und];
if (less1 === undefined) {
arr[und] = 0;
} else {
arr[und] = document["less1" + und].value;
}
if (less2 === undefined) {
arr[und] = 0;
} else {
arr[und] = document["less2" + und].value;
}
if (less3 === undefined) {
arr[und] = 0;
} else {
arr[und] = document["less3" + und].value;
}
if (less1 === undefined) {
arr[und] = 0;
} else {
arr[und] = document["less1" + und].value;
}
add = (["Q1B"+ und] * 1)+(["Q2B"+ und] * 1)+(["Q3B"+ und] * 1)+(["Q4B"+ und] * 1);
Returns NaN. I'm defining cells based on their values and trying to add them up.

You seem to be looking for bracket notation:
var und = 0; // some number below 2000
var less = form1["EActQ" + und];
Also use an object to collect all those values, not a set of Q2B… variables. Or even better, just an array:
arr = [];
…
if (less === undefined) {
arr[und] = 0;
} else {
arr[und] = document["less" + und].value;
}

Related

Different result when put outside of event listener?

Sorry I am bad at asking questions, if you don't understand what I am asking please let me know
let node = this.createSvgNode("rect", {
'data-id': section.id || '',
x: section.x,
y: section.y,
width: section.width,
height: section.height,
fill: section.backgroundColor || "#EEEEEE"
});
let thisObject = this;
let paths = thisObject.findPaths(7, 3) // Doesn't work
node.addEventListener("click", function (e) {
let paths = thisObject.findPaths(7, 3) // works
});
I don't understand why let paths = thisObject.findPaths(7, 3) works when it is inside the event listener and doesn't when it is outside of the event listener. isn't it the same?
btw this is the findPaths function:
findPaths: function (startId, endId) {
let paths = [];
let startDoors = doors[startId];
let endDoors = doors[endId];
for (let i = 0; i < startDoors.length; i++) {
let startingPoint = this.findPointByCoordinates(startDoors[i]);
// console.log("Starting Point: " + JSON.stringify(startingPoint));
for (let j = 0; j < doors[endId].length; j++) {
let endingPoint = this.findPointByCoordinates(endDoors[j]);
// console.log("Ending Point: " + JSON.stringify(endingPoint));
let potentialPath = this.recursiveIterationOfPoints([startingPoint], endingPoint);
// console.log(potentialPath);
paths = paths.concat(potentialPath);
}
}
for (let id in paths) {
paths[id] = this.linkRoomsWithPath(paths[id], startId, endId);
}
return paths;
},
I get this error when I put let paths = thisObject.findPaths(7, 3) above the event listener:
Uncaught TypeError: Cannot read property 'length' of undefined
here is the full code
(function (global) {
var IndoorMaps = function (options) {
return new IndoorMaps.init(options);
};
let svgRootNode;
let doors = {};
let hallwayPoints = {};
let currentZIndex = 0;
let validZIndexes = [0];
let showHallwayPoints = false;
//let svgDimensions = {};
let floorPlan = [];
let mapSelection = null;
IndoorMaps.init = function (options) {
this.parseConfiguration(options || {});
this.parseFloorPlan(options.floorSections || {});
this.parseHallwayPoints(options.hallway || {});
//svgDimensions = this.calculateSVGWidthAndHeight();
svgRootNode = this.createSvgNode("svg", {
width: '100%',
height: '100%'
});
this.appendToBody(svgRootNode);
// Render the Map
this.drawMap(floorPlan[currentZIndex] || {});
if (showHallwayPoints) {
this.displayHallwayPoints(options.hallway || {});
}
return svgRootNode;
};
IndoorMaps.init.prototype = {
createSvgNode: function (elementName, attributes = {}, value) {
if (elementName === undefined) {
throw "Element name not found!";
}
let node = document.createElementNS("http://www.w3.org/2000/svg", elementName);
for (let attributeKey in attributes) {
node.setAttribute(attributeKey, attributes[attributeKey]);
}
if (value !== undefined) {
node.innerHTML = value;
}
return node;
},
appendToBody: function (node) {
window.document.body.appendChild(node);
},
draw: function (node) {
let panZoom = svgRootNode.querySelector('.svg-pan-zoom_viewport');
if (!panZoom) {
svgRootNode.append(node);
} else {
panZoom.append(node);
}
},
addDoors: function(roomId, doorPoints) {
doors[roomId] = doorPoints;
for (let i = 0; i < doorPoints.length; i++) {
let coordinates = doorPoints[i];
let attributes = {
x: coordinates.x,
y: coordinates.y,
width: coordinates.width || 0,
height: coordinates.height || 0,
fill: "#FF0000"
};
if (coordinates.width > coordinates.height) {
attributes.x -= coordinates.width / 2;
attributes.y -= coordinates.height;
}
if (coordinates.height > coordinates.width) {
attributes.x -= coordinates.width;
attributes.y -= coordinates.height / 2;
}
let rect = this.createSvgNode("rect", attributes);
this.draw(rect);
}
},
drawMap: function (floorSections) {
for (let i = 0; i < floorSections.length; i++) {
let section = floorSections[i];
if (
section.x === undefined
|| section.y === undefined
|| section.width === undefined
|| section.height === undefined
) {
throw "The x,y coordinates and the width and height are required fields.";
}
let node = this.createSvgNode("rect", {
'data-id': section.id || '',
x: section.x,
y: section.y,
width: section.width,
height: section.height,
fill: section.backgroundColor || "#EEEEEE"
});
let thisObject = this;
node.addEventListener("click", function (e) {
if (mapSelection === null) {
thisObject.removeRouteIndicators();
mapSelection = this;
this.classList.add('selected');
} else {
console.log(mapSelection.dataset.id + " : " + this.dataset.id);
let paths = thisObject.findPaths(mapSelection.dataset.id, this.dataset.id);
let shortestPath = thisObject.findShortestPath(paths);
thisObject.drawPath(shortestPath);
mapSelection = null;
this.classList.add('destination');
}
});
this.draw(node);
this.addDoors(section.id, section.doors);
if (section.label === undefined) {
continue;
}
if (section.label.text === undefined) {
throw "The text must be included for the label to be shown. Set label as null if you do not wish to display a label.";
}
xCoordinate = section.x + (section.label.x || 0);
yCoordinate = section.y + (section.label.y || 0);
let attributes = {
'x': xCoordinate,
'y': yCoordinate,
'fill': section.label.color || '#333333',
'font-family': section.label.fontStyle || 'Verdana',
'font-size': section.label.fontSize || '10'
};
if (section.label.alignment === undefined) {
section.label.alignment = "center|center";
}
if (section.label.alignment !== undefined) {
switch (section.label.alignment) {
case "center|center":
attributes['text-anchor'] = "middle";
attributes['dominant-baseline'] = "middle";
attributes['x'] = (section.width / 2) + section.x;
attributes['y'] = (section.height / 2) + section.y;
break;
case "horizontal_center":
attributes['text-anchor'] = "middle";
attributes['x'] = (section.width / 2) + section.x;
break;
case "vertical_center":
attributes['dominant-baseline'] = "middle";
attributes['y'] = (section.height / 2) + section.y;
break;
default:
throw "Alignment mode requested was not found.";
}
}
let textNode = this.createSvgNode("text", attributes, section.label.text);
this.draw(textNode);
}
},
drawPath: function(path) {
for (let i = 0; i < (path.length - 1); i++) {
let lineNode = this.createSvgNode('line', {
x1: path[i].x,
y1: path[i].y,
x2: path[i + 1].x,
y2: path[i + 1].y,
stroke: "green",
'data-type': "route"
});
this.draw(lineNode);
}
},
removeRouteIndicators: function () {
let nodes = svgRootNode.querySelectorAll('[data-type="route"]');
let panZoom = svgRootNode.querySelector('.svg-pan-zoom_viewport');
for (let index = 0; index < nodes.length; index++) {
if (!panZoom) {
svgRootNode.removeChild(nodes[index]);
} else {
panZoom.removeChild(nodes[index]);
}
}
nodes = svgRootNode.getElementsByClassName('selected');
for (let index = 0; index < nodes.length; index++) {
nodes[index].classList.remove('selected');
}
nodes = svgRootNode.getElementsByClassName('destination');
for (let index = 0; index < nodes.length; index++) {
nodes[index].classList.remove('destination');
}
},
displayHallwayPoints: function (hallwayNodes) {
for (let i = 0; i < hallwayNodes.length; i++) {
this.draw(
this.createSvgNode("circle", {
cx: hallwayNodes[i].x,
cy: hallwayNodes[i].y,
r: 2,
fill: hallwayNodes[i].fill || "black",
'data-id': hallwayNodes[i].id
})
);
}
},
findPaths: function (startId, endId) {
let paths = [];
let startDoors = doors[startId];
let endDoors = doors[endId];
for (let i = 0; i < startDoors.length; i++) {
let startingPoint = this.findPointByCoordinates(startDoors[i]);
console.log("Starting Point: " + JSON.stringify(startingPoint));
for (let j = 0; j < doors[endId].length; j++) {
let endingPoint = this.findPointByCoordinates(endDoors[j]);
console.log("Ending Point: " + JSON.stringify(endingPoint));
let potentialPath = this.recursiveIterationOfPoints([startingPoint], endingPoint);
console.log(potentialPath);
paths = paths.concat(potentialPath);
}
}
for (let id in paths) {
paths[id] = this.linkRoomsWithPath(paths[id], startId, endId);
}
return paths;
},
recursiveIterationOfPoints: function(path, end) {
let results = [];
let current = path[path.length - 1];
console.log(current);
if (current.id === end.id) {
return [path];
}
for (let i = 0; i < current.connected.length; i++) {
let nextPoint = hallwayPoints[current.connected[i]];
let found = false;
path.forEach( function (point, index) {
if (point.id === nextPoint.id) {
found = true;
}
});
if (found)
continue;
var newPath = path.slice();
newPath.push(nextPoint);
results = results.concat(this.recursiveIterationOfPoints(newPath, end));
}
return results;
},
findPointByCoordinates: function (coordinates) {
for (let id in hallwayPoints) {
let point = hallwayPoints[id];
if (point.x === coordinates.x && point.y === coordinates.y) {
return point;
}
}
},
findActualCoordinatesOfDoorByCoordinates: function (coordinates, roomId) {
let validDoors = doors[roomId];
for (let id in validDoors) {
if (validDoors[id].x === coordinates.x && validDoors[id].y === coordinates.y) {
return validDoors[id].actual;
}
}
},
parseHallwayPoints: function (points) {
for (let i = 0; i < points.length; i++) {
hallwayPoints[points[i].id] = points[i];
}
},
findShortestPath: function(paths) {
if (paths.length === 1)
return paths[0];
// Set benchmark range
let shortestDistance = this.calculateDistanceForPath(paths[0]);
let shortestPath = paths[0];
// Skip the first since it's already calculated.
for (let i = 1; i < paths.length; i++) {
let distance = this.calculateDistanceForPath(paths[i]);
if (distance < shortestDistance) {
shortestDistance = distance;
shortestPath = paths[i];
}
}
return shortestPath;
},
calculateDistanceForPath: function(path) {
let totalDistance = 0;
for (let i = 0; i < (path.length - 1); i++) {
// Formula: sqrt[(x0 - x1)^2 + (y0 - y1)^2]
totalDistance += Math.sqrt(Math.pow(path[i].x - path[i + 1].x, 2) + Math.pow(path[i].y - path[i + 1].y, 2));
}
return totalDistance;
},
linkRoomsWithPath: function (path, startId, endId) {
let first = this.findActualCoordinatesOfDoorByCoordinates(path[0], startId);
let last = this.findActualCoordinatesOfDoorByCoordinates(path[path.length - 1], endId);
path.unshift(first);
path.push(last);
return path;
},
parseConfiguration: function (options) {
currentZIndex = options.config.defaultZIndex || 0;
validZIndexes = options.config.validZIndexes || [0];
showHallwayPoints = options.config.showHallwayPoints || false;
},
parseFloorPlan: function (floorLayout) {
for (let i in floorLayout) {
if (floorLayout[i].z === undefined) {
floorLayout[i].z = 0;
}
if (!(floorLayout[i].z in floorPlan)) {
floorPlan[floorLayout[i].z] = [];
}
floorPlan[floorLayout[i].z].push(floorLayout[i]);
}
},
calculateSVGWidthAndHeight: function () {
let dimensions = {
width: 0,
height: 0
};
let floorLayout = floorPlan[currentZIndex];
let first = true;
for (let i in floorLayout) {
let calculatedWidth = floorLayout[i].width + floorLayout[i].x;
let calculatedHeight = floorLayout[i].height + floorLayout[i].y;
if (first) {
dimensions.width = calculatedWidth;
dimensions.height = calculatedHeight;
first = false;
}
if (calculatedWidth > dimensions.width) {
dimensions.width = calculatedWidth;
}
if (calculatedHeight > dimensions.height) {
dimensions.height = calculatedHeight;
}
}
for (let i in hallwayPoints) {
let currentWidth = hallwayPoints[i].x;
let currentHeight = hallwayPoints[i].y;
if (currentWidth > dimensions.width) {
dimensions.width = currentWidth;
}
if (currentHeight > dimensions.height) {
dimensions.height = currentHeight;
}
}
return dimensions;
}
};
window.indoorMaps = IndoorMaps;
}(window));
From the comment above, it seems that at the point you are calling findPaths(), doors exists, but is empty when you call findPaths(), though it is not when the event is triggered. Make sure that doors is filled before try to use it.

How to convert from Path to XPath, given a browser event

On a MouseEvent instance, we have a property called path, it might look like this:
Does anybody know if there is a reliable way to translate this path array into an XPath? I assume that this path data is the best data to start from? Is there a library I can use to do the conversion?
This library looks promising, but it doesn't use the path property of an event: https://github.com/johannhof/xpath-dom
There's not a unique XPath to a node, so you'll have to decide what's the most appropriate way of constructing a path. Use IDs where available? Numeral position in the document? Position relative to other elements?
See getPathTo() in this answer for one possible approach.
PS: Taken from Javascript get XPath of a node
Another option is to use SelectorGadget from below link
https://dv0akt2986vzh.cloudfront.net/unstable/lib/selectorgadget.js
The actual code for the DOM path is at
https://dv0akt2986vzh.cloudfront.net/stable/lib/dom.js
Usage: on http://google.com
elem = document.getElementById("q")
predict = new DomPredictionHelper()
predict.pathOf(elem)
// gives "body.default-theme.des-mat:nth-child(2) div#_Alw:nth-child(4) form#f:nth-child(2) div#fkbx:nth-child(2) input#q:nth-child(2)"
predict.predictCss([elem],[])
// gives "#q"
CODE if link goes down
// Copyright (c) 2008, 2009 Andrew Cantino
// Copyright (c) 2008, 2009 Kyle Maxwell
function DomPredictionHelper() {};
DomPredictionHelper.prototype = new Object();
DomPredictionHelper.prototype.recursiveNodes = function(e){
var n;
if(e.nodeName && e.parentNode && e != document.body) {
n = this.recursiveNodes(e.parentNode);
} else {
n = new Array();
}
n.push(e);
return n;
};
DomPredictionHelper.prototype.escapeCssNames = function(name) {
if (name) {
try {
return name.replace(/\s*sg_\w+\s*/g, '').replace(/\\/g, '\\\\').
replace(/\./g, '\\.').replace(/#/g, '\\#').replace(/\>/g, '\\>').replace(/\,/g, '\\,').replace(/\:/g, '\\:');
} catch(e) {
console.log('---');
console.log("exception in escapeCssNames");
console.log(name);
console.log('---');
return '';
}
} else {
return '';
}
};
DomPredictionHelper.prototype.childElemNumber = function(elem) {
var count = 0;
while (elem.previousSibling && (elem = elem.previousSibling)) {
if (elem.nodeType == 1) count++;
}
return count;
};
DomPredictionHelper.prototype.pathOf = function(elem){
var nodes = this.recursiveNodes(elem);
var self = this;
var path = "";
for(var i = 0; i < nodes.length; i++) {
var e = nodes[i];
if (e) {
path += e.nodeName.toLowerCase();
var escaped = e.id && self.escapeCssNames(new String(e.id));
if(escaped && escaped.length > 0) path += '#' + escaped;
if(e.className) {
jQuery.each(e.className.split(/ /), function() {
var escaped = self.escapeCssNames(this);
if (this && escaped.length > 0) {
path += '.' + escaped;
}
});
}
path += ':nth-child(' + (self.childElemNumber(e) + 1) + ')';
path += ' '
}
}
if (path.charAt(path.length - 1) == ' ') path = path.substring(0, path.length - 1);
return path;
};
DomPredictionHelper.prototype.commonCss = function(array) {
try {
var dmp = new diff_match_patch();
} catch(e) {
throw "Please include the diff_match_patch library.";
}
if (typeof array == 'undefined' || array.length == 0) return '';
var existing_tokens = {};
var encoded_css_array = this.encodeCssForDiff(array, existing_tokens);
var collective_common = encoded_css_array.pop();
jQuery.each(encoded_css_array, function(e) {
var diff = dmp.diff_main(collective_common, this);
collective_common = '';
jQuery.each(diff, function() {
if (this[0] == 0) collective_common += this[1];
});
});
return this.decodeCss(collective_common, existing_tokens);
};
DomPredictionHelper.prototype.tokenizeCss = function(css_string) {
var skip = false;
var word = '';
var tokens = [];
var css_string = css_string.replace(/,/, ' , ').replace(/\s+/g, ' ');
var length = css_string.length;
var c = '';
for (var i = 0; i < length; i++){
c = css_string[i];
if (skip) {
skip = false;
} else if (c == '\\') {
skip = true;
} else if (c == '.' || c == ' ' || c == '#' || c == '>' || c == ':' || c == ',') {
if (word.length > 0) tokens.push(word);
word = '';
}
word += c;
if (c == ' ' || c == ',') {
tokens.push(word);
word = '';
}
}
if (word.length > 0) tokens.push(word);
return tokens;
};
DomPredictionHelper.prototype.decodeCss = function(string, existing_tokens) {
var inverted = this.invertObject(existing_tokens);
var out = '';
jQuery.each(string.split(''), function() {
out += inverted[this];
});
return this.cleanCss(out);
};
// Encode css paths for diff using unicode codepoints to allow for a large number of tokens.
DomPredictionHelper.prototype.encodeCssForDiff = function(strings, existing_tokens) {
var codepoint = 50;
var self = this;
var strings_out = [];
jQuery.each(strings, function() {
var out = new String();
jQuery.each(self.tokenizeCss(this), function() {
if (!existing_tokens[this]) {
existing_tokens[this] = String.fromCharCode(codepoint++);
}
out += existing_tokens[this];
});
strings_out.push(out);
});
return strings_out;
};
DomPredictionHelper.prototype.simplifyCss = function(css, selected_paths, rejected_paths) {
var self = this;
var parts = self.tokenizeCss(css);
var best_so_far = "";
if (self.selectorGets('all', selected_paths, css) && self.selectorGets('none', rejected_paths, css)) best_so_far = css;
for (var pass = 0; pass < 4; pass++) {
for (var part = 0; part < parts.length; part++) {
var first = parts[part].substring(0,1);
if (self.wouldLeaveFreeFloatingNthChild(parts, part)) continue;
if ((pass == 0 && first == ':') || // :nth-child
(pass == 1 && first != ':' && first != '.' && first != '#' && first != ' ') || // elem, etc.
(pass == 2 && first == '.') || // classes
(pass == 3 && first == '#')) // ids
{
var tmp = parts[part];
parts[part] = '';
var selector = self.cleanCss(parts.join(''));
if (selector == '') {
parts[part] = tmp;
continue;
}
if (self.selectorGets('all', selected_paths, selector) && self.selectorGets('none', rejected_paths, selector)) {
best_so_far = selector;
} else {
parts[part] = tmp;
}
}
}
}
return self.cleanCss(best_so_far);
};
DomPredictionHelper.prototype.wouldLeaveFreeFloatingNthChild = function(parts, part) {
return (((part - 1 >= 0 && parts[part - 1].substring(0, 1) == ':') &&
(part - 2 < 0 || parts[part - 2] == ' ') &&
(part + 1 >= parts.length || parts[part + 1] == ' ')) ||
((part + 1 < parts.length && parts[part + 1].substring(0, 1) == ':') &&
(part + 2 >= parts.length || parts[part + 2] == ' ') &&
(part - 1 < 0 || parts[part - 1] == ' ')));
};
DomPredictionHelper.prototype.cleanCss = function(css) {
return css.replace(/\>/, ' > ').replace(/,/, ' , ').replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').replace(/,$/, '');
};
DomPredictionHelper.prototype.getPathsFor = function(arr) {
var self = this;
var out = [];
jQuery.each(arr, function() {
if (this && this.nodeName) {
out.push(self.pathOf(this));
}
})
return out;
};
DomPredictionHelper.prototype.predictCss = function(s, r) {
var self = this;
if (s.length == 0) return '';
var selected_paths = self.getPathsFor(s);
var rejected_paths = self.getPathsFor(r);
var css = self.commonCss(selected_paths);
var simplest = self.simplifyCss(css, selected_paths, rejected_paths);
// Do we get off easy?
if (simplest.length > 0) return simplest;
// Okay, then make a union and possibly try to reduce subsets.
var union = '';
jQuery.each(s, function() {
union = self.pathOf(this) + ", " + union;
});
union = self.cleanCss(union);
return self.simplifyCss(union, selected_paths, rejected_paths);
};
DomPredictionHelper.prototype.fragmentSelector = function(selector) {
var self = this;
var out = [];
jQuery.each(selector.split(/\,/), function() {
var out2 = [];
jQuery.each(self.cleanCss(this).split(/\s+/), function() {
out2.push(self.tokenizeCss(this));
});
out.push(out2);
});
return out;
};
// Everything in the first selector must be present in the second.
DomPredictionHelper.prototype.selectorBlockMatchesSelectorBlock = function(selector_block1, selector_block2) {
for (var j = 0; j < selector_block1.length; j++) {
if (jQuery.inArray(selector_block1[j], selector_block2) == -1) {
return false;
}
}
return true;
};
// Assumes list is an array of complete CSS selectors represented as strings.
DomPredictionHelper.prototype.selectorGets = function(type, list, the_selector) {
var self = this;
var result = true;
if (list.length == 0 && type == 'all') return false;
if (list.length == 0 && type == 'none') return true;
var selectors = self.fragmentSelector(the_selector);
var cleaned_list = [];
jQuery.each(list, function() {
cleaned_list.push(self.fragmentSelector(this)[0]);
});
jQuery.each(selectors, function() {
if (!result) return;
var selector = this;
jQuery.each(cleaned_list, function(pos) {
if (!result || this == '') return;
if (self._selectorGets(this, selector)) {
if (type == 'none') result = false;
cleaned_list[pos] = '';
}
});
});
if (type == 'all' && cleaned_list.join('').length > 0) { // Some candidates didn't get matched.
result = false;
}
return result;
};
DomPredictionHelper.prototype._selectorGets = function(candidate_as_blocks, selector_as_blocks) {
var cannot_match = false;
var position = candidate_as_blocks.length - 1;
for (var i = selector_as_blocks.length - 1; i > -1; i--) {
if (cannot_match) break;
if (i == selector_as_blocks.length - 1) { // First element on right.
// If we don't match the first element, we cannot match.
if (!this.selectorBlockMatchesSelectorBlock(selector_as_blocks[i], candidate_as_blocks[position])) cannot_match = true;
position--;
} else {
var found = false;
while (position > -1 && !found) {
found = this.selectorBlockMatchesSelectorBlock(selector_as_blocks[i], candidate_as_blocks[position]);
position--;
}
if (!found) cannot_match = true;
}
}
return !cannot_match;
};
DomPredictionHelper.prototype.invertObject = function(object) {
var new_object = {};
jQuery.each(object, function(key, value) {
new_object[value] = key;
});
return new_object;
};
DomPredictionHelper.prototype.cssToXPath = function(css_string) {
var tokens = this.tokenizeCss(css_string);
if (tokens[0] && tokens[0] == ' ') tokens.splice(0, 1);
if (tokens[tokens.length - 1] && tokens[tokens.length - 1] == ' ') tokens.splice(tokens.length - 1, 1);
var css_block = [];
var out = "";
for(var i = 0; i < tokens.length; i++) {
if (tokens[i] == ' ') {
out += this.cssToXPathBlockHelper(css_block);
css_block = [];
} else {
css_block.push(tokens[i]);
}
}
return out + this.cssToXPathBlockHelper(css_block);
};
// Process a block (html entity, class(es), id, :nth-child()) of css
DomPredictionHelper.prototype.cssToXPathBlockHelper = function(css_block) {
if (css_block.length == 0) return '//';
var out = '//';
var first = css_block[0].substring(0,1);
if (first == ',') return " | ";
if (jQuery.inArray(first, [':', '#', '.']) != -1) {
out += '*';
}
var expressions = [];
var re = null;
for(var i = 0; i < css_block.length; i++) {
var current = css_block[i];
first = current.substring(0,1);
var rest = current.substring(1);
if (first == ':') {
// We only support :nth-child(n) at the moment.
if (re = rest.match(/^nth-child\((\d+)\)$/))
expressions.push('(((count(preceding-sibling::*) + 1) = ' + re[1] + ') and parent::*)');
} else if (first == '.') {
expressions.push('contains(concat( " ", #class, " " ), concat( " ", "' + rest + '", " " ))');
} else if (first == '#') {
expressions.push('(#id = "' + rest + '")');
} else if (first == ',') {
} else {
out += current;
}
}
if (expressions.length > 0) out += '[';
for (var i = 0; i < expressions.length; i++) {
out += expressions[i];
if (i < expressions.length - 1) out += ' and ';
}
if (expressions.length > 0) out += ']';
return out;
};

Last Key in JavaScript array appearing as Length?

Bit of a weird one. Am using the following code build an array from a json object to make it easier to reference later in the code. However it would appear that when the last item of each array is created, rather than adding a new item, the Key of the item appears as the length of the array.
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
for (var perf_no in obj.Extras) {
if (extras[perf_no] == undefined) {
var arr = new Array();
for (var extra in obj.Extras[perf_no]) {
if (arr[extra] == undefined) {
arr[extra] = obj.Extras[perf_no][extra];
}
}
extras[perf_no] = arr;
}
}
break;
}
}
}
The resulting array appears as below:
Any ideas what's going on here?
Edit:
Sample of Json below
{"Extras":{"32516":{"24186":"Example text"},"32515":{"24186":"Example text"},"32514":{"24186":"Example text"},"32512":{"24186":"Example text"},"32513":{"24186":"Example text"},"32511":{"24186":"Example text"},"32510":{"24186":"Example text"},"32509":{"24186":"Example text"},"32507":{"24186":"Example text"},"32503":{"24186":"Example text"},"32506":{"24186":"Example text"},"32505":{"24186":"Example text"},"32508":{"24186":"Example text"},"32502":{},"32497":{}}}
What's going on hear is that you are using for..in to iterate over an array, which is a no-no because it iterates properties that are not the array elements (such as the .length property). Instead, use Array#forEach:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
var arr = new Array();
item.forEach(function (item2, idx2) {
if (typeof arr[idx2] === 'undefined') {
arr[idx2] = item2;
}
});
extras[idx] = arr;
}
});
break;
}
}
}
The innermost loop is pretty pointless and can be replaced with Array#slice:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
extras[idx] = item.slice();
}
});
break;
}
}
}
The next inner loop can be replaced with Array#map and two if statements can be combined:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null&& obj.Extras != null) {
extras = obj.Extras.map(function (item) {
return item.slice();
});
break;
}
}
In fact, most of this code can be simplified:
function findLastElement(arr) {
for (var i = arr.length - 1; i >= 0; i -= 1) {
if (arr[i] != null && arr[i].Extras != null) { return arr[i]; }
}
}
perfsJson = $.parseJSON(result);
var lastElement = findLastElement(perfsJson);
var extras = lastElement
? lastElement.Extras.map(function (item) { return item.slice(); })
: [];

Push to an array in a nested loop is repeating the last value

I am trying to push elements to an array in a nested loop, but only the last item is getting repeated in the final array, where am I going wrong, very new to javascript asynchronous concept.Below is the function in which I push the items to an array.
$scope.showBeList = function(feed) {
if (feed[srcServ.KEY_CONTENT_TEXT]) {
var content = JSON.parse(feed[srcServ.KEY_CONTENT_TEXT])
if (content) {
$scope.beList = {};
for (var key in content) {
var decorationVal;
//reading value from a lokijs collection
var decoration = dataServ[srcServ.CONST_COLLECTION_DECORATION].find({
'name': key
});
if (decoration && decoration.length) {
decorationVal = decoration[0];
if (decorationVal != null) {
var tempObj = JSON.parse(decorationVal.value);
if (tempObj) {
var header = tempObj[key][key + '_HEADER'];
if (header) {
var counter = content[key].length;
var tempItems = [];
for (var j = 0; j < content[key].length; j++) {
(function(j) {
var obj = {};
obj[srcServ.KEY_MAIN_HEADER] = tempObj[key][srcServ.KEY_DESC];
obj[srcServ.KEY_SUB_HEADER] = header[srcServ.KEY_DESC];
obj.id = j;
var itemVal = content[key][j][key + '_HEADER'];
var details = [];
var notes = [];
for (var item in itemVal) {
var val = null;
var found = false;
for (var i = 0; i < header.field.length; i++) {
if (header.field[i].name == item) {
val = header.field[i];
found = true;
break;
}
}
if (found && val != null) {
val[srcServ.KEY_DESC_VALUE] = itemVal[item];
details.push(val);
}
}
obj.details = details;
counter--;
if (counter == 0) {
$scope.showMoreDetails = true;
$scope.beList.beItems = tempItems;
console.log(JSON.stringify($scope.beList));
}
tempItems.push(obj)
})(j);
// $scope.beList.beItems.push(obj);
}
}
}
}
}
}
}
}
}

Change one letter of innerHTML

I have a for loop like this:
for(var i = 0; i < woord.length; i++) {
if(woord[i] === letter) {
goed = true;
woordContainer.innerHTML[i] = woord[i];
}
}
But the text in the woordContainer doesn't change on the page. I tried logging woord[i] to the console and it show the correct letter.
EDIT:
Let me share the complete code, so you can understand it better:
(it is a hangman game)
var store,
woord,
wrapper,
woordContainer,
letterInput,
gokButton,
pogingen,
pogingenText;
window.onload = function() {
store = new Persist.Store("galgje");
woord = store.get("woord");
pogingen = 10;
wrapper = document.getElementById("wrapper");
woordContainer = document.getElementById("woordContainer");
letterInput = document.getElementById("letterInput");
gokButton = document.getElementById("gokButton");
pogingenText = document.getElementById("pogingenText");
if (!woord) {
document.location.href = "./index.html";
}
for (var i = 0; i < woord.length; i++) {
woordContainer.innerHTML += ".";
}
wrapper.appendChild(woordContainer);
gokButton.onclick = function() {
var letter = letterInput.value.toLowerCase();
var goed = false;
if(letter) {
for(var i = 0; i < woord.length; i++) {
if(woord[i] === letter) {
goed = true;
woordContainer.innerHTML = woord[i];
}
}
if(!goed) {
pogingen--;
if(pogingen === 0) {
document.location.href = "./af.html";
}
pogingenText.innerHTML = "Pogingen: " + pogingen;
}
letterInput.value = "";
}
return false;
}
}
If you want to replace the character int woordContainer.innerHTML at index i, with the one in woord[i], you can do it like this:
if(woord[i] === letter) {
goed = true;
var temp = woordContainer.innerHTML
woordContainer.innerHTML = temp.substr(0, i) + woord[i] + temp.substr(i + woord[i].length);
}

Categories