Asynchronous forms with bootstrap and django

So, I am trying to make this form asynchronous. Ideally, I use this form to add units, and then dynamically update the table. I do not want the whole page to be updated. I'm not so good with javascript, and I could use some pointers with what happens:

Several things happen that I do not want:

  • The whole page is being updated.
  • request.is_ajax () - False.

Basically, I'm just trying to figure out what is happening, but the question is, how do I modify the following to fix these two problems? (if it's a problem, it's a problem at all.)

Some of the code below is taken from this question:

How to insert django form in twitter bootstrap modal window?

For the record, I see the message just fine in the .POST request, I just want it to work asyncronously, since my question is different from the previous one.

{% 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> 
+2
source share
1 answer

I struggled with AJAX when I started with Django due to a lack of JS experience.

I will give you an example of the aync form that I use to add parameters and display parameters.

The trendy code for my template is as follows, and it will work just as well as the form you rendered, and not my lazy hardcoded 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> 

Then, make sure you have the following CSRF token issues at your disposal.

 <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 ie 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> 

Secondly, this is what the main AJAX POST will look like using jQuery. Please note that it is based on preventing the behavior of the default presentation of a form living in our modal mode. Upon successful addition of newly added values ​​to the table. It would not be so difficult to add values ​​as part of capturing the form, but I like to be sure that everything has been saved and processed before being added to the table.

  $(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(''); } }); }); }); 

Finally, you just need a view that captures this AJAX request, which will look like this partially written below.

 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 

The dict answer that we serialize json is what is returned as data and subsequently used to add values ​​to the table. All without reloading the main page.

Hope this example helped. Let me know if you have any questions.

Jd

+5
source

Source: https://habr.com/ru/post/1440312/


All Articles