Javascript: 'click' button doesn't work when pressed? - javascript

I'm in practical JS by Gordon Zhu (wwww.watchandcode.com). I don't understand why the buttons appear in the browser/UI/client side, but for some reason, when I go to click it the button makes an animation and does nothing. You know, kind of like one of those old, old software programs some companies and job boards use.
I'm getting an
VM3950:1 Uncaught ReferenceError: todoList is not defined
at :1:1
when defining todoList by displayTodos.addTodo('first');
var todoList = {
todos: [],
displayTodos: function() {
if (this.todos.length === 0) {
console.log('Your todo list is empty!');
} else {
console.log('My todos:');
for (var i = 0; i < this.todos.length; i++) {
if (this.todos[i].completed === true) {
console.log('(x)', this.todos[i].todoText);
} else {
console.log('( )', this.todos[i].todoText);
}
}
}
},
addTodo: function(todoText) {
this.todos.push({
todoText: todoText,
completed: false
});
this.displayTodos();
},
changeTodo: function(position, todoText) {
this.todos[position].todoText = todoText;
this.displayTodos();
},
deleteTodo: function(position) {
this.todos.splice(position, 1)
this.displayTodos();
},
toggleCompleted: function(position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
this.displayTodos();
},
toggleAll: function() {
var totalTodos = this.todos.length;
var completedTodos = 0;
for (var i = 0; i < totalTodos; i++) {
if (this.todos[i].completed === true) {
completedTodos++;
}
}
}
if (completedTodos === totalTodos) {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = false;
}
} else {
for (var i = 0; i < totalTodos; i++); {
this.todos[i].completed = true;
}
}
this.displayTodos();
}
};
var displayTodosButton = document.getElementById('displayTodosButton');
displayTodosButton.addEventListener('click', function() {
todoList.displayTodos();
});
<h1>Todo List</h1>
<button id = "displayTodosButton">Display Todos</button>
<button id = "toggleAllButton">Toggle All</button>

this keyword works different in Javascript compared in other languages, this is determined by how a function is called (runtime binding). In your handlers you may called todoList.displayTodos() or you can also update to use arrow functions, because in arrow functions, this retains the value of the enclosing lexical context's this see your code below:
var todoList = {
todos: [],
displayTodos: function() {
if (this.todos.length === 0) {
console.log('Your todo list is empty!');
} else {
console.log('My todos:');
for (var i = 0; i < this.todos.length; i++) {
if (this.todos[i].completed === true) {
console.log('(x)', this.todos[i].todoText);
} else {
console.log('( )', this.todos[i].todoText);
}
}
}
},
addTodo: function(todoText) {
this.todos.push({
todoText: todoText,
completed: false
});
this.displayTodos();
},
changeTodo: function(position, todoText) {
this.todos[position].todoText = todoText;
this.displayTodos();
},
deleteTodo: function(position) {
this.todos.splice(position, 1)
this.displayTodos();
},
toggleCompleted: function(position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
this.displayTodos();
},
toggleAll: function() {
var totalTodos = this.todos.length;
var completedTodos = 0;
for (var i = 0; i < totalTodos; i++) {
if (this.todos[i].completed === true) {
completedTodos++;
}
}
if (completedTodos === totalTodos) {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = false;
}
} else {
for (var i = 0; i < totalTodos; i++); {
this.todos[i].completed = true;
}
}
this.displayTodos();
}
};
var displayTodosButton = document.getElementById('displayTodosButton');
var toggleAllButton = document.getElementById('toggleAllButton');
displayTodosButton.addEventListener('click', () => {
this.todoList.displayTodos();
});
toggleAllButton.addEventListener('click', () => {
this.todoList.toggleAll();
});
<h1>Todo List</h1>
<button id = "displayTodosButton">Display Todos</button>
<button id = "toggleAllButton">Toggle All</button>

The error display is : Uncaught ReferenceError: todoList is not defined
Which means exactly that when referencing the todoList object from the this context it won't be defined because the this here is your html element not the window object thus if you want to refer to your object you have to remove the this keyword that's all (The javascript this keyword has a different behavior from many other languages).
Finally if you want to read more about the this behavior in java-script you can visit : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Related

Removing event listener from a tile of sudoku game

I`m trying to remove event listener from a tile that has been filled correctly on a sudoku game. But it is not working. After i fill the correct number on slot, i wish i wouldnt be able to click it again, but happens as the GIF show, it is erasing the grayed slots, meaning that removeEventListener is not working correctly. Any Help?
function qsa(selector) {
return document.querySelectorAll(selector);
}
function removeListenTiles() {
let tiles = qsa("tile");
for (let i = 0; i < tiles.length; i++) {
if (tiles[i].innerHTML.indexOf("table") == -1) {
if (tiles[i].textContent != "") {
tiles[i].removeEventListener("click", () => handleTile(tile[i), true);
}
}
}
}
function handleTile(tile) {
if (!disableSelect) {
if (tile.classList.contains("selected")) {
removeAllGrayedSelected();
updateMove();
removeSelected(tile);
selectedTile = null;
selectedNum = null;
} else {
removeAllGrayedSelected();
if (tile.innerHTML.indexOf("table") != -1) {
for (let j = 0; j < 81; j++) {
if (qsa(".tile")[j] !== tile) removeSelected(qsa(".tile")[j]);
}
tile.classList.add("selected");
selectedTile = tile;
updateSurround(tile);
updateMove();
}
}
}
}
function addListenTile(tile) {
tile.addEventListener("click", () => handleTile(tile), true);
}
Tried the currying method,and added tile.id to handlers array. Solved the problem.
const handlers = [];
const addListenTile = (tile) => {
tile.addEventListener("click", handlers[tile.id] = handleTile(tile), true);
};
const removeListenTile = (tile) => {
tile.removeEventListener("click", handlers[tile,id], true);
}
const handleTile = function (tile) {
return function onhandlerTile(event) {
console.log("OK1")
if (!disableSelect) {
if (tile.classList.contains("selected")) {
console.log("OK2");
removeAllGrayedSelected();
updateMove();
removeSelected(tile);
selectedTile = null;
selectedNum = null;
} else {
console.log("OK3");
removeAllGrayedSelected();
if (tile.innerHTML.indexOf("table") != -1) {
for (let j = 0; j < 81; j++) {
if (qsa(".tile")[j] !== tile) removeSelected(qsa(".tile")[j]);
}
tile.classList.add("selected");
selectedTile = tile;
updateSurround(tile);
updateMove();
}
}
}
};
};

update priority of queue in javascript

in hasValue class, why return is not working? when i try with console.log and alert, it worked.
want to implement function like priorityQueue.changePriority("Sheru", 1); changePriority class is not working.
commented code is code i tried to implement the changes i.e. i want to change the priority of existing item present in queue. Could anyone please help?
class QElement {
constructor(element, priority) {
this.element = element;
this.priority = priority;
}
}
class PriorityQueue {
constructor() {
this.items = [];
}
isEmpty() {
return this.items.length == 0;
}
add(element, priority) {
var qElement = new QElement(element, priority);
var contain = false;
for (var i = 0; i < this.items.length; i++) {
if (this.items[i].priority > qElement.priority) {
this.items.splice(i, 0, qElement);
contain = true;
break;
}
}
if (!contain) {
this.items.push(qElement);
}
}
peek() {
if (this.isEmpty())
return "No elements in Queue";
return this.items[0];
}
poll() {
if (this.isEmpty())
return "Underflow";
return this.items.shift();
}
/*changePriority(firstTerm, secondTerm)
{
let xxx = new QElement(firstTerm, secondTerm);
for (let i = 0; i < this.items.length; i++){
if (this.items[i].element === firstTerm){
this.items[i].priority = secondTerm;
this.items.splice(i, 0, xxx);
}
}
this.items.push(xxx);
}*/
hasValue(args) {
let status = false;
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].element === args) {
status = true;
}
}
console.log(status);
}
size() {
if (this.isEmpty())
return "Underflow";
return this.items.length;
}
printPQueue() {
var str = "";
for (var i = 0; i < this.items.length; i++)
str += this.items[i].element + " ";
return str;
}
}
var priorityQueue = new PriorityQueue();
console.log(priorityQueue.isEmpty());
console.log(priorityQueue.peek());
priorityQueue.add("Sumit", 2);
priorityQueue.add("Gourav", 1);
priorityQueue.add("Piyush", 1);
priorityQueue.add("Sunny", 2);
priorityQueue.add("Sheru", 3);
console.log(priorityQueue.printPQueue());
console.log(priorityQueue.peek().element);
console.log(priorityQueue.poll().element);
priorityQueue.add("Sunil", 2);
console.log(priorityQueue.size());
priorityQueue.hasValue('Sumit');
console.log(priorityQueue.printPQueue());
priorityQueue.changePriority("Sheru", 1);
console.log(priorityQueue.printPQueue());
You missing return keyword. This just works:
hasValue(args) {
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].element === args) {
return true;
}
}
return false;
}
I did not understand the idea how your changePriority function should work. Just find the element and move it up or down based on priority change:
swap(a, b) {
let tmp = this.items[a];
this.items[a] = this.items[b];
this.items[b] = tmp;
}
changePriority(firstTerm, secondTerm) {
let i = 0;
while (i < this.items.length) {
if (this.items[i].element === firstTerm) {
if (secondTerm < this.items[i].priority) {
// move up
this.items[i].priority = secondTerm;
while (i > 0 && this.items[i - 1].priority > secondTerm) {
this.swap(i - 1, i);
i--;
}
} else if (secondTerm > this.items[i].priority) {
// move down
this.items[i].priority = secondTerm;
while (i < this.items.length - 1 && this.items[i + 1].priority < secondTerm) {
this.swap(i + 1, i);
i++;
}
}
break;
}
i++;
}
}

Failed to compile - Syntax issue while iterating over object

I have a syntax issue that my code editor is unable to compile. I can't seem to know what the issue is exactly. Any help would be much appreciated. This is my code:
Object.values(otherStatus).map(function(value) {
for(var i=0; i < otherStatus.length; i++) {
for(value in otherStatus[i]) {
if (otherStatus[i][value].indexOf(Todos) !==-1) {
remainingStatus.push(otherStatus[i]);
} else if (otherStatus[i][value].indexOf(Onprogress) !==-1) {
remainingStatus.push(otherStatus[i]);
} else if (otherStatus[i][value].indexOf(Done) !==-1) {
remainingStatus.push(otherStatus[i]);
} else {
remainingStatus = []
}
}
}
)};
The iteration is within another function that looks like this:
addCardtoApp = event => {
event.preventDefault();
const card = {
taskName: this.taskName.current.value,
taskDescription: this.taskDescription.current.value,
taskPeriod: this.taskPeriod.current.value,
};
const cardStatus = this.taskStatus.current.value;
let otherStatus = {
otherStatus: this.taskStatus.current.textContent.replace(`${cardStatus}`, ''),
};
let remainingStatus = []
const Todos = 'Todos'
const Onprogress = 'Onprogress'
const Done = 'Done'
Object.values(otherStatus).map(function(value) {
for(var i=0; i < otherStatus.length; i++)
for(value in otherStatus[i]) {
if (otherStatus[i][value].indexOf(Todos) !==-1) {
remainingStatus.push(otherStatus[i]);
} else if (otherStatus[i][value].indexOf(Onprogress) !==-1) {
remainingStatus.push(otherStatus[i]);
} else if (otherStatus[i][value].indexOf(Done) !==-1) {
remainingStatus.push(otherStatus[i]);
} else {
remainingStatus = []
}
}
}
)};
console.log(remainingStatus)
this.props.addCard(card, cardStatus, otherStatus);
event.currentTarget.reset();
console.log(otherStatus);
};

Polymers this.$$(selector) (querySelector) for elements inside template repeat

I am simply trying to get an element inside of a template repeat by it's custom attribute. Here is the code:
<dom-module id="order-customize-sauces">
<link rel="stylesheet" href="order-customize-sauces.css"/>
<template>
<center>
<div style="width:100%; height:80px;">
<input class="customize-search" title="Filter The List By A Search Term" placeholder="Search List..." value="{{searchValue::input}}" type="text" on-keyup="filterSelections"></input>
<iron-icon icon="search" style="float:right;margin-right:5px;"></iron-icon>
</div>
<div style="height:300px;width:100%;">
<template id="saucesRepeat" is="dom-repeat" items="{{repeat}}" filter="{{filterSelections(searchValue)}}">
<paper-button data-sauce$="{{item.code}}" class$="button-{{item.SELECTED}}" raised on-click="buttonClick">{{item.name}}</paper-button>
</template>
</div>
</center>
<div style="margin-top:300px"> </div>
</template>
<script src="order-customize-sauces.js"></script>
As you can see I have "data-sauce" attribute that I want to select by. So here is what I have tried with no luck:
Try1:
var repeaters = document.querySelector('template[is="dom-repeat"]')
console.log(repeaters.querySelector("[data-sauce]"));
Try 2:
var items = Polymer.dom(this.$.saucesRepeat).node.__data__.items;
console.log(this.$$("[data-sauce]"));
Try 3:
this.$$("[data-sauce]");
Am I going about this wrong? How can I select an element inside of a template repeat? Also I am not using JQuery so if this could be javascript or polymer specific that would be great!
EDIT:
I have added the full JS code to help with the debugging.
The main function where this is the question is in the "changeButtonColor" function. This is called after a series of functions but it all starts with the "passCurrentItem" function. Also this element is a child of another element which is calling this elements function like the following:
this.$.allSaucesOptions.passCurrentItem(mynewarray);
The "allSaucesOptions" is the id given to the "order-customize-sauces" element.
Full JS Code:
Polymer({
is:"order-customize-sauces",
behaviors: [
Polymer.NeonSharedElementAnimatableBehavior
],
properties:{
animationConfig: {
value: function() {
return {
'entry':[
{
name:'fade-in-animation',
node:this
}],
'exit':[
{
name:'fade-out-animation',
node:this
}]
}
}
},
},
//--------------------------------------------------
ready:function(){
this.repeat = [];
this.currentItem = [];
this.originalArray = [];
},
//--------------------------------------------------
passCurrentList:function(list){
this.originalArray = list;
},
//--------------------------------------------------
passCurrentItem:function(array) {
var i;
this.currentItem.length = 0;
for(var i=0; i < array.length; i++) {
this.currentItem.push({name: array[i].name, code: array[i].code, price: array[i].price, SELECTED: array[i].SELECTED});
}
this.resetRepeatArray(); //everything above works!!
this.updateArray(); //update visually
},
//--------------------------------------------------
resetRepeatArray:function(){ //testing working!!!!
var i;
for(i=0; i < this.originalArray.length; i++) {
this.originalArray[i].SELECTED = 0;
}
this.repeat = this.originalArray;
},
//--------------------------------------------------
updateArray:function() {
var i;
//for(i =0; i < this.repeat.length; i++) {
//this.repeat[i] = {name: this.repeat[i].name, code: this.repeat[i].code, price: this.repeat[i].price, SELECTED: this.repeat[i].SELECTED};
//this.changeButtonColor(0,this.repeat[i].code);
//}
for(i = 0; i < this.currentItem.length; i++) {
//index = this.repeat.map(function(d) { return d['code']; }).indexOf(this.currentItem[i].code);
//this.set("repeat.index",{name: this.currentItem[i].name, code: this.currentItem[i].code,
// price: this.currentItem[i].price, SELECTED: this.currentItem[i].SELECTED});
console.log("set color "+this.currentItem[i].name);
this.changeButtonColor(this.currentItem[i].SELECTED,this.currentItem[i].code); //this isn't working
}
},
//--------------------------------------------------
changeButtonColor:function(number, id) {
var defaultClassValues = " style-scope order-customize-sauces x-scope paper-button-0";
var defaultClass ="button-";
// var items = Polymer.dom(this.$.saucesRepeat).node.__data__.items;
// console.log(this.$$("[data-sauce]"));
// var repeaters = document.querySelector('template[is="dom-repeat"]')
var element = this.$$("[data-sauce]");
console.log(element);
// for(var i=0; i < items.length; i++) {
// if(items[i].code === id) {
// Polymer.dom(this.$.saucesRepeat).node.__data__.items[i].SELECTED = number;
// }
// }
// var element = this.getElementByAttributeValue("data-sauce",id);
// if(element != null){
// element.className = defaultClass+number+defaultClassValues;
// console.log(element.className);
// }
},
//--------------------------------------------------
getElementByAttributeValue: function(attribute, value){
var matchingElements = [];
var allElements = document.getElementsByTagName('*');
for (var i = 0, n = allElements.length; i < n; i++) {
if (allElements[i].getAttribute(attribute) === value){
// Element exists with attribute. Add to array.
matchingElements.push(allElements[i]);
}
}
return matchingElements[0];
},
//--------------------------------------------------
isNumber:function(selected, number) {
selected = (selected == null)?0:selected;
if(selected == number) {
return false;
}
else {
return true;
}
},
//--------------------------------------------------
removeFromArray:function(itemName) {
var index, i;
for(i = 0; i < this.currentItem.length; i++) {
if(this.currentItem[i].name == itemName || this.currentItem[i].code == itemName) {
index = i;
break;
}
}
if(index > -1) {
this.currentItem.splice(index, 1);
}
},
//--------------------------------------------------
buttonClick:function(e){
var item = e.model.__data__.item;
item.SELECTED = this.setSelectedNumber(item.SELECTED);
var number = item.SELECTED;
if(number > 3) {//original item
this.currentItem[0] = {name: item.name, code: item.code, price: item.price, SELECTED: 4};//change original item to new values
if(this.currentItem[1] != null) { //is there another item selected?
this.removeFromArray(this.currentItem[1].code); //make original item the only thing in array
}
}
else if(number < 4) {//not original item
this.currentItem[0] = {name: this.currentItem[0].name, code: this.currentItem[0].code, price: this.currentItem[0].price, SELECTED: 4};//unselect original item -- don't remove from array
if(this.currentItem[1] == null) { //is this the first time selecting a new item?
this.currentItem.push({name: item.name, code: item.code, price: item.price, SELECTED: item.SELECTED}); //add item to a new slot in array
}
else{
this.currentItem[1] = {name: item.name, code: item.code, price: item.price, SELECTED: item.SELECTED}; //Update array slot with new information
}
}
this.updateArray();
},
//--------------------------------------------------
setSelectedNumber:function(number) {
if(number < 8 && number > 3) {
number += 1;
if(number > 7) {
number = 4;
}
}
if(number < 4 || number == null) {
number = (number == null)?0:number;
number += 1;
if(number > 3) {
number = 0;
}
}
return number;
},
//---------------------------------------------------
filterSelections:function(search) {
this.resetSauceArray();
this.changeButtonColor(this.currentItem[0].SELECTED, this.currentItem[0].code);
if(this.currentItem[1] != null){
this.changeButtonColor(this.currentItem[1].SELECTED, this.currentItem[1].code);
}
return function(item){
var string;
if (!search) return true;
if (!item) return false;
search = search.toUpperCase();
if(item.name && ~item.name.toUpperCase().indexOf(search)) {
return true;
}
else {
return false;
}
}
},
});

Tree building infinite recursion detection

I am working on JQuery mechanism that is building tree, it has to be as fast as possible. Volume of data is quite large so master record column is used to be able to 'grab' all relevant nodes in one select from webSQL db.
Whole mechanism but one part is done, when assembling tree it must check that there is no infinite recursion being created. What mechanism does at the moment if Record A is Master and Parent of record B, and Record B is Master and Parent of record A then structure like A.Children[0] = B and B.Children[0] = A is being built. It all would work fine, but it has do be knockout.js bound and displayed as expandable list to users, which results in overflow when trying to display the tree.
Requirement is to detect such loops and do not create tree relationships.
Mechanism that would check if item is already in the tree I came up is:
function InTree(master, item) {
return $.inArray(item, $.map(master, function recurs(n) {
return ($.isArray(n) ? $.map(n, recurs) : n);
})) != -1;
}
if(!InTree(tree, record))
{
//attach
} else {
// get next record
}
Is there anything faster than InTree() function that would get me if item is in the tree?
Whole tree building algorithm is below (not that I think it is relevant but rather to avoid the comments 'show the code')
$(document).on('OnPreQuery', onTheMove.PageDataRoles, function (e, options) {
var isChildAttachmentQueued = true;
var knockoutContextName = options.knockoutContextName;
if (TreeEnabled(knockoutContextName)) {
var isModelReadyToAttachChildren = function () {
var isReady = false;
if (PageObj[knockoutContextName] != undefined) {
isReady = (PageObj[knockoutContextName]().length > 0) && isChildAttachmentQueued;
}
return isReady;
};
var businessComponent = eval(knockoutContextName);
var treeSettings = businessComponent.Tree;
treeSettings.knockoutContextName = knockoutContextName;
$(businessComponent).on('OnPreUIUpdate', function (e, options) {
if (isModelReadyToAttachChildren()) {
getChildrenForMasterRecordList({
parentTable: businessComponent.primaryTableName,
knockoutContextName: treeSettings.knockoutContextName,
parentIdColumn: treeSettings.ParentIdColumn,
masterIdColumn: treeSettings.MasterIdColumn
});
isChildAttachmentQueued = false;
}
});
}
});
function TreeEnabled(knockoutContextName) {
var isTreeEnabled = false;
try {
eval(knockoutContextName);
} catch (e) {
return isTreeEnabled;
}
var treeSettings = eval(knockoutContextName).Tree;
if (treeSettings && treeSettings.IncludeChildren) {
isTreeEnabled = true;
}
return isTreeEnabled;
}
function ComposeRecordsToTreeStructure(results, tableArray, columnArray, options) {
if (results.rows.length > 0) {
if (options.parentLayerIdList == undefined) {
options.parentLayerIdList = options.masterIdList;
}
if (options.orphans == undefined) {
options.orphans = [];
}
var knockoutContextName = options.knockoutContextName;
var childRecordIdArray = [];
if (options.runningOnOrphans) {
if (options.orphans.length > 0) {
for (var j = 0; j < options.orphans.length; j++) {
var rowRecord = options.orphans[j];
var rowRecordParentId = rowRecord[options.parentIdColumn];
var result = EstablishParentChildConnectionOnAlreadyProcessedNodes(rowRecord, rowRecordParentId, options.parentLayerIdList, knockoutContextName, childRecordIdArray, options);
if (result.hasEstablishedConnection) {
childRecordIdArray = result.childRecordIdArray;
}
}
options.orphans = $.grep(options.orphans, function (item) {
return $.inArray(item['Id'], childRecordIdArray) == -1;
});
}
} else {
for (var i = 0; i < results.rows.length; i++) {
var rowRecord = results.rows.item(i);
var rowRecordParentId = rowRecord[options.parentIdColumn];
if (rowRecord[options.parentIdColumn] == '' || rowRecord[options.masterIdColumn] == '' || rowRecord[options.masterIdColumn] == rowRecord['Id']) {
rowRecord.isInvalid = true;
} else if ($.inArray(rowRecord['Id'], options.masterIdList) != -1) {
masterRecordClone = $.grep(PageObj[knockoutContextName](), function (item) { return item.Fields.Id() == rowRecord['Id'] })[0];
if (masterRecordClone != undefined && masterRecordClone.Children) {
rowRecord.Children = masterRecordClone.Children;
}
}
if (rowRecord.isInvalid == true) {
if (rowRecord[options.masterIdColumn] != rowRecord['Id']) {
var result = EstablishParentChildConnection(rowRecord, rowRecord[options.masterIdColumn], options.parentLayerIdList, knockoutContextName, childRecordIdArray, options);
if (result.hasEstablishedConnection) {
childRecordIdArray = result.childRecordIdArray;
EstablishParentChildConnectionOnAlreadyProcessedNodes(rowRecord, rowRecordParentId, options.parentLayerIdList, knockoutContextName, childRecordIdArray, options);
}
}
} else {
var result = EstablishParentChildConnectionOnAlreadyProcessedNodes(rowRecord, rowRecordParentId, options.parentLayerIdList, knockoutContextName, childRecordIdArray, options);
if (result.hasEstablishedConnection) {
childRecordIdArray = result.childRecordIdArray;
} else {
var recordObject = AddIsExpandedProperty(rowRecord);
options.orphans.push(recordObject);
options.runningOnOrphans = true;
}
}
}
}
if (options.orphans.length > 0 && childRecordIdArray.length > 0) {
options.parentLayerIdList = childRecordIdArray;
ComposeRecordsToTreeStructure(results, tableArray, columnArray, options);
}
}
onTheMove.seleniumHelper.markPageAsLoaded();
}
function EstablishParentChildConnectionOnAlreadyProcessedNodes(rowRecord, rowRecordParentId, parentLayerIdList, knockoutContextName, childRecordIdArray, options) {
var result = EstablishParentChildConnection(rowRecord, rowRecordParentId, parentLayerIdList, knockoutContextName, childRecordIdArray);
if (result.hasEstablishedConnection) {
childRecordIdArray = result.childRecordIdArray;
} else {
var result = EstablishParentChildConnection(rowRecord, rowRecordParentId, childRecordIdArray, knockoutContextName, childRecordIdArray);
if (result.hasEstablishedConnection) {
childRecordIdArray = result.childRecordIdArray;
} else {
var matchingOrphans = $.grep(options.orphans, function (item) {
return item['Id'] == rowRecordParentId;
});
if (matchingOrphans.length > 0) {
AttachPassedChildRecord(rowRecord, matchingOrphans);
var result = {
hasEstablishedConnection: true
};
}
}
}
return {
childRecordIdArray: childRecordIdArray,
hasEstablishedConnection: result.hasEstablishedConnection
};
}
function EstablishParentChildConnection(rowRecord, rowRecordParentId, parentLayerIdList, knockoutContextName, childRecordIdArray) {
var hasEstablishedConnection = false;
var parentPosition = $.inArray(rowRecordParentId, parentLayerIdList);
if (parentPosition != -1) {
AttachChildRecordsToParents(rowRecord, parentLayerIdList[parentPosition], knockoutContextName);
childRecordIdArray = AddChildRecordsToNextParentList(rowRecord, childRecordIdArray);
childRecordIdArray.push(rowRecord['Id']);
hasEstablishedConnection = true;
}
return {
childRecordIdArray: childRecordIdArray,
hasEstablishedConnection: hasEstablishedConnection
};
}
function AddChildRecordsToNextParentList(childRecord, childRecordIdArray) {
if (childRecord.Children != undefined) {
for (var i = 0; i < childRecord.Children.length; i++) {
childRecordIdArray.push(childRecord.Children[i]['Id']);
if (childRecord.Children[i].Children != undefined) {
AddChildRecordsToNextParentList(childRecord.Children[i], childRecordIdArray);
}
}
}
return childRecordIdArray;
}
function RowsToListDataStructure(results) {
var array = [];
for (var i = 0; i < results.rows.length; i++) {
array.push(results.rows.item(i));
}
return array;
}
function AttachChildRecordsToParents(recordRow, id, knockoutContextName) {
var childTreeOptions = {
id: id,
knockoutContextName: knockoutContextName,
results: []
};
findObjectsInChildTreeById(childTreeOptions);
if (childTreeOptions.results.length > 0) {
AttachPassedChildRecord(recordRow, childTreeOptions.results);
}
}
function AttachPassedChildRecord(recordObject, pageObjParentResults) {
for (var i = 0; i < pageObjParentResults.length; i++) {
if (pageObjParentResults[i].Children == undefined) {
pageObjParentResults[i].Children = [];
}
if ($.grep(pageObjParentResults[i].Children, function (children) {
return children['Id'] == recordObject['Id'];
}).length == 0) {
recordObject = AddIsExpandedProperty(recordObject);
pageObjParentResults[i].Children.push(recordObject);
}
}
}
function AddIsExpandedProperty(recordObject) {
recordObject.IsExpanded = ko.observable(false);
return recordObject;
}
function findObjectsInChildTreeById(options) {
if (options.item == undefined) {
if (typeof PageObj[options.knockoutContextName] != 'undefined') {
for (var item in PageObj[options.knockoutContextName]()) {
findObjectsInChildTreeById({
item: PageObj[options.knockoutContextName]()[item],
id: options.id,
results: options.results
});
}
}
} else {
if (typeof options.item.Fields != 'undefined') {
if (options.item.Fields['Id']() == options.id)
options.results.push(options.item);
} else {
if (options.item['Id'] == options.id)
options.results.push(options.item);
}
if (options.item.Children != undefined) {
for (var item in options.item.Children) {
findObjectsInChildTreeById({
item: options.item.Children[item],
id: options.id,
results: options.results
});
}
}
}
}
function getChildrenForMasterRecordList(options) {
var parentTable = options.parentTable,
masterIdColumn = options.masterIdColumn,
parentIdColumn = options.parentIdColumn,
knockoutContextName = options.knockoutContextName,
masterIds = getParentIdsAndMastersOfParentsFromPageObj(knockoutContextName, masterIdColumn);
for (var item in PageObj[options.knockoutContextName]()) {
AddIsExpandedProperty(PageObj[knockoutContextName]()[item]);
}
var dbManager = new OnTheMoveDatabaseManager();
dbManager.queryDatabase({
statement: {
Tables: [{
Alias: parentTable,
JoinSpec: null,
JoinType: "",
Name: parentTable
}, {
Alias: "Record",
JoinSpec: "Record.Id = " + parentTable + ".Id",
JoinType: "INNER",
Name: "Record"
}],
WhereClause: parentTable + "." + masterIdColumn + " IN ('" + masterIds.join("','") + "') AND Record.RecordType ='" + parentTable + "'",
SelectFields: [{
IsAggregate: false,
Name: "*"
}],
DisablePaging: true,
OrderClause: "Record.Id"
},
knockoutContextName: knockoutContextName,
isObservable: false,
masterIdColumn: masterIdColumn,
masterIdList: masterIds,
parentIdColumn: parentIdColumn,
parentTable: options.parentTable,
success: function (results, tableArray, columnArray, options) {
ComposeRecordsToTreeStructure(results, tableArray, columnArray, options);
}
});
}
function getParentIdsAndMastersOfParentsFromPageObj(knockoutContextName, masterColumnName) {
var list = [];
if (typeof PageObj[knockoutContextName] != 'undefined') {
for (var item in PageObj[knockoutContextName]()) {
if ($.inArray(PageObj[knockoutContextName]()[item].Fields['Id'](), list) == -1) {
list.push(PageObj[knockoutContextName]()[item].Fields['Id']());
}
if (PageObj[knockoutContextName]()[item].Fields[masterColumnName]() != '' && $.inArray(PageObj[knockoutContextName]()[item].Fields[masterColumnName](), list) == -1) {
list.push(PageObj[knockoutContextName]()[item].Fields[masterColumnName]());
}
}
}
return list
}
function InTree(master, item) {
return $.inArray(item, $.map(master, function recurs(n) {
return ($.isArray(n) ? $.map(n, recurs) : n);
})) != -1;
}
it depends on your circumstances. if you're able to run code on add/creation of the tree you may simply create a node id array and do a check like
if(allNodes[searchKey])
//etc
This is a very specific solution of course but technically it'd be as fast as it could possibly be.

Categories

Resources