How to render a field request without refreshing the page?
I have a form with a few fields, the first being where a person enters their ID #, which is tied to a separate model for verification. I made this function get_employee_name, which returns the name based on the ID from the other model, but I'm not sure how to display it in the page, right on the top, without refreshing after the person tabs/clicks out? I'm not too familiar with html, but I was reading an ajax GET request would do the trick, but I'm not sure how to approach this.
This is basically so the person knows that the ID # they entered matches their name before proceeding to fill the rest out.
views.py
class EnterExitArea(CreateView):
model = EmployeeWorkAreaLog
template_name = "enter_exit_area.html"
form_class = WarehouseForm
def form_valid(self, form):
emp_num = form.cleaned_data['adp_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
if 'enter_area' in self.request.POST:
form.save()
return HttpResponseRedirect(self.request.path_info)
elif 'leave_area' in self.request.POST:
form.save()
EmployeeWorkAreaLog.objects.filter(adp_number=emp_num, work_area=area, station_number=station).update(time_out=datetime.now())
return HttpResponseRedirect(self.request.path_info)
def get_employee_name(request):
adp_number = request.POST.get('adp_number')
employee = Salesman.objects.get(adp_number=adp_number)
employee_name = employee.slsmn_name
return employee_name
models.py
class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
employee_name = models.CharField(max_length=25)
adp_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False) #(max_length=50, help_text="Employee #", blank=False)
...
def __str__(self):
return self.adp_number
forms.py
class WarehouseForm(AppsModelForm):
class Meta:
model = EmployeeWorkAreaLog
widgets = {
'adp_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('adp_number').remote_field, site),
}
fields = ('adp_number', 'work_area', 'station_number')
enter_exit_area.html
{% extends "base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" data-stations-url="{% url 'operations:ajax_load_stations' %}" novalidate >
{% csrf_token %}
<div>
<div>
{{ form.adp_number.help_text }}
{{ form.adp_number }}
</div>
<div>
{{ form.work_area.help_text }}
{{ form.work_area }}
</div>
<div>
{{ form.station_number.help_text }}
{{ form.station_number }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
<button type="submit" name="leave_area" value="Leave">Leave Area</button>
</div>
</div>
</form>
{% endblock main %}
Solution 1:
We'll use ajax, with jQuery so be sure you have jQuery before you read.
first, you've to create an endpoint to GET, go to urls.py & add an endpoint say
path('/myserver/getID/', views.get_employee_name, name="whatever")
now, this calls get_employee_name
right? Let's now call it in JS without refreshing.
here's the basic syntax ->
$.ajax({THIS IS A SIMPLE DICT})
ajax takes parameters
-
type
which is the request type -
url
which is the request URL which we just made above (not the full url, you're specifying the endpoint from where you're located on the website so you just use/myserver/getID/
) - it also takes
data
which is a dictionary with your posted data (yes a dictionary inside the bigger ajax dictionary - it CAN take
success
which is a function to call after getting the response with status 200 (success) and that success function can have the parameterresponse
which is your response - it CAN take
error
which is a function that gets called after an error & takeserror
as argument
enough talking...
$.ajax({
url: 'myserver/getID',
type: 'GET',
data: // don't specify this, we're not posting any data,
success: function (response) {console.log(response.data)}, //this will be what returned from python
error: function (error){console.log(error)}
})
this is a simple ajax request
NOTE, if you return a redirect from python & accept it from ajax, it won't work, ajax can't redirect, be sure to remember that because most of the time people ask why redirect('mylink')
doesn't work after I return it from ajax.
Another NOTE is the when dealing with post requests with ajax, you must include the csrf token which can be included by
csrfmiddlewaretoken: '{%csrf_token%}'
You can use Fetch API too if you want, or even normal XMLhttprequest
.
Solution 2:
Sounds like you have a few questions and should split them up but just to answer the main question in your title, "How to render a field request without refreshing the page?", this is how you do that part with some DOM manipulation. This is basic HTML and JavaScript you would need to fit into your project.
Once you get the name back from your lookup, you just need to insert the value into the DOM and that will render it, not requiring a refresh. Here's a simple example:
var clickMe = function() {
var element = document.getElementById('heading');
// Do your AJAX and lookup something...
element.textContent = "Name Lookup From Server Request";
}
<div>
<h1 id="heading"></h1>
<button onclick="clickMe()">Click Me</button>
</div>