Tree building infinite recursion detection - javascript

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.

Related

Get element of chaining in jquery to use in $.fn.{FunctionName}

I am creating a pluging based in Jquery and Bootrap (Laste Versions), that is call by this method/code:
$(document).find('.calendar-plug-bs').each(function(index, el) {
//$(this).plgCalendar("destroy"); Testing for destroy if exist...
$(this).plgCalendar();
})
it work with and element like this:
<div class="form-group row">
<div class="calendar-plug-bs"></div>
</div>
and this script/plugin starts as follows ...
(function($) {
$.fn.plgCalendar = function(param) {
return window.plgCalendar(param);
};
}(jQuery));
But the problem is that i need retrive node that call the initial function...
|------|
$(this).plgCalendar();
to add a table inside it ...
function plgCalendar(param = null) {
var r = null;
if (param !== null) {
if (typeof param.func !== 'undefined') {
if (param.func === "destroy") {
} else if (param.func === "getValue") {
}
} else {
console.log('%cMSG: (func) not Set', 'color: #bada55');
}
} else {
/*****WORKING ON THIS***/
var target = $(this);
console.log(target);
if (target.is("div")) {
var id = window.BuildRandID();
var $tableObject = $('<table/>', {
'class': 'bigger',
'id': id
});
$(target).append($tableObject);
return id;
} else {
window.alert("calendar-plug-bs must be a div");
}
/*****WORKING ON THIS***/
}
return r;
}
the fail is that var taget not is a div... and i dont know how to retrive...
resolve by this way:
(function($) {
$.fn.plgCalendar = function(param = null) {
param = window.plgCalendarParam(param);
param['this'] = $(this);
return window.plgCalendar(param);
};
}(jQuery));
function plgCalendarParam(param) {
if (param == null) {
param = [];
}
return param;
}
function plgCalendar(param) {
var r = null;
if (typeof param.func !== 'undefined') {
if (param.func === "destroy") {
} else if (param.func === "getValue") {
}
} else {
/*****WORKING ON THIS***/
var target = param['this'];
if (target.is("div")) {
var id = 'plgCalendar_' + window.BuildRandID();
var $tableObject = $('<table/>', {
'class': 'bigger',
'id': id
});
$(target).append($tableObject);
r = { 'id': id, 'init': true };
} else {
window.alert("calendar-plug-bs must be a div");
}
/*****WORKING ON THIS***/
}
return r;
}

Array Data to HTML Table

What is the best way to get data from an array using tabletop.js into an html table? I am trying to take the data from the array and replace the dummy data that I currently have in there. The link below better explains what I'm trying to do.
Example of Data & Table
Here is my Fiddle: https://jsfiddle.net/1qeydx4f/
HTML:
<script type="text/javascript">
var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/16EypE4AkZVutLblpQEpsBu4ly7ziqBRYPxlv7wO1SJs/edit?usp=sharing';
function init() {
Tabletop.init( { key: publicSpreadsheetUrl,
callback: showInfo,
simpleSheet: true } )
}
function showInfo(data, tabletop) {
console.log(data);
}
window.addEventListener('DOMContentLoaded', init)
</script>
<div class="docs-section" id="tables">
<h6 class="docs-header">3-Pointers Made (2019)</h6>
<p> </p>
<div class="docs-example">
<table class="u-full-width">
<thead>
<tr>
<th>Name</th>
<th>Team</th>
<th>Made</th>
<th>Attempted</th>
<th>Percent</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dave Gamache</td>
<td>GS</td>
<td>150</td>
<td>300</td>
<td>50%</td>
</tr>
<tr>
<td>Dwayne Johnson</td>
<td>DAL</td>
<td>128</td>
<td>298</td>
<td>43%</td>
</tr>
</tbody>
</table>
</div>
</div>
Tabletop.js:
(function() {
'use strict';
var inNodeJS = typeof process !== 'undefined' && !process.browser;
var request = function requestNotProvided() {
throw new Error("The 'request' module is only available while running in Node.");
};
if(inNodeJS) { // This will get stripped out by Uglify, and Webpack will not include it
request = require('request');
}
var supportsCORS = false;
var inLegacyIE = false;
try {
var testXHR = new XMLHttpRequest();
if (typeof testXHR.withCredentials !== 'undefined') {
supportsCORS = true;
} else {
if ('XDomainRequest' in window) {
supportsCORS = true;
inLegacyIE = true;
}
}
} catch (e) { }
// Create a simple indexOf function for support
// of older browsers. Uses native indexOf if
// available. Code similar to underscores.
// By making a separate function, instead of adding
// to the prototype, we will not break bad for loops
// in older browsers
var indexOfProto = Array.prototype.indexOf;
var ttIndexOf = function(array, item) {
var i = 0, l = array.length;
if (indexOfProto && array.indexOf === indexOfProto) {
return array.indexOf(item);
}
for (; i < l; i++) {
if (array[i] === item) {
return i;
}
}
return -1;
};
/*
Initialize with Tabletop.init( { key: '0AjAPaAU9MeLFdHUxTlJiVVRYNGRJQnRmSnQwTlpoUXc' } )
OR!
Initialize with Tabletop.init( { key: 'https://docs.google.com/spreadsheet/pub?hl=en_US&hl=en_US&key=0AjAPaAU9MeLFdHUxTlJiVVRYNGRJQnRmSnQwTlpoUXc&output=html&widget=true' } )
OR!
Initialize with Tabletop.init('0AjAPaAU9MeLFdHUxTlJiVVRYNGRJQnRmSnQwTlpoUXc')
*/
var Tabletop = function(options) {
// Make sure Tabletop is being used as a constructor no matter what.
if(!this || !(this instanceof Tabletop)) {
return new Tabletop(options);
}
if(typeof(options) === 'string') {
options = { key : options };
}
this.callback = options.callback;
this.wanted = options.wanted || [];
this.key = options.key;
this.simpleSheet = !!options.simpleSheet;
this.parseNumbers = !!options.parseNumbers;
this.wait = !!options.wait;
this.reverse = !!options.reverse;
this.postProcess = options.postProcess;
this.debug = !!options.debug;
this.query = options.query || '';
this.orderby = options.orderby;
this.endpoint = options.endpoint || 'https://spreadsheets.google.com';
this.singleton = !!options.singleton;
this.simpleUrl = !!(options.simpleUrl || options.simple_url); //jshint ignore:line
this.authkey = options.authkey;
this.sheetPrivacy = this.authkey ? 'private' : 'public'
this.callbackContext = options.callbackContext;
// Default to on, unless there's a proxy, in which case it's default off
this.prettyColumnNames = typeof(options.prettyColumnNames) === 'undefined' ? !options.proxy : options.prettyColumnNames;
if(typeof(options.proxy) !== 'undefined') {
// Remove trailing slash, it will break the app
this.endpoint = options.proxy.replace(/\/$/,'');
this.simpleUrl = true;
this.singleton = true;
// Let's only use CORS (straight JSON request) when
// fetching straight from Google
supportsCORS = false;
}
this.parameterize = options.parameterize || false;
if (this.singleton) {
if (typeof(Tabletop.singleton) !== 'undefined') {
this.log('WARNING! Tabletop singleton already defined');
}
Tabletop.singleton = this;
}
/* Be friendly about what you accept */
if (/key=/.test(this.key)) {
this.log('You passed an old Google Docs url as the key! Attempting to parse.');
this.key = this.key.match('key=(.*?)(&|#|$)')[1];
}
if (/pubhtml/.test(this.key)) {
this.log('You passed a new Google Spreadsheets url as the key! Attempting to parse.');
this.key = this.key.match('d\\/(.*?)\\/pubhtml')[1];
}
if(/spreadsheets\/d/.test(this.key)) {
this.log('You passed the most recent version of Google Spreadsheets url as the key! Attempting to parse.');
this.key = this.key.match('d\\/(.*?)\/')[1];
}
if (!this.key) {
this.log('You need to pass Tabletop a key!');
return;
}
this.log('Initializing with key ' + this.key);
this.models = {};
this.modelNames = [];
this.model_names = this.modelNames; //jshint ignore:line
this.baseJsonPath = '/feeds/worksheets/' + this.key + '/' + this.sheetPrivacy +'/basic?alt=';
if (inNodeJS || supportsCORS) {
this.baseJsonPath += 'json';
} else {
this.baseJsonPath += 'json-in-script';
}
if(!this.wait) {
this.fetch();
}
};
// A global storage for callbacks.
Tabletop.callbacks = {};
// Backwards compatibility.
Tabletop.init = function(options) {
return new Tabletop(options);
};
Tabletop.sheets = function() {
this.log('Times have changed! You\'ll want to use var tabletop = Tabletop.init(...); tabletop.sheets(...); instead of Tabletop.sheets(...)');
};
Tabletop.prototype = {
fetch: function(callback) {
if (typeof(callback) !== 'undefined') {
this.callback = callback;
}
this.requestData(this.baseJsonPath, this.loadSheets);
},
/*
This will call the environment appropriate request method.
In browser it will use JSON-P, in node it will use request()
*/
requestData: function(path, callback) {
this.log('Requesting', path);
if (inNodeJS) {
this.serverSideFetch(path, callback);
} else {
//CORS only works in IE8/9 across the same protocol
//You must have your server on HTTPS to talk to Google, or it'll fall back on injection
var protocol = this.endpoint.split('//').shift() || 'http';
if (supportsCORS && (!inLegacyIE || protocol === location.protocol)) {
this.xhrFetch(path, callback);
} else {
this.injectScript(path, callback);
}
}
},
/*
Use Cross-Origin XMLHttpRequest to get the data in browsers that support it.
*/
xhrFetch: function(path, callback) {
//support IE8's separate cross-domain object
var xhr = inLegacyIE ? new XDomainRequest() : new XMLHttpRequest();
xhr.open('GET', this.endpoint + path);
var self = this;
xhr.onload = function() {
var json;
try {
json = JSON.parse(xhr.responseText);
} catch (e) {
console.error(e);
}
callback.call(self, json);
};
xhr.send();
},
/*
Insert the URL into the page as a script tag. Once it's loaded the spreadsheet data
it triggers the callback. This helps you avoid cross-domain errors
http://code.google.com/apis/gdata/samples/spreadsheet_sample.html
Let's be plain-Jane and not use jQuery or anything.
*/
injectScript: function(path, callback) {
var script = document.createElement('script');
var callbackName;
if (this.singleton) {
if (callback === this.loadSheets) {
callbackName = 'Tabletop.singleton.loadSheets';
} else if (callback === this.loadSheet) {
callbackName = 'Tabletop.singleton.loadSheet';
}
} else {
var self = this;
callbackName = 'tt' + (+new Date()) + (Math.floor(Math.random()*100000));
// Create a temp callback which will get removed once it has executed,
// this allows multiple instances of Tabletop to coexist.
Tabletop.callbacks[ callbackName ] = function () {
var args = Array.prototype.slice.call( arguments, 0 );
callback.apply(self, args);
script.parentNode.removeChild(script);
delete Tabletop.callbacks[callbackName];
};
callbackName = 'Tabletop.callbacks.' + callbackName;
}
var url = path + '&callback=' + callbackName;
if (this.simpleUrl) {
// We've gone down a rabbit hole of passing injectScript the path, so let's
// just pull the sheet_id out of the path like the least efficient worker bees
if(path.indexOf('/list/') !== -1) {
script.src = this.endpoint + '/' + this.key + '-' + path.split('/')[4];
} else {
script.src = this.endpoint + '/' + this.key;
}
} else {
script.src = this.endpoint + url;
}
if (this.parameterize) {
script.src = this.parameterize + encodeURIComponent(script.src);
}
this.log('Injecting', script.src);
document.getElementsByTagName('script')[0].parentNode.appendChild(script);
},
/*
This will only run if tabletop is being run in node.js
*/
serverSideFetch: function(path, callback) {
var self = this;
this.log('Fetching', this.endpoint + path);
request({url: this.endpoint + path, json: true}, function(err, resp, body) {
if (err) {
return console.error(err);
}
callback.call(self, body);
});
},
/*
Is this a sheet you want to pull?
If { wanted: ["Sheet1"] } has been specified, only Sheet1 is imported
Pulls all sheets if none are specified
*/
isWanted: function(sheetName) {
if (this.wanted.length === 0) {
return true;
} else {
return (ttIndexOf(this.wanted, sheetName) !== -1);
}
},
/*
What gets send to the callback
if simpleSheet === true, then don't return an array of Tabletop.this.models,
only return the first one's elements
*/
data: function() {
// If the instance is being queried before the data's been fetched
// then return undefined.
if (this.modelNames.length === 0) {
return undefined;
}
if (this.simpleSheet) {
if (this.modelNames.length > 1 && this.debug) {
this.log('WARNING You have more than one sheet but are using simple sheet mode! Don\'t blame me when something goes wrong.');
}
return this.models[this.modelNames[0]].all();
} else {
return this.models;
}
},
/*
Add another sheet to the wanted list
*/
addWanted: function(sheet) {
if(ttIndexOf(this.wanted, sheet) === -1) {
this.wanted.push(sheet);
}
},
/*
Load all worksheets of the spreadsheet, turning each into a Tabletop Model.
Need to use injectScript because the worksheet view that you're working from
doesn't actually include the data. The list-based feed (/feeds/list/key..) does, though.
Calls back to loadSheet in order to get the real work done.
Used as a callback for the worksheet-based JSON
*/
loadSheets: function(data) {
var i, ilen;
var toLoad = [];
this.googleSheetName = data.feed.title.$t;
this.foundSheetNames = [];
for (i = 0, ilen = data.feed.entry.length; i < ilen ; i++) {
this.foundSheetNames.push(data.feed.entry[i].title.$t);
// Only pull in desired sheets to reduce loading
if (this.isWanted(data.feed.entry[i].content.$t)) {
var linkIdx = data.feed.entry[i].link.length-1;
var sheetId = data.feed.entry[i].link[linkIdx].href.split('/').pop();
var jsonPath = '/feeds/list/' + this.key + '/' + sheetId + '/' + this.sheetPrivacy + '/values?alt=';
if (inNodeJS || supportsCORS) {
jsonPath += 'json';
} else {
jsonPath += 'json-in-script';
}
if (this.query) {
// Query Language Reference (0.7)
jsonPath += '&tq=' + this.query;
}
if (this.orderby) {
jsonPath += '&orderby=column:' + this.orderby.toLowerCase();
}
if (this.reverse) {
jsonPath += '&reverse=true';
}
toLoad.push(jsonPath);
}
}
this.sheetsToLoad = toLoad.length;
for(i = 0, ilen = toLoad.length; i < ilen; i++) {
this.requestData(toLoad[i], this.loadSheet);
}
},
/*
Access layer for the this.models
.sheets() gets you all of the sheets
.sheets('Sheet1') gets you the sheet named Sheet1
*/
sheets: function(sheetName) {
if (typeof sheetName === 'undefined') {
return this.models;
} else {
if (typeof(this.models[sheetName]) === 'undefined') {
// alert( "Can't find " + sheetName );
return;
} else {
return this.models[sheetName];
}
}
},
sheetReady: function(model) {
this.models[model.name] = model;
if (ttIndexOf(this.modelNames, model.name) === -1) {
this.modelNames.push(model.name);
}
this.sheetsToLoad--;
if (this.sheetsToLoad === 0) {
this.doCallback();
}
},
/*
Parse a single list-based worksheet, turning it into a Tabletop Model
Used as a callback for the list-based JSON
*/
loadSheet: function(data) {
var that = this;
new Tabletop.Model({
data: data,
parseNumbers: this.parseNumbers,
postProcess: this.postProcess,
tabletop: this,
prettyColumnNames: this.prettyColumnNames,
onReady: function() {
that.sheetReady(this);
}
});
},
/*
Execute the callback upon loading! Rely on this.data() because you might
only request certain pieces of data (i.e. simpleSheet mode)
Tests this.sheetsToLoad just in case a race condition happens to show up
*/
doCallback: function() {
if(this.sheetsToLoad === 0) {
this.callback.apply(this.callbackContext || this, [this.data(), this]);
}
},
log: function() {
if(this.debug) {
if(typeof console !== 'undefined' && typeof console.log !== 'undefined') {
Function.prototype.apply.apply(console.log, [console, arguments]);
}
}
}
};
/*
Tabletop.Model stores the attribute names and parses the worksheet data
to turn it into something worthwhile
Options should be in the format { data: XXX }, with XXX being the list-based worksheet
*/
Tabletop.Model = function(options) {
var i, j, ilen, jlen;
this.columnNames = [];
this.column_names = this.columnNames; // jshint ignore:line
this.name = options.data.feed.title.$t;
this.tabletop = options.tabletop;
this.elements = [];
this.onReady = options.onReady;
this.raw = options.data; // A copy of the sheet's raw data, for accessing minutiae
if (typeof(options.data.feed.entry) === 'undefined') {
options.tabletop.log('Missing data for ' + this.name + ', make sure you didn\'t forget column headers');
this.originalColumns = [];
this.elements = [];
this.ready();
return;
}
for (var key in options.data.feed.entry[0]){
if (/^gsx/.test(key)) {
this.columnNames.push(key.replace('gsx$',''));
}
}
this.originalColumns = this.columnNames;
this.original_columns = this.originalColumns; // jshint ignore:line
for (i = 0, ilen = options.data.feed.entry.length ; i < ilen; i++) {
var source = options.data.feed.entry[i];
var element = {};
for (j = 0, jlen = this.columnNames.length; j < jlen ; j++) {
var cell = source['gsx$' + this.columnNames[j]];
if (typeof(cell) !== 'undefined') {
if (options.parseNumbers && cell.$t !== '' && !isNaN(cell.$t)) {
element[this.columnNames[j]] = +cell.$t;
} else {
element[this.columnNames[j]] = cell.$t;
}
} else {
element[this.columnNames[j]] = '';
}
}
if (element.rowNumber === undefined) {
element.rowNumber = i + 1;
}
this.elements.push(element);
}
if (options.prettyColumnNames) {
this.fetchPrettyColumns();
} else {
this.ready();
}
};
Tabletop.Model.prototype = {
/*
Returns all of the elements (rows) of the worksheet as objects
*/
all: function() {
return this.elements;
},
fetchPrettyColumns: function() {
if (!this.raw.feed.link[3]) {
return this.ready();
}
var cellurl = this.raw.feed.link[3].href.replace('/feeds/list/', '/feeds/cells/').replace('https://spreadsheets.google.com', '');
var that = this;
this.tabletop.requestData(cellurl, function(data) {
that.loadPrettyColumns(data);
});
},
beforeReady: function() {
if(this.postProcess) {
for (i = 0, ilen = this.elements.length; i < ilen; i++) {
this.postProcess(element);
}
}
},
ready: function() {
this.beforeReady();
this.onReady.call(this);
},
/*
* Store column names as an object
* with keys of Google-formatted "columnName"
* and values of human-readable "Column name"
*/
loadPrettyColumns: function(data) {
var prettyColumns = {};
var columnNames = this.columnNames;
var i = 0;
var l = columnNames.length;
for (; i < l; i++) {
if (typeof data.feed.entry[i].content.$t !== 'undefined') {
prettyColumns[columnNames[i]] = data.feed.entry[i].content.$t;
} else {
prettyColumns[columnNames[i]] = columnNames[i];
}
}
this.prettyColumns = prettyColumns;
this.pretty_columns = this.prettyColumns; // jshint ignore:line
this.prettifyElements();
this.ready();
},
/*
* Go through each row, substitutiting
* Google-formatted "columnName"
* with human-readable "Column name"
*/
prettifyElements: function() {
var prettyElements = [],
orderedPrettyNames = [],
i, j, ilen, jlen;
for (j = 0, jlen = this.columnNames.length; j < jlen ; j++) {
orderedPrettyNames.push(this.prettyColumns[this.columnNames[j]]);
}
for (i = 0, ilen = this.elements.length; i < ilen; i++) {
var newElement = {};
for (j = 0, jlen = this.columnNames.length; j < jlen ; j++) {
var newColumnName = this.prettyColumns[this.columnNames[j]];
newElement[newColumnName] = this.elements[i][this.columnNames[j]];
}
prettyElements.push(newElement);
}
this.elements = prettyElements;
this.columnNames = orderedPrettyNames;
},
/*
Return the elements as an array of arrays, instead of an array of objects
*/
toArray: function() {
var array = [],
i, j, ilen, jlen;
for (i = 0, ilen = this.elements.length; i < ilen; i++) {
var row = [];
for (j = 0, jlen = this.columnNames.length; j < jlen ; j++) {
row.push(this.elements[i][ this.columnNames[j]]);
}
array.push(row);
}
return array;
}
};
if(typeof module !== 'undefined' && module.exports) { //don't just use inNodeJS, we may be in Browserify
module.exports = Tabletop;
} else if (typeof define === 'function' && define.amd) {
define(function () {
return Tabletop;
});
} else {
window.Tabletop = Tabletop;
}
})();
This can actually be achieved pretty simply. All you need to do is give your table an ID to be able to select it, and have a loop in the tabletop callback:
function gotData(data) {
const table = document.getElementById("table1-id").tBodies[0];
for (const player of data) {
const row = table.insertRow(-1); // index -1 inserts at bottom
const keys = Object.keys(player);
for (let i = 0; i < keys.length; i++) {
const c = row.insertCell(i);
c.appendChild(document.createTextNode(player[keys[i]]));
}
}
}

.JS not working on Chrome Extension

I'm working on my first Chrome extension to help me on my job.
Well, I have a HTML file as the extension pop-up and a .JS file to do all the magic. When I run the HTML in the browser, it works fine (it has to autocomplete the keywords are being typed) but when I run it as a Chrome extension it does not work at all.
Any idea?
JSON file
{
"name": "Autocompleter",
"version": "0",
"description": "It completes!",
"manifest_version": 2,
"browser_action": {
"name": "project with jquery",
"icons": ["icon.png"],
"default_icon": "icon.png",
"default_popup": "home.html"
},
"content_scripts": [ {
"js": [ "awesomplete.js" ],
"matches": [ "http://*/*", "https://*/*"]
}]
}
HTML
<!doctype html>
<html lang="en">
<head>
<script src="awesomplete.js"></script>
<link rel="stylesheet" href="awesomplete.css" />
</head>
<body>
<section id="multiple-values">
<input data-list="Brazil, Argentina, Uruguai, Paraguai, Nova Zelândia, Canadá" data-multiple data-minchars="1" /></label>
<pre class="language-javascript"><code><script>new Awesomplete('input[data-multiple]', {
filter: function(text, input) {
return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]);
},
replace: function(text) {
var before = this.input.value.match(/^.+,\s*|/)[0];
this.input.value = before + text + ", ";
}
});</script></code></pre>
</section>
</body>
</html>
.JS file
(function () {
var _ = function (input, o) {
var me = this;
// Setup
this.isOpened = false;
this.input = $(input);
this.input.setAttribute("autocomplete", "off");
this.input.setAttribute("aria-autocomplete", "list");
o = o || {};
configure(this, {
minChars: 2,
maxItems: 10,
autoFirst: false,
data: _.DATA,
filter: _.FILTER_CONTAINS,
sort: _.SORT_BYLENGTH,
item: _.ITEM,
replace: _.REPLACE
}, o);
this.index = -1;
// Create necessary elements
this.container = $.create("div", {
className: "awesomplete",
around: input
});
this.ul = $.create("ul", {
hidden: "hidden",
inside: this.container
});
this.status = $.create("span", {
className: "visually-hidden",
role: "status",
"aria-live": "assertive",
"aria-relevant": "additions",
inside: this.container
});
// Bind events
$.bind(this.input, {
"input": this.evaluate.bind(this),
"blur": this.close.bind(this, { reason: "blur" }),
"keydown": function(evt) {
var c = evt.keyCode;
// If the dropdown `ul` is in view, then act on keydown for the following keys:
// Enter / Esc / Up / Down
if(me.opened) {
if (c === 13 && me.selected) { // Enter
evt.preventDefault();
me.select();
}
else if (c === 27) { // Esc
me.close({ reason: "esc" });
}
else if (c === 38 || c === 40) { // Down/Up arrow
evt.preventDefault();
me[c === 38? "previous" : "next"]();
}
}
}
});
$.bind(this.input.form, {"submit": this.close.bind(this, { reason: "submit" })});
$.bind(this.ul, {"mousedown": function(evt) {
var li = evt.target;
if (li !== this) {
while (li && !/li/i.test(li.nodeName)) {
li = li.parentNode;
}
if (li && evt.button === 0) { // Only select on left click
evt.preventDefault();
me.select(li, evt.target);
}
}
}});
if (this.input.hasAttribute("list")) {
this.list = "#" + this.input.getAttribute("list");
this.input.removeAttribute("list");
}
else {
this.list = this.input.getAttribute("data-list") || o.list || [];
}
_.all.push(this);
};
_.prototype = {
set list(list) {
if (Array.isArray(list)) {
this._list = list;
}
else if (typeof list === "string" && list.indexOf(",") > -1) {
this._list = list.split(/\s*,\s*/);
}
else { // Element or CSS selector
list = $(list);
if (list && list.children) {
var items = [];
slice.apply(list.children).forEach(function (el) {
if (!el.disabled) {
var text = el.textContent.trim();
var value = el.value || text;
var label = el.label || text;
if (value !== "") {
items.push({ label: label, value: value });
}
}
});
this._list = items;
}
}
if (document.activeElement === this.input) {
this.evaluate();
}
},
get selected() {
return this.index > -1;
},
get opened() {
return this.isOpened;
},
close: function (o) {
if (!this.opened) {
return;
}
this.ul.setAttribute("hidden", "");
this.isOpened = false;
this.index = -1;
$.fire(this.input, "awesomplete-close", o || {});
},
open: function () {
this.ul.removeAttribute("hidden");
this.isOpened = true;
if (this.autoFirst && this.index === -1) {
this.goto(0);
}
$.fire(this.input, "awesomplete-open");
},
next: function () {
var count = this.ul.children.length;
this.goto(this.index < count - 1 ? this.index + 1 : (count ? 0 : -1) );
},
previous: function () {
var count = this.ul.children.length;
var pos = this.index - 1;
this.goto(this.selected && pos !== -1 ? pos : count - 1);
},
// Should not be used, highlights specific item without any checks!
goto: function (i) {
var lis = this.ul.children;
if (this.selected) {
lis[this.index].setAttribute("aria-selected", "false");
}
this.index = i;
if (i > -1 && lis.length > 0) {
lis[i].setAttribute("aria-selected", "true");
this.status.textContent = lis[i].textContent;
$.fire(this.input, "awesomplete-highlight", {
text: this.suggestions[this.index]
});
}
},
select: function (selected, origin) {
if (selected) {
this.index = $.siblingIndex(selected);
} else {
selected = this.ul.children[this.index];
}
if (selected) {
var suggestion = this.suggestions[this.index];
var allowed = $.fire(this.input, "awesomplete-select", {
text: suggestion,
origin: origin || selected
});
if (allowed) {
this.replace(suggestion);
this.close({ reason: "select" });
$.fire(this.input, "awesomplete-selectcomplete", {
text: suggestion
});
}
}
},
evaluate: function() {
var me = this;
var value = this.input.value;
if (value.length >= this.minChars && this._list.length > 0) {
this.index = -1;
// Populate list with options that match
this.ul.innerHTML = "";
this.suggestions = this._list
.map(function(item) {
return new Suggestion(me.data(item, value));
})
.filter(function(item) {
return me.filter(item, value);
})
.sort(this.sort)
.slice(0, this.maxItems);
this.suggestions.forEach(function(text) {
me.ul.appendChild(me.item(text, value));
});
if (this.ul.children.length === 0) {
this.close({ reason: "nomatches" });
} else {
this.open();
}
}
else {
this.close({ reason: "nomatches" });
}
}
};
// Static methods/properties
_.all = [];
_.FILTER_CONTAINS = function (text, input) {
return RegExp($.regExpEscape(input.trim()), "i").test(text);
};
_.FILTER_STARTSWITH = function (text, input) {
return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
};
_.SORT_BYLENGTH = function (a, b) {
if (a.length !== b.length) {
return a.length - b.length;
}
return a < b? -1 : 1;
};
_.ITEM = function (text, input) {
var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
return $.create("li", {
innerHTML: html,
"aria-selected": "false"
});
};
_.REPLACE = function (text) {
this.input.value = text.value;
};
_.DATA = function (item/*, input*/) { return item; };
// Private functions
function Suggestion(data) {
var o = Array.isArray(data)
? { label: data[0], value: data[1] }
: typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
this.label = o.label || o.value;
this.value = o.value;
}
Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", {
get: function() { return this.label.length; }
});
Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
return "" + this.label;
};
function configure(instance, properties, o) {
for (var i in properties) {
var initial = properties[i],
attrValue = instance.input.getAttribute("data-" + i.toLowerCase());
if (typeof initial === "number") {
instance[i] = parseInt(attrValue);
}
else if (initial === false) { // Boolean options must be false by default anyway
instance[i] = attrValue !== null;
}
else if (initial instanceof Function) {
instance[i] = null;
}
else {
instance[i] = attrValue;
}
if (!instance[i] && instance[i] !== 0) {
instance[i] = (i in o)? o[i] : initial;
}
}
}
// Helpers
var slice = Array.prototype.slice;
function $(expr, con) {
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
}
function $$(expr, con) {
return slice.call((con || document).querySelectorAll(expr));
}
$.create = function(tag, o) {
var element = document.createElement(tag);
for (var i in o) {
var val = o[i];
if (i === "inside") {
$(val).appendChild(element);
}
else if (i === "around") {
var ref = $(val);
ref.parentNode.insertBefore(element, ref);
element.appendChild(ref);
}
else if (i in element) {
element[i] = val;
}
else {
element.setAttribute(i, val);
}
}
return element;
};
$.bind = function(element, o) {
if (element) {
for (var event in o) {
var callback = o[event];
event.split(/\s+/).forEach(function (event) {
element.addEventListener(event, callback);
});
}
}
};
$.fire = function(target, type, properties) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent(type, true, true );
for (var j in properties) {
evt[j] = properties[j];
}
return target.dispatchEvent(evt);
};
$.regExpEscape = function (s) {
return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
};
$.siblingIndex = function (el) {
/* eslint-disable no-cond-assign */
for (var i = 0; el = el.previousElementSibling; i++);
return i;
};
// Initialization
function init() {
$$("input.awesomplete").forEach(function (input) {
new _(input);
});
}
// Are we in a browser? Check for Document constructor
if (typeof Document !== "undefined") {
// DOM already loaded?
if (document.readyState !== "loading") {
init();
}
else {
// Wait for it
document.addEventListener("DOMContentLoaded", init);
}
}
_.$ = $;
_.$$ = $$;
// Make sure to export Awesomplete on self when in a browser
if (typeof self !== "undefined") {
self.Awesomplete = _;
}
// Expose Awesomplete as a CJS module
if (typeof module === "object" && module.exports) {
module.exports = _;
}
return _;
}());
Prints:
Working
Not working (as a Chrome Extension)

How to inherit Common object with other objects in javascript prototype

I am working with javascript. I would like to inherit Common object with other objects in javascript. Is it possible to do it? I mean to convert this js to a prototype model.
function setEvent(evt, ele, callback) {
var ele = getEle(ele);
if (ele.length === undefined) {
ele.addEventListener(evt, callback, false);
} else if (ele.length > 0) {
for (var i = 0; i < ele.length; i++) {
ele[i].addEventListener(evt, callback, false);
}
}
return false;
}
function getEle(ele) {
var _idf = ele.charAt(0);
if (_idf == "#") {
var _ele = document.getElementById(ele.substr(1));
return _ele;
} else if (_idf == ".") {
var _els = document.getElementsByClassName(ele.substr(1));
return _els;
}
return ele;
}
function getInnerHtml(id) {
return document.getElementById(id).innerHTML;
}
function getValue(elem) {
return elem.value;
}
setEvent("click", ".input", function() {
console.log(this.value);
var _num = getInnerHtml("math");
_num = _num + "" + getValue(this);
document.getElementById("math").innerHTML = _num;
});
It is a bit hard to understand what type of object model you're trying to build since you did not describe any requirements or desires in that regard. Here's one idea that kind of works like jQuery does:
function core(selector) {
if (!(this instanceof core)) {
return new core(selector);
}
var items = document.querySelectorAll(selector);
if (items) {
this.items = Array.prototype.slice.call(items);
} else {
this.items = [];
}
this.length = this.items.length;
return this;
}
core.prototype = {
each: function(fn) {
for (var i = 0; i < this.length; i++) {
fn.call(this.items[i]);
}
return this;
},
firstProp: function(propName, defaultVal) {
if (this.length > 0) {
var val = this.items[0][propName];
return val !== undefined ? val : defaultVal;
} else {
return defaultVal;
}
},
getHTML: function() {
return this.firstProp("innerHTML", "");
},
setHTML: function(html) {
return this.each(function() {
this.innerHTML = html;
});
},
on: function(event, fn) {
return this.each(function() {
this.addEventListener(event, fn);
});
},
getValue: function() {
return this.firstProp("value", "");
}
};
And, then a usage example like yours:
core(".input").on("click", function(e) {
console.log(this.value);
var math = core("#math");
math.setHTML(math.getHTML() + this.value);
});
Working demo: http://jsfiddle.net/jfriend00/t56L4p5f/

XML Javascript undefined error in ie9

I have a 'jargon buster' on my site that uses an xml file to load an A-Z of words which when clicked display a brief short explanation of each word. This works fine in all browsers bar the latest ie's which i get an 'undefined' error with. The jscript im using is below
Jargon = {
xmlfile: 'http://www.mysite.com/jargon.xml',
xml: null,
wordHolder: 'words',
defHolder: 'definition',
idprefix: 'jargon_',
selected: null,
init: function () {
var con = Jargon.xhcon();
Jargon.wordHolder = $(Jargon.wordHolder);
Jargon.defHolder = $(Jargon.defHolder);
if (!con || !Jargon.wordHolder || !Jargon.defHolder) {
return;
}
function conComplete(oXML) {
Jargon.xml = oXML.responseXML;
//Jargon.showWords('a');
}
con.connect(Jargon.xmlfile, 'GET', Math.random(), conComplete);
},
showWords: function (c) {
if (Jargon.selected) {
Jargon.selected.className = '';
}
var words = Jargon.getWords(c);
while (Jargon.wordHolder.childNodes.length > 0) {
Jargon.wordHolder.removeChild(Jargon.wordHolder.childNodes[0]);
}
while (Jargon.defHolder.childNodes.length > 0) {
Jargon.defHolder.removeChild(Jargon.defHolder.childNodes[0]);
}
for (var i = 0; i < words.length; i++) {
var o = document.createElement('a');
o.href = 'javascript:Jargon.showDef(\'' + words[i].id + '\');';
o.id = Jargon.idprefix + words[i].id;
//o.onclick = Jargon.showDef;
o.appendChild($t(words[i].name));
Jargon.wordHolder.appendChild(o);
Jargon.wordHolder.appendChild(document.createElement('br'));
}
if (!words.length) {
var o = document.createElement('p');
var s = 'There are no words for the letter ' + c.toUpperCase();
Jargon.wordHolder.appendChild(o.appendChild($t(s)));
}
},
showDef: function (id) {
var o = $(Jargon.idprefix + id);
if (Jargon.selected) {
Jargon.selected.className = '';
}
if (o) {
o.className = 'selected';
Jargon.selected = o;
}
var defobjs = Jargon.getDef(id);
while (Jargon.defHolder.childNodes.length > 0) {
Jargon.defHolder.removeChild(Jargon.defHolder.childNodes[0]);
}
var heading = document.createElement('span');
heading.className = "jargtitle";
heading.appendChild(document.createTextNode(defobjs[1][0].textContent));
Jargon.defHolder.appendChild(heading);
var definition = document.createElement('span');
definition.className = "jargdefinition";
definition.appendChild(document.createTextNode(defobjs[0][0].textContent));
Jargon.defHolder.appendChild(definition);
},
getWords: function(c) {
var x = Jargon.xml;
var letters = x.getElementsByTagName('letter');
var oLetter = null;
for (var i = 0; i < letters.length; i++) {
if (letters[i].getAttribute('id') == c) {
oLetter = letters[i];
break;
}
}
if (!oLetter) {
return [];
}
var words = [];
for (i = 0; i < oLetter.childNodes.length; i++) {
var oJargon = oLetter.childNodes[i];
if (oJargon.nodeName == 'jargon') {
var s = Jargon.getName(oJargon);
words[words.length] = {
id: oLetter.childNodes[i].getAttribute('id'),
name: s
};
}
}
return words;
},
getDef: function (id) {
var x = Jargon.xml;
var j = null;
var temp = new Array(2);
var jargons = x.getElementsByTagName('jargon');
for (var i = 0; i < jargons.length; i++) {
if (jargons[i].getAttribute('id') == id) {
j = jargons[i];
break;
}
}
if (!j) {
return [];
}
//return [];
for (i = 0; i < j.childNodes.length; i++) {
if (j.childNodes[i].nodeName == 'name') {
temp[1] = j.childNodes[i].childNodes;
}
}
for (i = 0; i < j.childNodes.length; i++) {
if (j.childNodes[i].nodeName == 'desc') {
temp[0] = j.childNodes[i].childNodes;
}
}
//return [];
return temp;
},
cloneNode: function (oldNode, deep) {
deep = (deep) ? true : false;
// a replacement to the normal dom clone node
// this will copy xml nodes to html nodes
// which can then be inserted into the document
// scope in all browsers
// See for for the bug http://www.quirksmode.org/blog/archives/2005/12/xmlhttp_notes_c.html
var newNode = null;
if (oldNode.nodeType == '3') {
// textnode
newNode = $t(oldNode.nodeValue);
}
else if (oldNode.nodeType == '1') {
// element node
newNode = document.createElement(oldNode.nodeName);
if (deep) {
for (var i = 0; i < oldNode.childNodes.length; i++) {
newNode.appendChild(Jargon.cloneNode(oldNode.childNodes[i], true));
}
}
}
return newNode;
},
getName: function (oJargon) {
for (var i = 0; i < oJargon.childNodes.length; i++) {
if (oJargon.childNodes[i].nodeName == 'name') {
var oName = oJargon.childNodes[i];
var s = '';
for (var j = 0; j < oName.childNodes.length; j++) {
if (oName.childNodes[j].nodeType == 3) {
// text node
s += oName.childNodes[j].nodeValue;
}
}
return s;
}
}
return '';
},
xhcon: function () {
var xmlhttp, bComplete = false;
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { try { xmlhttp = new XMLHttpRequest(); }
catch (e) { xmlhttp = false; }}}
if (!xmlhttp) {
return null;
}
this.connect = function(sURL, sMethod, sVars, fnDone) {
if (!xmlhttp) {
return false;
}
bComplete = false;
sMethod = sMethod.toUpperCase();
try {
if (sMethod == "GET") {
xmlhttp.open(sMethod, sURL+"?"+sVars, true);
sVars = "";
}
else {
xmlhttp.open(sMethod, sURL, true);
xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && !bComplete) {
bComplete = true;
fnDone(xmlhttp);
}
};
xmlhttp.send(sVars);
}
catch(z) { return false; }
return true;
};
return this;
}
}
In terms of how im calling the jscript im using <li>a</li>
which loads a list of all items that begin with f then when i click one of items from that list say "Fiduciary" it triggers javascript:Jargon.showDef('f1'); which in turns loads the and into a definition div
however in ie9 it displays "undefined" . It works in all other browers
Example of the XML below:
<letter id="f"> -<jargon id="f1"> <name>Fiduciary</name> <desc>in a position of trust. This includes people such as trustees looking after trust assets for the beneficiaries and company directors running a company for the shareholders' benefit.</desc> </jargon> -<jargon id="f2"> <name>Forfeiture</name> <desc>the loss of possession of a property because the tenancy conditions have not been met by the tenant.</desc> </jargon> -<jargon id="f3"> <name>Freehold</name> <desc>describing land that only the owner has any rights over.</desc> </jargon> -<jargon id="f4"> <name>Free of encumbrances</name> <desc>no one else having any rights over something. When property is owned by someone and nobody else has any rights over it, it is owned free of encumbrances.</desc> </jargon> </letter>

Categories

Resources