58498

Do I have to re-render my page after updating template data

Question:

First I have <a href="https://stackoverflow.com/questions/13465711/how-do-i-post-with-jquery-ajax-in-django" rel="nofollow">searched and seen another answer</a>, but it doesn't address my need.

I am trying to POST data using jQuery/AJAX from my HTML to update a list that is also on my HTML.

When I first rendered my template, it had two list-group containers of which the <strong>left container</strong> is pre populated.

<a href="https://i.stack.imgur.com/ngSSy.png" rel="nofollow">two containers</a>

The <strong>choice made</strong> user makes on the left container determines the list group data of the <strong>right container</strong>.

I wanted to send back to the backend Python (server) which selection the user made from the left container, so that I may populate the appropriate list for the second (right) container. This is why I used the POST method using jQuery/AJAX to send users selection.

<strong>HTML</strong>

Here is a <strong><a href="http://plnkr.co/edit/piQLQQGYZCz2elNRdygO?p=preview" rel="nofollow">Plnkr</a></strong> of the HTML

Below is the jQuery/AJAX implementation which <strong>WORKS</strong>. It sends data back to Python <em>(to my views.py)</em>:

<strong>JS/jQuery/AJAX:</strong>

<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <script> $("#leftContainer > a").click(function(event){ event.preventDefault(); $("#leftContainer > a").removeClass("active"); $(this).addClass("active"); var leftDataSet = parseInt($(this).attr("data-set")); var item_selected = $(this).text(); var item_index = $(this).attr("id") //Users selection to send $.ajax({ type:'POST', url:"home/view_results/onclick/", data:{ selected_item:item_index, csrfmiddlewaretoken:"{{ csrf_token }}" }, dataType:"text", success: function(){$('#message').html("<h3>Data Submitted!</h3>") } }) }); $("#rightContainer > a").click(function(event){ event.preventDefault(); $(this).toggleClass("active"); }); </script>

<strong>views.py</strong>

#app/views.py from django.shortcuts import render class View_Items(): def render_view_items(self, request, shopid): item_history = self.get_item_list(shopid) #Fetches a list return render(request, 'view_results/View_items.html',{ 'item_list':item_history, })

<strong>urls.py</strong>

#app/urls.py from django.urls import path, re_path from . import views results = views.View_Items() urlpatterns=[ ... re_path(r'view_results/(?P<shopid>\w+)$', results.render_view_items, name = 'view_items'), re_path(r'view_results/onclick/$', results.render_view_items_again, name = 'view_results_new'), # NEW ]

<strong>My question is:,</strong>

now that I have the AJAX data returned back to my Python backend at views.py, do I have to re-render my page to populate the Right container's list group items in my HTML? Or is it possible to update the list without having to re-render. If so, why is my proposed re-render function below <strong>NOT</strong> updating the <strong>RIGHT container</strong> of my HTML? Updating the Right container is the objective which required the selection choice of left container.

<strong>Addition I made to views.py</strong>

#app/views.py def render_view_items_again(self, request): selected_item_by_user = request.POST.get('selected_item') # print(selected_item_by_user) models = self.get_all_models(selected_item_by_user) #Fetches a list. # print(models) #Tested if my list is populated. return render(request, 'view_results/View_items.html',{ 'model_list':models, })

Answer1:

It is totally possible to fill the right container, without having to reload your page.

What is usually done is to divide the function from views.py into the case of the first render and when you return from an AJAX POST. In your case, the views.py will be something like:

if request.method == 'POST': # Returning from AJAX selected_item_by_user = request.POST.get('selected_item') models = self.get_all_models(selected_item_by_user) #Fetches a list. return JsonResponse({'completed': "ok", 'list': models}) else: # First time render item_history = self.get_item_list(shopid) #Fetches a list return render(request, 'view_results/View_items.html',{ 'item_list':item_history, })

As you can see, I have only rendered the template the first time. When you get back from AJAX, I only call JsonResponse. Add the following import to your code:

from django.http import JsonResponse

Please be aware that depending on how is built your list (you have not provided the details), you will need to encode it <a href="https://docs.djangoproject.com/en/2.1/ref/request-response/" rel="nofollow">accodingly</a>.

Then, in the success function of your AJAX method, you can easily use the list (adapt it so that you fill the right container):

success: function(data){console.log(data.list)}

Hence, the right container will be filled without doing a re-render/refresh of the page.

Edit 1

Now I see that you are also redirecting to a different url in your AJAX method. If you want not to refresh, set your url in the AJAX method as follows:

$.ajax({ type:'POST', url: window.location.href, data:{ selected_item:item_index, csrfmiddlewaretoken:"{{ csrf_token }}" }, dataType:"text", success: function(){$('#message').html("<h3>Data Submitted!</h3>") } })

So you only need one url in the urls.py file too.

I do not know the HTML code of your right container, but if it is a list ul (let's suppose that it has an id=list_conditions), you could add an item to the right container as follows:

// Get where I should add the index let ul=document.getElementById("list_conditions"); // Create a new child let li=document.createElement("li"); li.setAttribute("class", "list-group-item list-group-item-secondary"); li.appendChild(document.createTextNode(data.list[0])); // Here you can replace by the index you need from the list ul.appendChild(li);

Recommend

  • Why doesn't >= (greater than or equals) comparison work in Javascript?
  • getting java.lang.ClassCastException: class java.lang.String in running a simple MapReduce Program
  • d3.js create stacked bar chart from values in object
  • Increasing dimensions on hover without changing the position of other elements
  • How to keep button state across different pages?
  • Get css animation property with jQuery
  • jquery code not working without breakpoint
  • SAVE attribute needed for Fortran variables when only the C_LOC address is returned to a C program?
  • saving file generated by TCPDF
  • Visual Studio 2010 debugger build correctly - compiler pdb and linker pdb not in synch?
  • d3 v4 drag and drop with TypeScript
  • Custom Tabgroup Appcelerator
  • Adding a button at the bottom of a table view
  • How can I send an e-mail from a vbs script
  • Spring security and special characters
  • Ajax jQuery multiple calls at the same time - long wait for answer and not able to cancel
  • How do I fake an specific browser client when using Java's Net library?
  • Date difference with leap year
  • angularjs unit test when to use $rootScope.$new()
  • Volusion's generic SQL folder, functionality
  • Menu Color Fade on Hover with Jquery
  • Where to put my custom functions in Wordpress?
  • How to limit post in wp_query
  • Hazelcast - OperationTimeoutException
  • How to make Safari send if-modified-since header?
  • Adding custom controls to a full screen movie
  • File upload with ng-file-upload throwing error
  • How to delete a row from a dynamic generate table using jquery?
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • trying to dynamically update Highchart column chart but series undefined
  • using HTMLImports.whenReady not working in chrome
  • How to set the response of a form post action to a iframe source?
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Change div Background jquery
  • How to stop GridView from loading again when I press back button?
  • Qt: Run a script BEFORE make
  • Authorize attributes not working in MVC 4
  • EntityFramework adding new object to nested object collection
  • reshape alternating columns in less time and using less memory
  • java string with new operator and a literal