jQueryUIダイアログへのデータの受け渡し


83

私はASP.Net MVCサイトを開発していて、データベースクエリからのいくつかの予約をテーブルにリストActionLinkし、次のBookingIdような特定の行の予約をキャンセルします。

私の予約

<table cellspacing="3">
    <thead>
        <tr style="font-weight: bold;">
            <td>Date</td>
            <td>Time</td>
            <td>Seats</td>      
            <td></td>              
            <td></td>
        </tr>
    </thead>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">13:00 - 14:00</td>
        <td style="width: 100px;">2</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/15">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/15">change</a></td>
    </tr>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">15:00 - 16:00</td>
        <td style="width: 100px;">3</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/10">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/10">change</a></td>
    </tr>  
</table>

を使用しjQuery Dialogて、ユーザーが予約をキャンセルするかどうかを確認するメッセージをポップアップ表示できると便利です。私はこれを機能させようとしていますが、パラメータを受け入れるjQuery関数を作成する方法に固執し続けているので、

<a href="https://stackoverflow.com/Booking.aspx/Cancel/10">cancel</a>

<a href="#" onclick="ShowDialog(10)">cancel</a>

次に、ShowDialog関数はダイアログを開き、パラメーター10をダイアログに渡すので、ユーザーが[はい]をクリックすると、hrefが投稿されます。/Booking.aspx/Change/10

次のようなスクリプトでjQueryダイアログを作成しました。

$(function() {
    $("#dialog").dialog({
        autoOpen: false,
        buttons: {
            "Yes": function() {
                alert("a Post to :/Booking.aspx/Cancel/10 would be so nice here instead of the alert");},
            "No": function() {$(this).dialog("close");}
        },
        modal: true,
        overlay: {
            opacity: 0.5,
            background: "black"
        }
    });
});   

およびダイアログ自体:

   <div id="dialog" title="Cancel booking">Are you sure you want to cancel your booking?</div>

最後に私の質問に:どうすればこれを達成できますか?またはそれを行うためのより良い方法はありますか?

回答:


45

あなたはこのようにそれを行うことができます:

  • <a>クラスでマークを付け、「キャンセル」と言います
  • class = "cancel"を使用してすべての要素を操作して、ダイアログを設定します。

    $('a.cancel').click(function() { 
      var a = this; 
      $('#myDialog').dialog({
        buttons: {
          "Yes": function() {
             window.location = a.href; 
          }
        }
      }); 
      return false;
    });
    

(および他のオプション)

ここでの重要なポイントは次のとおりです。

  • できるだけ目立たないようにする
  • 必要なのがURLだけの場合は、すでにhrefにあります。

ただし、キャンセルアクションには副作用があり、GETセマンティクスに準拠していないため、これをGETではなくPOSTにすることをお勧めします...


良い答えをありがとう。私はそれを試してみますが、1つの質問です。GETではなくPOSTにする方がよいとおっしゃっていますが、これは、href = "/ Booking.aspx / Cancel / 10"のような通常のhrefがGETになることを意味しますか?もしそうなら、それを投稿するのはどうですか?
フレデリク

それを投稿にするために、window.locationを変更する代わりに、jQuery $ .post()ajax関数を使用できます。docs.jquery.com/Ajax/jQuery.post#examples
Franck

1
私は$ .post()を使用しません、そのアプローチはうまく劣化しません。ただ、確認なしでそれを動作させる、任意のAJAXない標準<form>を書き、その後、あなたの<form>の「上に」確認を追加
マウリシオ・シェファー

これは、hijaxアプローチ(domscripting.com/blog/display/41)としても知られています
Mauricio Scheffer

postを使用する必要はありません、データベースを変更する操作にgetを使用すると、「クロスサイトリクエストフォージェリ」攻撃を受ける可能性があります...参照:en.wikipedia.org/wiki/Cross- site_request_forgery
strickli

273

jQueryは、データを保存するメソッドを提供します。ダミー属性を使用したり、問題の回避策を見つけたりする必要はありません。

クリックイベントをバインドします。

$('a[href*=/Booking.aspx/Change]').bind('click', function(e) {
    e.preventDefault();
    $("#dialog-confirm")
        .data('link', this)  // The important part .data() method
        .dialog('open');
});

そしてあなたの対話:

$("#dialog-confirm").dialog({
    autoOpen: false,
    resizable: false,
    height:200,
    modal: true,
    buttons: {
        Cancel: function() {
            $(this).dialog('close');
        },
        'Delete': function() {
            $(this).dialog('close');
            var path = $(this).data('link').href; // Get the stored result
            $(location).attr('href', path);
        }
    }
});

15
これは素晴らしい解決策です。.dataを使用してダイアログにデータを設定できることに気づいていませんでした。私は長年にわたってグローバル変数を設定し、ダイアログからそれらにアクセスしてから破棄してきました。
ケビンブラッドショー

この.data()マジックをありがとうございました。ただし、次の更新に注意してください。「jQuery 1.7の時点では、.on()メソッドがイベントハンドラーをドキュメントにアタッチするための推奨メソッドです」api.jquery.com/bind
daniloquio

2
.dataパラメーターは間違いなく進むべき道です。ありがとう!
アンドレアス

1
+1 jquery uiのドキュメントを検索しましたが、これがjQueryコア自体のメソッドであることに気付くまで見つかりませんでした。とても素敵なキャッチ
Tivie 2013

@ boris-gueryこんにちは、試してみましたが、うまくいきませんでした。デフォルトのアクションを妨げることはないので、ダイアログを開く代わりにリンクに移動します。任意の助けをいただければ幸いです:私はjsfiddleを作成します:jsfiddle.net/sebababi/9zKcZ
セバスチャン

2

jQueryで何をしているのかというと、私の理解では、関数をチェーンすることができ、内側の関数は外側の関数から変数にアクセスできます。したがって、ShowDialog(x)関数にはこれらの他の関数が含まれているので、それらの中でx変数を再利用でき、外部関数からのパラメーターへの参照として使用されます。

mauschに同意します。これらのアクションにPOSTを使用することを実際に検討する必要があります。これにより、<form>各要素の周囲にタグが追加されますが、自動化されたスクリプトまたはツールがキャンセルイベントをトリガーする可能性ははるかに低くなります。変更アクションは、(おそらく編集フォームを開くだけで)そのままにしておくことができます。


1

私は今あなたの提案を試しましたが、それはちょっとうまくいくことがわかりました、

  1. ダイアログdivは常にプレーンテキストで書き出されます
  2. $ .postバージョンでは、コントローラーが呼び出されて実際に予約がキャンセルされるという点で実際に機能しますが、ダイアログは開いたままで、ページは更新されません。get version window.location = h.refを使用すると、うまく機能します。

以下の私の「新しい」スクリプトを参照してください。

$('a.cancel').click(function() {
        var a = this;               
        $("#dialog").dialog({
            autoOpen: false,
            buttons: {
                "Ja": function() {
                    $.post(a.href);                     
                },
                "Nej": function() { $(this).dialog("close"); }
            },
            modal: true,
            overlay: {
                opacity: 0.5,

            background: "black"
        }
    });
    $("#dialog").dialog('open');
    return false;
});

});

手がかりはありますか?

ああ、私のアクションリンクは次のようになります:

<%= Html.ActionLink("Cancel", "Cancel", new { id = v.BookingId }, new  { @class = "cancel" })%>

$ .post()とhijaxアプローチの使用に関する私の回答に対する私のコメントを参照してください
Mauricio Scheffer

1

コードを確認するために必要なことは、ウィンドウを閉じてページを更新する機能を追加することです。「はい」関数では、次のように書く必要があります。

        buttons: {
            "Ja": function() {
                $.post(a.href);
                $(a). // code to remove the table row
                $("#dialog").dialog("close");
            },
            "Nej": function() { $(this).dialog("close"); }
        },

テーブルの行を削除するコードを書くのは面白くないので、詳細を説明しますが、基本的には、投稿後にダイアログに何をするかを指示する必要があります。賢い対話かもしれませんが、何らかの方向性が必要です。


あなたの答えに感謝します。私はそれを試してみて、行を削除する方法も見つけます...
Frederik

私はそれについて考えていました。「<TR>」タグにIDを追加すると、jQueryでその行を簡単に削除できる可能性があります。
thaBadDawg 2008

1

数時間のtry / catchの後、私はついにこの実用的な例を思いつきました。新しい行を使用したAJAX POSTでの作業は、その場でTABLEに追加されます(これが私の本当の問題でした)。

魔法はこれにリンクして来ました:

<a href="#" onclick="removecompany(this);return false;" id="remove_13">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_14">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_15">remove</a>

これは、AJAXPOSTとJqueryダイアログでの最後の作業です。

  <script type= "text/javascript">/*<![CDATA[*/
    var $k = jQuery.noConflict();  //this is for NO-CONFLICT with scriptaculous
     function removecompany(link){
        companyid = link.id.replace('remove_', '');
    $k("#removedialog").dialog({
                bgiframe: true,
                resizable: false,
                height:140,
                autoOpen:false,
                modal: true,
                overlay: {
                    backgroundColor: '#000',
                    opacity: 0.5
                },
                buttons: {
                    'Are you sure ?': function() {
                        $k(this).dialog('close');
                        alert(companyid);
                        $k.ajax({
                              type: "post",
                              url: "../ra/removecompany.php",
                              dataType: "json",
                              data: {
                                    'companyid' : companyid
                                    },
                              success: function(data) {
                                    //alert(data);
                                    if(data.success)
                                    {
                                        //alert('success'); 
                                        $k('#companynew'+companyid).remove();
                                    }
                          }
                        }); // End ajax method
                    },
                    Cancel: function() {
                        $k(this).dialog('close');
                    }
                }
            });
            $k("#removedialog").dialog('open'); 
            //return false;
     }
    /*]]>*/</script>
    <div id="removedialog" title="Remove a Company?">
        <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
        This company will be permanently deleted and cannot be recovered. Are you sure?</p>
    </div>

1

私のためのこの仕事:

<a href="#" onclick="sposta(100)">SPOSTA</a>

function sposta(id) {
        $("#sposta").data("id",id).dialog({
            autoOpen: true,
            modal: true,
            buttons: { "Sposta": function () { alert($(this).data('id')); } }
        });
    }

ダイアログアラート表示100で「Sposta」をクリックすると


0

divタグの最初の問題は簡単でした。それにastyle="display:none;"を追加し、ダイアログを表示する前に、ダイアログスクリプトにこれを追加しました。

$("#dialog").css("display", "inherit");

しかし、ポストバージョンについては、私はまだ運が悪いです。


$ .post()とhijaxアプローチの使用に関する私の回答に対する私のコメントを参照してください
Mauricio Scheffer

0

ダイアログを完全に制御したい場合は、デフォルトのボタンオプションの使用を避け、#dialogdivに自分でボタンを追加することをお勧めします。クリックなど、リンクのダミー属性にデータを配置することもできます。必要なときにattr( "data")を呼び出します。


0

私が採用したBorisGueryに触発されたソリューションは、次のようになります。リンク:

<a href="#" class = "remove {id:15} " id = "mylink1" >This is my clickable link</a>

アクションをそれにバインドします:

$('.remove').live({
        click:function(){
            var data = $('#'+this.id).metadata();
            var id = data.id;
            var name = data.name;
            $('#dialog-delete')
                .data('id', id)
                .dialog('open');    
            return false;
        }
    });

次に、idフィールドにアクセスします(この場合、値は15です:

$('#dialog-delete').dialog({
    autoOpen: false,
    position:'top',
    width: 345,
    resizable: false,
    draggable: false,
    modal: true,
    buttons: {            
        Cancel: function() {

            $(this).dialog('close');
        },
        'Confirm delete': function() {
            var id = $(this).data('id');
            $.ajax({
                url:"http://example.com/system_admin/admin/delete/"+id,
                type:'POST',
                dataType: "json",
                data:{is_ajax:1},
                success:function(msg){

                }
            })
        }
    }
});

0

これがお役に立てば幸いです

$("#dialog-yesno").dialog({
    autoOpen: false,
    resizable: false,
    closeOnEscape: false,
    height:180,
    width:350,
    modal: true,
    show: "blind",
    open: function() {
        $(document).unbind('keydown.dialog-overlay');
        },
    buttons: {
        "Delete": function() {
            $(this).dialog("close");
            var dir = $(this).data('link').href;
            var arr=dir.split("-");
            delete(arr[1]);
        },
    "Cancel": function() {
        $(this).dialog("close");
        }
    }
});



<a href="product-002371" onclick="$( '#dialog-yesno' ).data('link', this).dialog( 'open' ); return false;">Delete</a>

1
@ffernandezさん、OPでコードをスローするのではなく、実行していることの説明を含めることをお勧めします。
thomasfedb 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.