web-dev-qa-db-ja.com

jsonまたはhtmlファイルを使用してjQuery ajaxを使用したテーブルの自動更新/更新

@SOF、

私は学校の成績、結果、予想成績などのウェブページに自動更新機能を持たせようとしました。そのため、jqueryを使用して新しいデータが届くとページのデータが更新されます。 ajaxだけでなく、クラスの「単一ビュー」もあります。

私の主な問題は、どの形式のajaxの更新/読み込みも正しく動作しないことです.jsonまたは単一のhtmlファイルで出力を生成できます。私の目的のためには、jsonの方が良いと思いますが、わかりません。

私のウェブページの左上にはナビゲーションヘルパーがあります。これは、テーブル内にある_<a id="CLASS1" optionname="CLASS 1"></a>_の「検索」で見つかったリストを介して入力されるドロップダウンメニューですが、必要に応じて入力できます必要に応じてテーブルの外。

この例では、_- Select Class -_、_Class 1_、_Class 2_、_Class 3_、_Class 4_、_Class 5_、_All Updating__All Non-Updating_

すべての更新

  • このオプションは、すべてのクラスを1つのhtml表示可能ページにロードし、30秒ごとに各クラスを更新します(一部のクラスは1時間で更新され、別の時間では他のクラスが更新される可能性があるため)異なる場合は更新しますか?

すべて非更新

  • このオプションは、すべてのクラスを1つのhtml表示可能ページにロードしますが、ユーザーが別のクラスをクリックして(ドロップダウンを使用して)をクリックしない限り、not更新しません...

クラス1、クラス2、クラス3 ...など(個別の読み込み/シングルビュー)

  • このオプションは、単一のクラスのデータをhtml表示可能ページにロードし、30秒ごとに特定のクラスを更新します、以前の投稿では-という名前のユーザー_Gaby aka G. Petrioli_は、私が必要とするものにかなり近い例を示しましたが、メンバーは私に戻ってきませんでした: http://jsfiddle.net/u7UkS/ 4 /

すべてのデータへのリンク

HTML- http://Pastebin.com/raw.php?i=0PNQGMmn

CSS- http://Pastebin.com/raw.php?i=4H5GHv15

JSON- http://Pastebin.com/raw.php?i=xk860dBN

シングルクラスページ- http://Pastebin.com/raw.php?i=HvpaVhG6

JSFiddle- http://jsfiddle.net/kHtuQ | http://jsfiddle.net/kHtuQ/show

特定のメンバーによるajaxの例を含む以前の投稿: Anchor Cycler /学校のクラスデータを定期的にインポートするドロップダウン


以下は、各「クラス」に何があるかを大まかに示す例です注クラス=学校クラス

超スリムテーブルの例:

_<table id="gradient-style">
    <tbody>
        <thead>
            <tr>
                <th scope="col"><a id="CLASS1" optionname="CLASS 1"></a>Class</th>
            </tr>
        </thead>
        <tr><td>Class 1</td></tr>
    </tbody>
    <tfoot>
            <tr>
                <th class="alt" colspan="34" scope="col"><a id="KEY"></a><img class="headimager" src="http://placehold.it/250x50"/></th>
            </tr>
            <tr>
                <td colspan="34"><em><b>Data</b> - Test</em></td>
            </tr>
    </tfoot>
</table>
_

誰かがこれを手伝うことができれば、それは非常にありがたいですし、あなたがコメントできるなら、私が学び続けることができるようにそうしてください。

ありがとう
デニスS

26
Dennis Sylvian

ajaxの使用は非常に簡単です。
コンテナにテーブルがあるため、これにはHTMLデータ型を使用することをお勧めします。
ここにAPIドキュメントがあります=> http://api.jquery.com/jQuery.ajax/
これは私があなたのために作ったフィドルです=> http://jsfiddle.net/sijav/kHtuQ/19/ または http://fiddle.jshell.net/ sijav/kHtuQ/19/show /

updateClass(url)という名前の関数にajaxコードを配置しました。urlは取得するURLを表し、取得するHTMLでコンテナーを追加します=>

_function updateClass(url){
    $.ajax({
        url: url,
        dataType: "HTML",
        error: function(msg){
            alert(msg.statusText);
            return msg;
        },
        success: function(html){
            $("#container").html(html);
        }
    });
}
_

コンテナクラス全体を更新するrefreshClassを追加しました=>

_function refreshClass(){
            updateClass("http://fiddle.jshell.net/sijav/mQB5E/5/show/"); //update the class
}
_

変更セレクタで以下のコードに変更=>

_var classUpdateI; //stands for our interval updating class
$(".class-selector").on("change",function(){
    if (classUpdateI!=null)clearInterval(classUpdateI); //If the selector changed clear the interval so the container won't be update on it's own
    if(this.value == "")
        return; // if the value is null don't do anything
    else if(this.value == "allclassnup"){
        refreshClass(); //if the value is allclassnup which is stands for All Non-Updating just refresh the whole class 
    }
    else if(this.value == "allclassup"){
        refreshClass(); //if the value is allclassup which is stands for All Updating refresh the whole class and set an interval for thirty second (look for 30*1000)
        classUpdateI = setInterval(refreshClass,30*1000);
    }
    else //else then it's a simple class value, just simply update the current class
        updateClass(this.value);
})
_

それが役に立てば幸い ;)
[〜#〜] edit [〜#〜]:大きなテーブルを取得できるように編集しました(生成しない!) -更新は30秒間隔で更新されます
AnotherEDIT:信じられないかもしれませんが、私はあなたの質問をすべて終えました!
WORKING FIDDLE: http://jsfiddle.net/sijav/kHtuQ/39/ または http://fiddle.jshell.net/sijav/kHtuQ/39/ show /
1これは、最後のhtmlに対してのみ行われたためです。新しいため、もう一度作成する必要があります。したがって、$('tr').click()関数全体を別の関数に入れ、必要に応じて呼び出します。
-これを完全に機能させますか?少し複雑ですが、コードを少し変更するだけで機能します。ここで、クラスセレクターの現在のクラスをCookieに変更するアルゴリズムを示します。ページを更新または再読み込みし、必要な選択したクラスを配置するたびにそれを読み取ることができます...
しかし、ここでのコード設計では、それを機能させるようにしました。
最初に_FirstTimeInit = true;_というグローバル変数を作成しました。これは、ページの読み込みを初めて行うかどうかを確認するためです。次に、ページの読み込みを強調するforループを配置します。 selectSelectedClassという関数、なぜですか?何度も呼び出す必要があるため、第三に、Cookieを読み取って強調表示されたものと現在のクラスを変更できるかどうかを確認するifステートメントを追加しました。コードは次のとおりです。

_if(readCookie("CurrentClass")) //if we can read coockie
    $(".class-selector").val(readCookie("CurrentClass")).change(); //change it's value to current cookie and trigger the change function
else{ // else
    selectSelectedClass(); //select those which was highlighted before
    trClick(); //make things clickable
    FirstTimeInit = false; //and turn of the first time init
}
_

セレクターの値の変更でCookieの作成を追加する=> createCookie("CurrentClass",$(".class-selector").val(),1);
そして最終的にAjaxの成功をこれに変更します

_        success: function(html){
            $("#container").html(html + '<a id="KEY"></a>'); //the html container changer with adding extra id , I'll explain it later it's for your second question
            if(FirstTimeInit){ //if it is First Time then
                selectSelectedClass(); //highlight which was highlighted after put the correct html
                FirstTimeInit = false; // turn of the first time init
            }
            else //else
                for (var i=0;i<($("table").children().length);i++){
                    if(readCookie(i))
                        eraseCookie(i); //erase every cookie that has been before because the table is now changed and we're going on another table so old cookie won't matter
                }
            trClick(); //make things selectable!
        }
_

また、バグをなくすために、選択したクラスがすべてまたはnullのときにfirstinitを有効にするようにrefreshClassを変更しました。これは、すべてのクラスがあり、それらのCookieが必要だからです!コードは次のとおりです。

_function refreshClass(){
    if(readCookie("CurrentClass")=="allclassnup"||readCookie("CurrentClass")=="allclassup"||readCookie("CurrentClass")==null)
        FirstTimeInit = true;
    updateClass("http://fiddle.jshell.net/sijav/mQB5E/5/show/");
}
_

2 _<a id="TOP"></a>_はコンテナの前にある必要があり、_<a id="KEY"></a>_はコンテナにhtmlを配置した後にコンテナの最後に生成される必要があります。 $("#container").html(html + '<a id="KEY"></a>');

3 [次へ]および[前へ]ボタンは、ajax以外の以前のデザイン用に設計されました。現在、別のソリューションが必要です!例としてこれらの簡単なコードを参照してください

_$("#PreviousClass").click(function(){//on prev click
    $(".class-selector").val($(".class-selector option:selected").prev().val()).change() //change the value to the prev on and trigger the change
});

$("#NextClass").click(function () {//on next click
    $(".class-selector").val($(".class-selector option:selected").next().val()).change() //change the value to the prev on and trigger the change
});
_

4はいキーを上下に変更してこれらのコードに変更する必要があります。

_currentClass=0;
$("a.TOPJS").click(function () {
    if(currentClass>0){
        currentClass--
        scrollToAnchor('CLASS'+currentClass);
    }
});

$("a.KEYJS").click(function () {
    if($("a[id='CLASS" + currentClass + "']")[0]!=undefined){
        currentClass++
        scrollToAnchor('CLASS'+currentClass);
    }
    else
        scrollToAnchor('CLASSMAX');
});
_

神の幸運

別のリクエスト編集:(これが最後になることを願っています!)
Working Fiddlehttp://jsfiddle.net/sijav/kHtuQ/42/ または- http://fiddle.jshell.net/sijav/kHtuQ/42/show/
大丈夫です。更新時の変更クラスが気に入らなかったので、それを削除しました。Cookieがツリーではないため、Cookieにクラスを追加するコードを追加しました。条件の種類、クラスはクラスセレクターの最後の文字から読み取られるため、クラスセレクターの最後の文字に-> _Class number ***5***_のようなクラス番号があることを確認してください!
[〜#〜] edit [〜#〜]:クラスnextを最適化し、前を参照してください http:// jsfiddle .net/sijav/kHtuQ/46 /
[〜#〜] edit [〜#〜]:要求されたコメントに従って、
それが私があなたに伝えようとしていることです。時にはデモがjsfiddle.netに表示され、時にはfiddle.jshell.netに表示されます。これらは異なるドメインであり、異なるドメインからhtmlを取得できません。
1)関数をIntervalに入れるか、別の関数を作成して、次のように適切な方法で呼び出すことができます=>

_classUpdateI = setInterval(function(){updateClass(this.value,parseInt(a.charAt(a.length-1),10));},30*1000);
_

2)行方不明?! 2番目の質問が見つかりません。
3)さて、... trclickは...に変更する必要があります=>

_function trClick(tIndex){ //tIndex would be classnumber from now on
    if (tIndex == -1){ //if it is all updating or all non updating
        $("tr").click(function(){ //do the previous do
            $(this).toggleClass('selected').siblings().removeClass('selected');
            if(readCookie($(this).parent().index("tbody"))){
                if(readCookie($(this).parent().index("tbody"))==$(this).index())
                    eraseCookie($(this).parent().index("tbody"));
                else{
                    eraseCookie($(this).parent().index("tbody"));
                    createCookie($(this).parent().index("tbody"),$(this).index(),1);
                }
            }
            else
                createCookie($(this).parent().index("tbody"),$(this).index(),1);
        });
    }
    else{ //else
        $("tr").click(function(){ //on click
            $(this).toggleClass('selected').siblings().removeClass('selected');//do the toggle like before
            if(readCookie(tIndex)){ //if you can read the CLASS cookie, not the current index of table because our table has only one row
                if(readCookie(tIndex)==$(this).index()) //as before if we selecting it again
                    eraseCookie(tIndex); //just erase the cookie
                else{ //else
                    eraseCookie(tIndex); //select the new one
                    createCookie(tIndex,$(this).index(),1);
                }
            }
            else
                createCookie(tIndex,$(this).index(),1); //else if we can't read it, just make it!
        });
    }
}
_

そして、Ajaxの成功時に呼び出す場合、classNumber => trClick(classNumber);で呼び出す必要があります。
最後の作業フィドル:http://jsfiddle.net/sijav/kHtuQ/ 53 / または http://fiddle.jshell.net/sijav/kHtuQ/53/show/

幸運

22
Sijav

正直なところ、主にJSONの例を理解していないため、投稿したコードに苦労しています。フラットなHTMLをJSON値として保存する場合、$.ajax JSONエンコード、解析、挿入ではなくHTMLをDOMに挿入します。とはいえ、JSONはnot現実的な例であると仮定します形:

{ class_name: "Class 1", description: "Blah Blah Blah" }

この仮定を念頭に置いて、この十分に文書化されているがテストされていない例は、正しい方向を示すはずです。基本的に、私は次のことを行います。

  • HTMLテンプレートを定義する
  • JSON値をHTMLテンプレートに転置する単純なテンプレート関数を作成します
  • setIntervalを使用してサーバー側スクリプトを生成するJSONに最後に要求したタイムスタンプを渡す関数を呼び出すgetJSONを使用して、サーバーをポーリングして新しいデータを取得する間隔を設定します。

これが私の例です。質問がある場合はお知らせください。

<script>
//  I wrapped this in a self-invoking anonymous function to prevent adding new global variables
(function(){
    var SECONDS_TO_POLL = 3
    ,   $parent_node = $('#node-to-append-to')
    ,   last_timestamp = null // this will be a timestamp passed to the server
    ,   template = '<table id="gradient-style"> \
            <tbody> \
                <thead> \
                    <tr>
                        <th scope="col"><a id="{ident}" optionname="{class_name}"></a>Class</th> \
                    </tr> \
                </thead> \
                <tr><td>{class_name}</td></tr> \
            </tbody> \
            <tfoot> \
                <tr> \
                    <th class="alt" colspan="34" scope="col"><a id="KEY"></a><img class="headimager" src="{image}" /></th> \
                </tr> \
                <tr> \
                    <td colspan="34"><em><b>Data</b> - Test</em></td> \
                </tr> \
            </tfoot> \
        </table>';

    /**
    *   simple templating function
    *   @param template String template using bracket vars (e.g. <h1>{message}</h1>)
    *   @param values Object literal (e.g. {message: "Hello"})
    *   @return Rendered HTML template
    */
    var render_template = function(template, values) {
            values = values || {};
            return template.replace(/{([^{}]*)}/g, function(bracketed, clean){
                  var object_value = values[clean];
                  return ['string', 'number'].indexOf((typeof object_value)) > -1 ? object_value : bracketed;
            });
        };

    // this is our polling function, will retrieve the JSON from the server, convert to HTML using template and render to the DOM
    var poller = function(){
        // load the JSON and pass a GET var telling the server what timestamp to query from (e.g. WHERE data.timestamp > last_timestamp)
        $.getJSON('/path/to/json?last_retrieved='+last_timestamp, function(data){
            // render the new data into our HTML template
            var html = render_template(template, data);
            // append the result to the parent DOM node
            $parent_node.append(html);
        })
        // get a current timestamp so that we can limit the server results to those 
        last_timestamp = new Date().getTime();
    }

    // retrieve new results every N seconds
    setInterval(poller, SECONDS_TO_POLL*1000);
})()
</script>

また、これに頭を置くだけで、サーバーからHTMLを返すだけの場合は、(ほとんどの場合)$.getJSON with $.get、クライアント側のすべてのテンプレートレンダリングを廃止し、DOMに応答を追加するだけ

(function(){
    var SECONDS_TO_POLL = 3
    ,   $parent_node = $('#node-to-append-to')
    ,   last_timestamp = null // this will be a timestamp passed to the server

    // this is our polling function, will retrieve the HTML from the server and render to the DOM
    var poller = function(){
        // load the HTML pass a GET var telling the server what timestamp to query from (e.g. WHERE data.timestamp > last_timestamp)
        $.get('/path/to/server?last_retrieved='+last_timestamp, function(html){
            // append the result to the parent DOM node
            $parent_node.append(html);
        })
        // get a current timestamp so that we can limit the server results to those 
        last_timestamp = new Date().getTime();
    }

    // retrieve new results every N seconds
    setInterval(poller, SECONDS_TO_POLL*1000);
})()
4
Rob M.

問題を解決する最善の方法は、ノックアウトなどのバインディングライブラリを使用することです。これにより、データとビューを分離し、データの更新方法を心配するだけで、ビューは自動的に更新されます。これはあなたが現在苦労しているように見えるものです。

そのため、リストを生成し、常にポーリングしてデータを更新する小さなサンプルを作成しました(ランダムに変化する同じデータを常に返す偽のサービスを使用)。

以下は、ノックアウトを使用して行った例です。ノックアウトのドキュメントページをご覧ください。 http://knockoutjs.com/documentation/introduction.html

HTML:ヘッダーとコンテンツを含む単純なテーブルを定義する

<table style="width: 100%" border="1">
    <thead>
        <tr>
            <td>
                <p><b>Classes</b>   
                </p>
            </td>http://jsfiddle.net/yBat5/#fork
            <td>
                <p><b>Childs</b>
                </p>
            </td>
        </tr>
    </thead>
    <tbody data-bind="foreach: Classes">
        <tr>
            <td>
                <p data-bind=" text: Class"></p>
            </td>
            <td>
                <p data-bind=" text: Child"></p>
            </td>
        </tr>
    </tbody>
</table>

JavaScript:

$(function () {
   // define a ViewModel for your data
    function ViewModel() {
        this.Classes = ko.observableArray([{
            "Class": "test",
                "Child": "Max"
        }, {
            "Class": "test2",
                "Child": "Walter"
        }]);
    }

    var vm = new ViewModel(),
        dummyData = [];

    // create a lot of dummy data sets
    for (var i = 0; i < 1000; i++) {
        dummyData.Push({
            "Class": "test " + i,
                "Child": "Child" + i
        })
    }

    // constantly poll for new data
    // JS fiddle implements a simple echo service, which we can use
    // to simulate data changes we change a rendon number
    function poll() {
        $.ajax({
            "url": "\/echo\/json\/",
                "type": "POST",
                "data": {
                "json": JSON.stringify(dummyData),
                    "deley": 3
            },
                "success": function (data) {
                vm.Classes(data);

                // poll again (3 seconds so we see how fast the update is)
                setTimeout(poll, 300);

                    // change a random entry to see that data changes
                var randomnumber=Math.floor(Math.random()*1000);
                    dummyData[randomnumber].Child = "Child"  +randomnumber +" changed"
            }
        });
    }

    poll();

    // apply it to the page, knocout now does the binding for you
    ko.applyBindings(vm);
});

フィドル: http://jsfiddle.net/yBat5/3/

1
Stefan