I have created a tree using Treepanel in Extjs. The following is the code snippet which is used which to traverse the node using drag and drop
beforenodedrop:function(dropEvent){
try {
targetNode = dropEvent.target;
sourceNode = dropEvent.dropNode;
sourceNode = getDeepAllChildNodes(sourceNode);
treeTarget = sourceNode.getOwnerTree().id;
if (treeTarget == 'tree' && sourceNode.attributes.lvl > 0){
changeAlignTrees = true;
if (sourceNode.childNodes != null){
var targetFather = {};
var node = sourceNode;
if(targetNode.id==-2){
targetFather = targetNode;
}else{
targetFather = targetNode.parentNode;
}
while(sourceNode.hasChildNodes() == true){
node = node.firstChild;
if (node.hasChildNodes() == false){
node = node.parentNode;
targetFather.appendChild(node.firstChild);
if(node.hasChildNodes() == false){
node = node.parentNode;
}
}
}
}
if(targetNode.id==-2){
dropEvent.point = 'append';
}else{
dropEvent.point = 'below';
targetNode.leaf='true';
}
Ext.Ajax.request({
url: "testURL",
params: {
option: 'alUnit',
unitNum: sourceNode.id,
parentUnitNum: '-1'
},
scriptTag: true,
success: function(response, options){
}
});
}else{
dropEvent.cancel=true;
}
}catch (e) {
logException("Exception: " + e.description);
}
}
This is Async Tree Node, if i do not expand the nodes then the following line node = node.firstChild; returns null. I have one more function to get all the child nodes, the following is the code snippet
getDeepAllChildNodes = function(node){
var allNodes = new Array();
if(!Ext.value(node,false)){
return [];
}
if(!node.hasChildNodes()){
return node;
}else{
allNodes.push(node);
node.eachChild(function(Mynode){allNodes = allNodes.concat(getDeepAllChildNodes(Mynode));});
}
return allNodes;
};
When executed the line !node.hasChildNodes() the following error "Object doesn't support property or method 'hasChildNodes'"
How can i achieve traversing all child nodes in treepanel without expanding.
Related
I am trying to do a Q20-ish game, the problem is when I try to invoque a class in Javascript. See the extract below.
var TreeQuestions = require('./Tree.js');
var node = {
value: null,
id: null,
ifAnswer:false,
No: null,
Yes: null};
var counter = 0;
node.value= "Root";
node.id=counter;
node.No=null;
nodeYes=null;
TreeQuestions.addYes(node.value,node.id,null);
counter = counter + 1 ;
...
On TreeQuestions.addYes an error comes up telling me that the method is undefined.
See my Tree.js file below for further reference.
var Tree = {
//If you need to add the root node, just specify the third parameter as null on any of addYes or addNo function;
addYes: function(value,id,CurrentNode){
//create a new item object, place data in
var node = {
value: value,
id: id,
ifAnswer:false,
No: null,
Yes: null};
//special case: no items in the tree yet
if (this._root === null){
this._root = node;
} else {
CurrentNode.Yes = node;
}
},
addNo: function(value,id,CurrentNode){
//create a new item object, place data in
var node = {
value: value,
id: id,
ifAnswer:false,
No: null,
Yes: null};
//special case: no items in the tree yet
if (this._root === null){
this._root = node;
} else {
CurrentNode.No= node;
}
},
getNo: function(CurrentNode){
if(CurrentNode.No != null){
return CurrentNode.No;
}else{
return null;
}
},
getYes: function(CurrentNode){
if(CurrentNode.Yes != null){
return CurrentNode.Yes;
} else{
return null;
}
},
gameBegin: function(){
currentNode = this._root;
var response = Yes;
var win = false;
while(currentNode != null && win==false){
if( response=="yes"){
currentNode = This.getYes(this.currentNode);
console.log(currentNode.value+" "+ currentNode.value+" "+currentNode.ifAnswer.toString())
} else if(response=="no"){
currentNode = This.getNo(this.currentNode);
console.log(currentNode.value+" "+ currentNode.value+" "+currentNode.ifAnswer.toString())
}
}
}
};
var node = {
value: null,
id: null,
ifAnswer:false,
No: null,
Yes: null
};
function Tree() {
this._root = null;
}
Which seem to be the error? Am I taking a wrong approach to this problem?
You have:
var Tree = {
And then at the end of Tree.js you have:
function Tree() {
this._root = null;
}
It means you have just overridden your Tree object with a function definition.
Also you need to export the literal which is currently assigned to var Tree:
module.exports = {
addYes:...
}
getNo: function(CurrentNode){
if(CurrentNode.No != null){
return CurrentNode.No;
} else{
return null;
}
},`getNo: function(CurrentNode){
if(CurrentNode.No != null){
return CurrentNode.No;
} else {
return null;
}
},
I'm trying to determine if an element is a descendant of another elect that has a specific attribute. So far, I have no issue when the value is true, but I get TypeError: undefined is not a function (evaluating 'node.hasAttribute(attribute)') when hasAttribute is false. Any ideas?
document.body.addEventListener('touchmove', function(event) { stopScroll(event); });
var stopScroll = function(event) {
var target = event.target;
var parent = target.parentNode;
if (isDescendantOf.attribute('data-scroll', target)) {
} else {
event.preventDefault();
}
};
var isDescendantOf = {};
isDescendantOf.parent = function(parent, child) {
var node = child.parentNode;
while (typeof node !== 'undefined') {
if (node == parent) {
return true;
}
node = node.parentNode;
}
return false;
};
isDescendantOf.tag = function(tag, child) {
var node = child.parentNode;
while (typeof node !== 'undefined') {
if (node.tagName == tag) {
return true;
}
node = node.parentNode;
}
return false;
};
isDescendantOf.attribute = function(attribute, child) {
var node = child.parentNode;
while (node !== null) {
console.log(typeof node);
if (node.hasAttribute(attribute) === true) {
return true;
}
node = node.parentNode;
}
return false;
};
Here's the fiddle, though it acts even weirder for some reason: http://jsfiddle.net/x95tgmkn/
Your loop goes from the child.parentNode up to the document, and on each node it uses the hasAttribute method of the Element interface. However, Documents are plain Nodes that do not implement this interface.
Change your condition to
while (node != null && node.nodeType == 1)
or node.nodeType != 9 or typeof node.hasAttribute == "function".
I'm new to nodeJS javascript and I have a simple problem here.
I have a Binary Search Tree (BST) in javascript. Each Node has a value, and a count. We're inserting words into the BST such that each Node represents a word. Upon insertion, if the word is already in the BST, we want to increase the count of that word, where count is a property on the Node.
My problem comes when I want to display the Nodes and their counts. Displaying the counts is not working correctly. That is, the BST.prototype.showWords = function (node) is not correct.
Thank you for your help and insight!!!
files:
bstnode.js - the 'node class'
BST.js - the Binary Search Tree Class
wordCount.js - reads in a text file, splits on spaces to get words, and creates nodes. I want each node to represent a word, and if that word appears multiple times, count++ on that node each time.
// wordCount.js
var BST = require('./bst.js');
var fs = require('fs');
var countNodes = require('./countNodes.js');
// THIS RIGHT HERE DOES NOT WORK CORRECTLY.
BST.prototype.showWords = function (node) {
if (node !== null) {
this.inOrder(node.left);
console.log(node.showCount());
this.inOrder(node.right);
}
};
// get the file, and get it into an array of string-words
var filePath = './simpleTest.txt';
var contents = fs.readFileSync(filePath).toString();
var stringArr = contents.split(' ');
var myBST = new BST();
for (var i=0; i<stringArr.length; i++){
var word = stringArr[i].trim();
var aNode = myBST.find(word);
console.log(aNode);
if ( aNode !== null ) { // then word exists in BST already,
aNode.count++; // node count ++ on that one
}
else { // then word dne in BST, so add it now!
myBST.insert(word);
}
}
myBST.showWords(myBST.root);
// bstnode.js
'use strict';
var Node = function (data, left, right) {
this.data = data;
this.count = 1;
this.left = left;
this.right = right;
};
Node.prototype.show = function () {
return this.data;
};
Node.prototype.show2 = function () {
return (this.data + ' ' + this.count);
};
module.exports = Node;
'use strict';
// bst.js - has the BST CTor function, and requires the bstnode in
var Node = require('./bstnode');
// BST CTor function
var BST = function() { // Binary Search Tree class
this.root = null;
};
BST.prototype.insert = function (data) {
var n = new Node(data, null, null);
if (this.root === null) {
this.root = n;
} else {
var current = this.root;
var parent;
while (true) {
parent = current;
if (data < current.data) {
current = current.left;
if (current === null) {
parent.left = n;
break;
}
} else {
current = current.right;
if (current === null) {
parent.right = n;
break;
}
}
}
}
};
// inOrder: log VALUES in order starting from node param
BST.prototype.inOrder = function (node) {
if (node !== null) {
this.inOrder(node.left);
console.log(node.show() + " ");
this.inOrder(node.right);
}
};
BST.prototype.find = function (data) {
var current = this.root;
while (current && current.data !== data) {
if (data < current.data) {
current = current.left;
} else {
current = current.right;
}
}
return current;
};
module.exports = BST;
a friend helped me out, here's the soln
// THIS RIGHT HERE -- - --
// That's because it should call itself recursively, not the inOrder function!
BST.prototype.showWords = function (node) {
if (node !== null) {
this.showWords(node.left);
console.log(node.showCount());
this.showWords(node.right);
}
};
I've got a bit paranoid lately about the solutions out there that deal with the task by using regular expressions to 'sanitize' html strings. They largely depend on how 'bullet-proof' given regex is. So, I came up with this snippet and hope to get some feedback about it from community. Thanks.
//
// #notags
String.prototype.notags = (function (doc) {
var mkel = doc.createElement.bind(doc);
var hasown = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
// #textlike-nodes
var textlike = {
12 : "NOTATION_NODE",
3 : "TEXT_NODE",
4 : "CDATA_SECTION_NODE",
5 : "ENTITY_REFERENCE_NODE",
6 : "ENTITY_NODE",
7 : "PROCESSING_INSTRUCTION_NODE",
8 : "COMMENT_NODE"
};
// #_notags
// main function
var _notags = function (tagedstring) {
var div;
var istxt = istextnode;
var nodes;
var nodetxt = getxt;
var res;
div = mkel('div');
div.innerHTML = (''+ tagedstring);
// get the div's descendants
// and read their text content
// until all of its childern are plain
// text nodes...
nodes = descendants(div);
while (!nodes.every(istxt)) {
div.innerHTML = nodetxt(div);
nodes = descendants(div);
}
res = div.innerHTML;
// get rid of temporary div
// prevents mem. leaks
div.innerHTML = '';
delete div;
return res;
};
// #save
// String#notags
return function () {
return _notags(this);
};
////////////////
////// #helpers
// #istextnode
function istextnode (node) {
return !(3 - node.nodeType);
}
// #descendants
function descendants (startnode, _nodels) {
_nodels || (_nodels = []);
var node = startnode.firstChild;
while (node) {
_nodels.push(node);
descendants(node, _nodels);
node = node.nextSibling;
}
return _nodels;
}
// #getxt
// loop each node's descendant
// and fetch it' text content
function getxt (node) {
var _ = {
str: '',
txt: textlike
};
descendants(node)
.forEach(getnodetext, _);
return _.str;
}
// #getnodetext
function getnodetext (node) {
//this: {str, txt}
if (hasown(this.txt, node.nodeType))
this.str += (node.data || node.textContent || node.nodeValue);
}
})(document);
// /eof
I'm making a code that removes a videoplayer from the page and then places it back when needed (even if the element doesn't have an id).
I'm finding issues with IE7
Here is my code:
var weboElem, weboElemPar, weboElemIndex, weboStored;
function weboRemoveVideoplayer(vpId){
weboElem = document.getElementById(vpId);
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
var child = weboElem;
while( (child = child.previousSibling) != null )
weboElemIndex++;
weboElemPar.removeChild(weboElem);
return true;
}
function weboPlaceVideoplayerBack(){
if(weboElemPar.insertBefore !== undefined && weboElemPar.childNodes !== undefined)
{
weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
return true;
}
return false;
}
var result = document.evaluate(
'//*/param[contains(#value, "autoplay=1")]/..', // XPath expression
document, // context node
null, // namespace resolver
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
} else document.getElementById('info').innerHTML = "not found";
(Note that document.evaluate WORKS because I imported javascript-xpath library)
On IE7 if the XPath finds an IFRAME there are no problems and it works but if it finds an OBJECT does nothing and stops at weboElem = document.getElementById(vpId); as if it didn't find the id.
I tried modifying the code like this:
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
node.parentNode.removeChild(node);
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
if(node.nodeName.toLowerCase() == "object") weboStored = node;
else weboStored = null;
} else document.getElementById('info').innerHTML = "not found";
and it works, the videoplayer disappears at page load. I want to use the function though, so I edited everything like this (storing the node into a global var that later I get in the weboRemoveVideoplayer function):
var weboElem, weboElemPar, weboElemIndex, weboStored;
function weboRemoveVideoplayer(vpId){
if(!weboStored) weboElem = document.getElementById(vpId);
else weboElem = weboStored;
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
var child = weboElem;
while( (child = child.previousSibling) != null )
weboElemIndex++;
weboElemPar.removeChild(weboElem);
alert("5");
return true;
}
function weboPlaceVideoplayerBack(){
if(weboElemPar.insertBefore !== undefined && weboElemPar.childNodes !== undefined)
{
weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
return true;
}
return false;
}
// bind XPath methods to document and window objects
// NOTE: This will overwrite native XPath implementation if it exists
//XPathJS.bindDomLevel3XPath(); //solo per xpathJs
var result = document.evaluate(
'//*/param[contains(#value, "autoplay=1")]/..', // XPath expression
document, // context node
null, // namespace resolver
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
node.parentNode.removeChild(node);
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
if(node.nodeName.toLowerCase() == "object") weboStored = node;
else weboStored = null;
} else document.getElementById('info').innerHTML = "not found";
This way the code blocks itself when trying to retrieve the parent node.
Could someone suggest me what to do here?
PS: with chrome and firefox the code works perfectly in the first version I posted.
Fixed it!
I solved the issue by wrapping the OBJECT inside a div with an id of my choice which I can retrieve whenever I want. I do this in the resolveXpath function.
Here the code:
var weboElem, weboElemPar, ieObject = false;
var weboElemIndex = 0;
function weboRemoveVideoplayer(vpId){
var child;
if(!ieObject) weboElem = document.getElementById(vpId);
else weboElem = document.getElementById('my_usage');
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
child = weboElem;
while( (child = child.previousSibling) != null ) weboElemIndex++;
if(typeof weboElemPar.removeChild !== 'undefined') weboElemPar.removeChild(weboElem);
else return false;
return true;
}
function weboPlaceVideoplayerBack(){
if(typeof weboElemPar.insertBefore !== 'undefined' && typeof weboElemPar.childNodes !== 'undefined' && typeof weboElemPar.appendChild !== 'undefined'){
if(weboElemPar.childNodes.length > 0 && weboElemIndex < weboElemPar.childNodes.length) weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
else weboElemPar.appendChild(weboElem);
return true;
}
return false;
}
function resolveXpath(path)
{
//XPathJS.bindDomLevel3XPath(); //solo per xpathJs
var result = document.evaluate(path,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
if(result.snapshotLength > 0){
var child, node = result.snapshotItem(0);
if(node.nodeName.toLowerCase() == 'object'){
ieObject = true;
child = node;
while( (child = child.previousSibling) != null ) weboElemIndex++;
var div = document.createElement('div');
div.id = 'my_usage';
if(typeof node.parentNode.insertBefore !== 'undefined' && typeof node.parentNode.childNodes !== 'undefined' && typeof node.parentNode.appendChild !== 'undefined'){
if(node.parentNode.childNodes.length > 0 && weboElemIndex < node.parentNode.childNodes.length) node.parentNode.insertBefore(div,node.parentNode.childNodes[weboElemIndex]);
else node.parentNode.appendChild(div);
div.appendChild(node);
} else return false;
} else node.id = 'my_usage';
return true;
} else return false;
}
resolveXpath('//*/param[contains(#src, "autoplay=1")]/..');