UWA ウィジェット形式を使用して JavaScript ウィジェットを開発しています。残念ながら、これにより私のコードを jsFiddle することはできなくなりますが、詳細にコメントしたので、うまくいけば、かなり簡単な手順に従うことができます。
HighestClass = {};
HighestClass.array = [];
HighestClass.url = "http://our.url.local/frog/pointsByWeek.php?cmd=highestClass&students=";
HighestClass.init = function(groupPrefix) {
var count = 0;
/* Using the group prefix, i.e. "CLS 9", from the drop-down box,
get a list of all of the classes in that year group */
/* First time round, count the number of groups that match this
syntax because there are no parameters available to filter
this API */
Frog.API.get('groups.getAll',{
'onSuccess': function(data){
for (var i = 0; i < data.length; i++) {
if (data[i].name.indexOf(groupPrefix) != -1)
count++;
}
});
/* Now that these classes have been counted, run through the API
call again to push each class ID through to another function */
var run_through = 0;
Frog.API.get('groups.getAll',{
'onSuccess': function(data){
for (var i = 0; i < data.length; i++) {
if (data[i].name.indexOf(groupPrefix) != -1) {
var end = false;
run_through++;
/* When it gets to the last class group, i.e. the run_through
variable becomes equal to count, let the getClassPoints
function know */
if( run_through == count )
end = true;
HighestClass.getClassPoints( data[i].name, data[i].id, end );
}
}
}
});
}
HighestClass.getClassPoints = function(name, id, end) {
var list = '';
/* Using the ID of the class group, create a comma-separated list
of students for use in our MySQL query */
Frog.API.get("users.search", {
"params": {
"group": id
},
"onSuccess": function (data){
for (var i = 0; i < data.length; i++)
list += data[i].id + ",";
}
});
/* If the list exists... */
if( typeof list === "string" && list.length > 0 ) {
list = list.slice(0,-1);
/* Run an AJAX call to our PHP script which simply returns an integer
value of the SUM of reward points earned by that list of students */
UWA.Data.getJson(HighestClass.url + list, function(res){
if (res === false || res === "") res = 0;
/* Push this data into an array of objects alongside the class name */
var obj = { "name": name, "points": res };
HighestClass.array.push(obj);
});
}
/* As this function is being called asynchronously multiple times we need to
determine when the last call is run so that we can deal with our array
of data. We do this thanks to the count/run_through variables in earlier
function which will trigger end=true in this function */
if( end === true )
HighestClass.display();
}
HighestClass.display = function() {
/* Once we've put our array of objects together, we need to sort it so that
the class with the highest number of points are at array entry 0 */
function compare(a,b) {
if (a.points < b.points)
return 1;
if (a.points > b.points)
return -1;
return 0;
}
/* IF I PUT AN ALERT HERE, INTERNET EXPLORER WORKS, LOL? */
HighestClass.array.sort(compare);
/* We can then display the data of array entry 0 which should be our highest
point-scoring class */
$('#display').html( '<h1>' + HighestClass.array[0].name + '</h1><h3>' + HighestClass.array[0].points + '</h3>' );
}
/* equivalent of document ready */
widget.onLoad = function(){
/* Choose the year group from the drop down box */
$("select").change(function(){
var val = $('select option:selected').val();
$("#display").html('<h1><img width="60" height="60" src="http://logd.tw.rpi.edu/files/loading.gif" />Loading...</h1>');
HighestClass.init(val);
});
}
本質的に、スクリプトは次のことを行います。
- 各クラス グループの生徒のリストを取得する
- PHPスクリプト/MySQLデータベースへのAJAX呼び出しを実行して、それらの学生のポイントの合計を返します
- オブジェクトの配列に名前とポイント情報を追加します
- 最高得点のクラスが最初の配列エントリになるように、オブジェクトの配列を並べ替えます
- クラスの名前と配列エントリ 0 からのポイントを表示します
問題は、(API の制限のため) 私が考えることができる唯一の方法は、非同期 API 呼び出しを実行し、これらから AJAX 呼び出しをチェーンすることです。次に、カウント変数を使用して、最後の非同期呼び出しがいつ行われたかを判断します。
さて、重要なことに、このスクリプトは FireFox で完全に機能します。ただし、Internet Explorer では、スクリプトは「読み込み中」の DIV/画像を表示し、それ以上は実行しません。
奇妙なことalert
に、コード (大文字でコメントした場所) に を入れると、Internet Explorer は正しく動作します。
これは同期性とタイミングの問題に違いありませんが、私には経験も知識もありません。
誰でも解決策を提案できますか? 必要に応じて、Hacky で問題ありません。
乾杯、