3

所以我试图使这种形式异步。理想情况下,我使用此表单添加单位,然后动态更新表格。我不希望整个页面刷新。我对 javascript 不是很好,我可以使用一些指针来说明正在发生的事情:

发生了一些我不想发生的事情:

  1. 整个页面令人耳目一新
  2. request.is_ajax() 是假的。

大多数情况下,我只是想了解发生了什么,但问题是,如何更改以下内容以解决上述两个问题?(如果它们是问题,那根本就是问题。)

下面的一些代码取自这个问题:

如何在 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

由于缺乏 JS 经验,当我开始使用 Django 时,我在 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 序列化的响应字典是作为数据反馈的,随后用于将值附加到表中。所有这些都无需重新加载主页。

希望这个例子有所帮助。如果您还有问题,请告诉我。

京东

于 2012-10-15T22:39:26.727 回答