I now know how to load columns, of a table, from an external webpage.
Now I want to expand on that and:
AJAX, is asynchronous by the very definition. This means that the returned data will come back in just about any order, and the data will not be available outside the callback function(s) unless you explicitly copy it out.
So, for multi-page mashups, you must have some way to collate the data as necessary. (In your case you can collate on team name.)
A general approach is to:
Here's what it looks like in a userscript:
// ==UserScript==
// @name _Mash up tables from several *static*, third-party, web pages.
// @match *://football.fantasysports.yahoo.com/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant GM_xmlhttpRequest
// ==/UserScript==
const playerPositions = ["QB", "WR", "RB", "TE", "K", "DEF"];
const numPositions = playerPositions.length;
const baseURL = "http://football.fantasysports.yahoo.com/f1/326198/pointsagainst?pos=";
var rankingsTable = {}; //-- This will be filled by the AJAX parser.
var numPagesFetched = 0;
for (var J in playerPositions) {
GM_xmlhttpRequest ( {
method: "GET",
url: baseURL + playerPositions[J],
context: playerPositions[J],
onload: parseResponse,
onerror: function (e) { console.error ('**** error ', e); },
onabort: function (e) { console.error ('**** abort ', e); },
ontimeout: function (e) { console.error ('**** timeout ', e); }
} );
}
function parseResponse (response) {
var playerPosition = response.context;
var parser = new DOMParser ();
var ajaxDoc = parser.parseFromString (response.responseText, "text/html");
var statRows = ajaxDoc.querySelectorAll ("#statTable0 > tbody > tr");
var newStatTable = $(statRows).map ( function () {
var tblRow = $(this);
var teamRank = parseInt (tblRow.find (".rank-indicator").text().trim(), 10);
var teamName = tblRow.find ("td:eq(1)").text().trim().split(" vs")[0];
return [ [teamName, teamRank] ];
} ).get ();
numPagesFetched++;
console.log ('Fetched page ' + numPagesFetched + ' of ' + numPositions + '.');
/*--- Now loop over the fetched rows and collate them into the master table, depending
on playerPosition.
*/
var columnIdx = playerPositions.indexOf (playerPosition);
for (var K in newStatTable) {
var teamName = newStatTable[K][0];
var teamRank = newStatTable[K][1];
var teamStats = rankingsTable[teamName] || new Array (numPositions);
teamStats[columnIdx] = teamRank;
rankingsTable[teamName] = teamStats;
}
if (numPagesFetched === numPositions) {
displayFinalResult ();
}
}
function displayFinalResult () {
var sortedTeamNames = Object.keys (rankingsTable).sort ( function (zA, zB) {
return zA.localeCompare (zB);
} );
const namePadStr = new Array (25).join (' ');
console.log (
'Team Ranks QB, WR, RB, TE, K, DEF\n' +
'------------------------ ------------------------------'
);
for (var J in sortedTeamNames) {
var teamName = sortedTeamNames[J];
if (rankingsTable.hasOwnProperty (teamName) ) {
console.log (
(teamName + namePadStr).slice (0, 24) + ' ', rankingsTable[teamName]
);
}
}
}
We're going to get a large cut of your FF winnings, right? ;)