3

だから私はこのフォームを非同期にしようとしています。理想的には、このフォームを使用してユニットを追加し、テーブルを動的に更新します。ページ全体を更新したくありません。私はJavaScriptが得意ではありませんが、何が起こっているのかについていくつかのポインタを使用できます:

私が起こりたくないいくつかのことが起こっています:

  1. ページ全体がリフレッシュされます
  2. request.is_ajax() は False です。

ほとんどの場合、何が起こっているのかを理解しようとしているだけですが、問題は、上記の 2 つの問題を修正するために以下を変更するにはどうすればよいですか? (それらが問題である場合は、まったく問題です。)

以下のコードの一部は、この質問から取られています。

Twitterブートストラップモーダルウィンドウにdjangoフォームを挿入するにはどうすればよいですか?

記録のために、request.POSTで問題なく投稿が表示されています。非同期で機能させたいだけです。これが、私の質問が上記とどのように異なるかです。

{% block scripts %}
<script type="text/javascript">
    $(document).ready(function() {
        modalConnect();
    });
</script>

<script type="text/javascript">
$( document ).ajaxStop( function() {
    modalConnect();
});
</script>

<script type="text/javascript">
    function modalConnect()
        {
            //unbind the click event. If not done we will end up with multiple click event bindings, since binding is done after each ajax call.
            $(".editItem").unbind('click');
            //bind the click event
            $(".editItem").click(function(ev) { // for each edit item <a>
                ev.preventDefault(); // prevent navigation
                var url = this.href; //get the href from the <a> element
                $.get(url, function(results){
                  //get the form
                  var itemForm = $("#ajax_form_modal_result", results);
                  //get the update URL
                  var formUpdateURLDiv = $("#formUpdateURL", results);
                  //get the inner html of the div
                  var formUpdateURL = formUpdateURLDiv.html();
                  //update the dom with the received form
                  $('#inventory').html(itemForm);
                  //show the bootstrap modal
                  $("#inventory").modal('show');
                  $(document).ready(function () {
                     //bind the form to an ajax call. ajax call will be set to the received update url
                     submitItemModalFormBind(formUpdateURL);
                  });
                }, "html");
                return false; // prevent the click propagation
            })
        }
</script>

<script type="text/javascript">
       function submitItemModalFormBind(url){
         //bind the form. prevent default behavior and submit form via ajax instead
         $('#ajax_form_modal_result').submit(function(ev){
             $.ajax({
                type: "POST",
                url: url,
                data: $(this).serialize(),
                success:function(response, textStatus, jqXHR){
                     var form = $("#ajax_form_modal_result_div", response);
                     //form is returned if it is not valid. update modal with returned form
                     //change this "if" to check for a specific return code which should be set in the view
                     if (form.html()) {
                        console.log('Form was invalid and was returned');
                        //update modal div
                         $('#ajax_form_modal_result_div').html(form);
                         $("#inventory").modal('show');
                      }
                      //form is not returned if form submission succeeded
                      else{
                        //update the entire document with the response received since we received a entire success page and we want to reload the entire page

                        //sort by modified date descending

                        //var notificationDiv = $("#notification", response);
                        //$('#notification').html(notificationDiv.html());
                        console.log('Form was valid and was not returned');
                        $("#inventory").modal('hide');
                        }
                },
                error: function (request, status, error) {
                            var div = $("ajax_form_modal_result_div", request.responseText);
                            $('#ajax_form_modal_result_div').html(div);
                            //implement proper error handling
                            console.log("failure");
                            console.log(request.responseText);
                        }
                    });
                    return false;
                });
              }
</script>



{% endblock %}

{% block content %}

<div class="row">
    <div class="span8 offset4">
        <div class="row">
            <div class="span3">
                <h1>
                Acquisitions
                </h1>
            </div>
            <div class="span3 offset2">
                <h1>
                <a id="editItem" href="#inventory" role="button" class="icon-plus-sign" data-toggle="modal"></a>
                Add Units
                </h1>
            </div>
        </div>
        <table class="table table-hover table-striped">
            <thead>
                <tr>
                    <th>
                    lolcats
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>
                    lolcats
                    </td>
                </tr>
                    <tr>
                    <td>
                    test
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>


    <div class="modal hide fade" id="inventory" >
<form id="#ajax_form_modal_result" class="well" method="post" action="">
 <div id="ajax_form_modal_result_div">


    <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h3>Add units</h3>
    </div>
    <div class="modal-body">
        {% csrf_token %}
         {{inventory.as_p}}

    </div>
    <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <input class="btn btn-primary" type="submit" value="Save" />

    </div>

   </div>
</form>
</div>
4

1 に答える 1

6

Django を使い始めたとき、JS の経験がなかったため、AJAX にひどく苦労しました。

オプションを追加してオプションを表示するために使用する aync フォームの例を示します。

私のテンプレート モーダル コードは次のとおりです。これは、怠惰なハードコーディングされた html ではなく、レンダリングされるフォームでも同様に機能します。

   <div class="modal" id="AddOptions" style="display:none;">
  <div class="modal-header">
    <button class="close" data-dismiss="modal">X</button>
    <h3>Add Options</h3>
  </div>
  <div class="modal-body">

<form id="OptionForm" action="." method='POST'>
  <div id="OptionValueError" class="control-group">
  <span class="help-inline"></span><br>
  <br>Value&nbsp;<input type="text" name="OptionValue" id="id_OptionValue" /><br>Label&nbsp;<input type="text" name="OptionLabel" id="id_OptionLabel"/><input type="hidden" name="VariableID">
  </div>
<div id="divid_OptionTable">
<table class="table table-condensed" id="OptionTable">
<thead>
  <th>Value</th>
  <th colspan="2">Label</th>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
  <div class="modal-footer">
  <input type="submit" class="btn btn-primary" value="Add">&nbsp;<button type="reset" class="btn">Reset</button>
</form>
  </div>
</div>

次に、CSRF トークンの問題に対処するために、以下が含まれていることを確認してください。

<script type="text/javascript"> 
jQuery(document).ajaxSend(function(event, xhr, settings) {
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    function sameOrigin(url) {
        // url could be relative or scheme relative or absolute
        var host = document.location.host; // host + port
        var protocol = document.location.protocol;
        var sr_origin = '//' + host;
        var origin = protocol + sr_origin;
        // Allow absolute or scheme relative URLs to same origin
        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
            // or any other URL that isn't scheme relative or absolute i.e relative.
            !(/^(\/\/|http:|https:).*/.test(url));
    }
    function safeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    }
});
</script>

次に、jQuery を使用した基本的な AJAX POST は次のようになります。これは、モーダルにあるフォームのデフォルトの送信動作を防止することに基づいていることに注意してください。成功すると、新しく追加された値がテーブルに追加されます。フォームを取得する際に値を追加する方が面倒ではありませんが、テーブルに追加する前に、すべてが保存および処理されていることを確認したいと思います。

   $(document).ready(function() {
   $("#OptionForm").submit(function(event){
       event.preventDefault();
       $.ajax({
            type:"POST",
            url:"{% url builder.views.addoption %}",
            data: {VariableID: $('input:hidden[name=VariableID]').val(), OptionLabel: $('input:text[name=OptionLabel]').val(), OptionValue: $('input:text[name=OptionValue]').val()},
            success: function(data){
            console.log(data['OptionID']);
            $("#OptionValueError").removeClass("error");  
            $("#OptionValueError span").text("");  
            $("#OptionValueError span").removeClass("error");
            $('#OptionTable > tbody:last').append('<tr id=Option_'+data['OptionID']+'><td>'+data['OptionValue']+'</td><td>'+data['OptionLabel']+'</td><td><a href="#" onClick="deleteOption('+data['OptionID']+')"><i class="icon icon-remove"></i></a>');
            $('input:text[name=OptionValue]').val('');
            $('input:text[name=OptionLabel]').val('');
            }
          });
       });
    });

最後に、この AJAX リクエストをキャプチャするビューだけが必要です。これは、以下に部分的に記述されたもののようになります。

def addoption(request):
    if request.is_ajax():
        OptionValue = int(request.POST['OptionValue'])
        OptionLabel = request.POST['OptionLabel']
        VariableID = int(request.POST['VariableID'])
        getVar = Variable.objects.get(id=VariableID)
        newOption = Option(VariableID=getVar,
                Value=OptionValue,
                Label=OptionLabel)
        newOption.save()
        response = {'OptionValue': OptionValue, 'OptionLabel': OptionLabel, 'OptionID': newOption.id}
        json = simplejson.dumps(response)
        return HttpResponse(json, mimetype="text/json")
    else:
        pass

JSON でシリアライズしているという応答の辞書は、データとしてフィードバックされ、その後テーブルに値を追加するために使用されます。メインページをリロードせずにすべて。

うまくいけば、例が役に立ちました。ご不明な点がございましたら、お気軽にお問い合わせください。

JD

于 2012-10-15T22:39:26.727 に答える