Making a django form interactive - javascript

html file
<div id="calculator">
<h2>Kalkuleeri saematerjali hind</h2>
<form method="post" action="{% url 'products' %}">
{% csrf_token %}
<label>Valige materjali kvaliteet/tüüp:</label><br>
<select name="tyyp">
<option value="taiskant">Täiskant</option>
<option value="v_poomkant">Väike Poomkant</option>
<option value="s_poomkant">Suur Poomkant</option>
<option value="voodrilaud">Voodrilaud</option>
</select><br><br>
{% if not tyyp %}
<button type="submit">Edasi</button><br><br>
{% endif %}
</form>
<form method="post" action="{% url 'products' %}">
{% csrf_token %}
{% if tyyp %}
<label>Valige mõõdud: (Paksus mm x Laius mm)</label><br>
<select name="moot">
{% for product in products %}
<option value="1">{{ product.nimi }}</option>
{% endfor %}
</select><br><br>
<label>Pikkus:</label><br>
<select name="pikkus">
<option value="kunikolm">Kuni 3,1 m</option>
<option value="kolmkuniviis">3,2 - 5,1 m</option>
<option value="viiskunikuus">5,2 - 6,0 m</option>
</select><br><br>
<label>Kogus:</label><br>
<input type="number" required>
<select name="yhik">
<option value="tm">Tihumeetrit</option>
<option value="jm">Meetrit</option>
<option value="lauda">Lauda</option>
</select><br><br>
<button type="submit">Kalkuleeri</button>
<input type="text" class="calculator-screen" value="" disabled />
{% endif %}
</form>
views.py file
def products_view(request, *args, **kwargs):
taiskant_list = Taiskant.objects.all()
s_poomkant_list = S_Poomkant.objects.all()
v_poomkant_list = V_Poomkant.objects.all()
voodrilaud_list = Voodrilaud.objects.all()
context = {}
if request.method == "POST":
tyyp = request.POST['tyyp']
context['tyyp'] = tyyp
if request.POST['tyyp']=="taiskant":
context['products'] = taiskant_list
return render(request, "products.html", context)
elif request.POST['tyyp']=="s_poomkant":
context['products'] = s_poomkant_list
return render(request, "products.html", context)
elif request.POST['tyyp']=="v_poomkant":
context['products'] = v_poomkant_list
return render(request, "products.html", context)
elif request.POST['tyyp']=="voodrilaud":
context['products'] = voodrilaud_list
return render(request, "products.html", context)
else:
return render(request, "products.html", context)
The problem is, I am trying to create a live form(after choosing first select form option, it automatically renders second select form options without pressing a button).
It should be calculator, but without "Calculate button". It has to update/fill rest of the forms depending on first form choice. And after filling 4 fields, it calculates the "price".
Should I use Django-Forms or html/js for this?
Feel free to ask any questions if I didnt express myself understandably.

Since this is for homework, I'll point you in the right direction.
Let's say we have Make and Model of cars (a common example). There are a number of ways to create a dynamic form and store the data. You could use a dict or you could store the items in the db.
You would need a function that your front-end could call:
from django.http import JsonResponse
def get_models(request, make):
# query the db, or get the results from a global / readonly dict?
data = global_model_dict[make]
# return json for the js caller
return JsonResponse(data, content_type="application/json")
Add an entry in "urls" for it.
urlpatterns = [
# whatever else you have in here
path('models/<str:make>', views.get_models)
]
Finally, you'd need some javascript to call it. JQuery would be simple to include and would help this a lot. Something like this:
var settings = {
"url": "/myapp/models/honda",
"method": "GET",
"timeout": 0,
};
$.ajax(settings).done(function (response) {
console.log(response);
});
From there, you'll have the data you need to append / set html on the page. You'll do that with a loop where I have "console.log" right now.
Some sources for you to read.
https://docs.djangoproject.com/en/3.1/topics/http/urls/
https://api.jquery.com/

Related

Calling the list created using getlist on the form

In my Django project, I save the data in a field that I have made multiple selections to the database using the getlist function and the POST method. Then I pull this data from the database and print it on an html form, but I cannot access the list data properly unless I split it here.
views.py
def record_form(request):
if request.method == "POST" and 'registrationSave' in request.POST:
records = Records()
records.medications = request.POST.getlist('medications')
records.scale_used = request.POST.getlist('scale_used')
records.save()
return redirect('/index/tables')
def editRecords(request,id):
edit_records = Records.objects.get(id=id)
if edit_records.medications is not None:
edit_records.medications = edit_records.medications.split(",")
if edit_records.scale_used is not None:
edit_records.scale_used = edit_records.scale_used.split(",")
institutionName = Institution.objects.all()
medicationName = MedicationName.objects.all()
return render(request,"update_record.html",{"Records": edit_records,
"institutionName":institutionName,"medicationName":medicationName})
update.html
<div class="col-4">
{% for medication in Records.medications%}
<div class="mb-3 col">
<label for="">İlaç Adı:</label>
<select class="form-select" name="medications" id="medications">
<option {% if medication == '{{medicationName.medicationName}}' %} selected {%endif%}>{{medication}}</option>
{% if medicationName%}
<p>{{medicationName}}</p>
{% for medicationName in medicationName %}
<option value="{{medicationName.medicationName}}">{{medicationName.medicationName}}</option>
{%endfor%}
{%endif%}
</select>
</div>
{%endfor%}
</div>
I'm sharing my code pieces above with you, and I'm leaving the screenshot of the update.html page below. How can I follow a method to avoid [ ] and ' ' signs?
enter image description here
Thank you in advance for your help

Send data back to other input field after getting user input from first one flask

I´m getting data from the first input field using a xmlhttprequest which is send to my flask code. Then it´s processed and returns a specific list and in the next step i want to display the list (person) in the second input field so the user can select another value.
Here´s what i got so far:
.py
#application.route('/index', methods=["POST","GET"])
def index():
nodes=get_topic()
if request.method == "GET":
topic=request.args.get("topic")
#topic=''.join(str(x) for x in topic)
person=get_person(topic)
print("get")
print(topic)
return render_template("dash.html",nodes=nodes,ifxp=person)
.html
<form name ="myform" method="post" onchange="ajaxRequest()">
<input type="text" name="topic" list="nodes" id="topic" placeholder="Select aTopic" onchange="ajaxRequest()" required/>
<datalist id="nodes">
{% for node in nodes %}
<option value="{{node}}"> {{ node }}</option>
{% endfor %}
</datalist>
<input type="text" name="person" list="person" id="if_select" placeholder="Select a IFX Person"/>
<datalist id="ifx_person">
{% for p in ifxp %}
<option value="{{p}}"> {{ p }}</option>
{% endfor %}
</datalist>
</form
<script type="text/javascript">
function ajaxRequest() {
const checked = document.getElementById("topic").value;
console.log("Sending data to the server that the box is", checked);
// Use the XMLHttpRequest API
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
console.log("Result sent to server!");
}
xhttp.open("GET", "/index?topic="+encodeURIComponent(checked), true);
xhttp.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
xhttp.send(checked);
}
</script>

Django forms - How to change form data with HTML DOM?

I am trying to change a Django form's data by using:
document.getElementById("id_role").innerHTML = "developer"
The CustomUser model has a "role" field that is referenced in the function. By testing the output (with the displayField() function, it appears that document.getElementById("id_role").innerHTML actually references all of the available fields ("choices" given in the models.py).
The goal is for the second function, changeField(), to change the selected data on the form (my goal isn't to change the database's stored data at this point, just the selected form's input).
My question: How do I use document.getElementById().innerHTML to access the specific value that is shown in the form, instead of all of the options for the field?
models.py
TECH_OPTIONS = ( ('developer','DEVELOPER'), ('manager','MANAGER'), ('testing','TESTING'), )
class CustomUser(AbstractUser):
career = models.CharField(max_length=30)
role = models.CharField(choices=TECH_OPTIONS,blank = True, max_length=30)
def __str__(self):
return self.username
html page
{% extends "base.html" %}
{% load bootstrap3 %}
{% block content %}
<h1 id="testTag">{{user.username}}'s Info</h1>
<input onclick="displayField(); changeField();" type="submit" name="" value="TESTING">
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" value="Save" />
</form>
<script type="text/javascript">
function displayField(){
var myFormFields = document.getElementById("id_role").innerHTML
document.getElementById("testTag").innerHTML = myFormFields;
}
function changeField(){
document.getElementById("id_role").innerHTML = "developer"
}
</script>
{% endblock %}
You need to use value rather than innerHTML to change/read the value of a field:
document.getElementById("id_role").value = "developer"

keep original selected values after form submit python/flask

I have a two pronged question and would appreciate any advice.
1) I have a flask template with multiple forms in it. Each form presents the user with a list that is dynamically generated from a mongodb query.
name_list = [p['name'] for p in posts.find({'type': "server"})]
name_list.insert(0, "select")
This is then refernced in my html template (thank you again to the person who helped me with this loop on a previous question)
<select name="option" id="myselect" onchange="this.form.submit()">
{% for x in server_list %}
<option value="{{ x }}"{% if loop.first %} SELECTED{% endif %}>{{ x }}</option>
{% endfor %}
This selection is then passed back to python to be used in another db query and then present the user with another dropdown select box. However when the first form is submitted, the new page render means that that value is now lost on the html and appears blank. Is there a way to keep this choice persistent so when after the new page render it still appears?
2) Secondly, I would like to keep a running list of what options the user makes, however given the if, elif structure I'm using that variable looses state and can no longer used. Eventually I would like to present the user with two sets of these dropdown menus to generate to final db querys that I can compare and return the difference, however I can only do this if I can keep state of these values generated in the loops.
Please see full code below:
python:
from flask import render_template
from flask import request
from flask import Response
from app import app
from pymongo import MongoClient
#app.route('/', methods=['POST','GET'])
#app.route('/index', methods=['POST','GET'])
def index():
user = {'name': 'Bob'}
client = MongoClient('mongodb://localhost:27017/')
db = client['test-database']
collection = db.test_collection
name_list = []
posts = db.posts
name_list = [p['name'] for p in posts.find({'type': "server"})]
name_list.insert(0, "select")
select_list = []
#if request.form['submit'] == 'myselect':
if request.method == 'POST' and request.form.get('option'):
choice = request.form.get('option')
select_list.append(choice)
sub_name_list = [q['type'] for q in posts.find({'name': choice})]
return render_template("index.html",
sub_server_list=sub_name_list)
elif request.method == 'POST' and request.form.get('option1'):
choice1 = request.form.get('option1')
select_list.append(choice1)
return render_template("index.html",
title='Database selector',
user='Person',
choiced=choice1,
total_choice=select_list)
return render_template("index.html",
title='Database selector',
user='Person',
server_list=name_list)
html/jinja:
<html>
<head>
<title>{{ title }} - Test</title>
</head>
<body>
<h1>Hi, {{ user }}!</h1>
<h2>Database selector</h2>
<h3><table><form action="" method="post">
<td>
<label>Select1 :</label>
<!--<select name="option" width="300px">-->
<select name="option" id="myselect" onchange="this.form.submit()">
{% for x in server_list %}
<option value="{{ x }}"{% if loop.first %} SELECTED{% endif %}>{{ x }}</option>
{% endfor %}
</select>
</td>
</form></table></h3>
<h3><table><form action="" method="post">
<td>
<label>Select2 :</label>
<select name="option1" id="sub_myselect" onchange="this.form.submit()">
{% for y in sub_server_list %}
<option value="{{ y }}"{% if loop.first %} SELECTED{% endif %}>{{ y }}</option>
{% endfor %}
</td>
</form></table></h3>
<h3>Here is the choice: {{ choiced }}</h3>
<h3>Here is the choice: {{ total_choice }}</h3>
</body>
</html>
Any pointers or ideas would be greatly appreciated.
Have a look at sessions. You might have to change the way you store your data though, maybe by finding an appropriate name for choiceand choice1 and storing them in a dict.

request.method == 'GET', but has no items within the GET QueryDict object [duplicate]

This question already has answers here:
django MultiValueDictKeyError error, how do I deal with it
(9 answers)
Closed 8 years ago.
After trawling the internet for hours trying to no avail, I've come here in hope that maybe somebody can steer me in the correct direction.
So I'm new to django and stuck trying to use ajax in a template to pass data to a view. I have drop down menus that are populated from a database and when the user selects the type of result and model, I'm just trying to get it to pass these values to the view method. The reason why I'm doing this is because the view page populates the template (using extends), by generating an html page via a perl script that accepts these variables (result, model).
view.py
def platform_pass_rate(request):
#some other stuff
#This is currently always true
if request.method == 'GET':
#It is an issue however, because this never gets anything, just as request.GET.items() returns nothing
resultVar = request.GET['resultValue']
# modelVar = request.POST['selectedModelValue']
subprocess.call(["perl", "static/static/perl/passRateByPlatform.pl", resultVar, "Ahmed_00"])
#This calls the perl script. Currently set up so that just a default result is entered - so I now GET is working
else:
subprocess.call(["perl", "static/static/perl/passRateByPlatform.pl", "liftforce", "Ahmed_25"])
#Default html page created by script when user does not select anything
current_url = get_full_path(request)
return render_to_response("data_form_platform.html", {'our_url': current_url, 'study_models': study_models,'study_results': study_results})
urls.py
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('AppFalconV1.views',
# Examples:
url(r'^$', 'home'),
url(r'^Pass_Rate_by_Build/$', 'build_pass_rate'),
url(r'^Pass_Rate_by_Platform/$', 'platform_pass_rate'),
url(r'^Platform_Coverage/$', 'platform_coverage'),
url(r'^Regression_Coverage/$', 'regression_coverage'),
url(r'^Coverage_All_Builds/$', 'coverage_all_builds'),
# url(r'^test/$', 'get_current_url'),
url(r'^time/$', 'current_datetime'),
#url(r'^time/plus/(\d{1,2})/$', 'hours_ahead'),
url(r'^admin/', include(admin.site.urls)),
)
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Revised script in base.html
<script type="text/javascript">
$(document).ready(function () {
{# $.ajaxSetup({ cache: false });#}
var current_url = $('#current_url').text();
var id = current_url.trim();
$('#' + id).addClass('active');
$('#platform_data_form_button').click(function () {
var selectedResultValue = $('#platform_type_of_result :selected').text();
console.log(selectedResultValue);
var selectedModelValue = $('#platform_models :selected').text();
console.log(selectedModelValue);
$('#platform_type_of_result').change(function () {
var selectedResultValue = $('#platform_type_of_result :selected').text();
console.log(selectedResultValue);
});
$('#platform_models').change(function () {
var selectedModelValue = $('#platform_models :selected').text();
console.log(selectedModelValue);
});
$.get("/Pass_Rate_by_Platform/", { resultValue: selectedResultValue, modelValue: selectedModelValue}, function (response) {
console.log("workinggggggg");
//alert(response);
});
});
});
</script>
Location of dropdown buttons - data_form_platform.html
{% extends 'platform_pass_rate.html' %}
{% block data_form_platform_content %}
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<label class="col-md-2 control-label" for="type_of_result">Type of result</label>
<div class="col-md-3">
<select id="platform_type_of_result" name="type_of_result" class="form-control">
{% for result in study_results %}
{% if result != "testid" and result != "studyid"%}
<option value="{{ result }}">{{ result }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="model">Model</label>
<div class="col-md-3">
<select id="platform_models" name="model" class="form-control">
{% for model in study_models %}
<option value="{{ model }}">{{ model }}</option>
{% endfor %}
</select>
</div>
<label class=" control-label" for="model"></label>
<div class="col-md-1" style="margin-left: -20px" id="platform_data_form_button">
<a href="" class="btn btn-primary btn-success" ></span> Confirm</a>
</div>
</div>
</fieldset>
</form>
{% endblock %}
This just seems to be a problem with your Javascript. You're getting the value for selectedResultValue when the page is first loaded, presumably when no value is selected. The Ajax request is made when the button is clicked, but you don't fetch the new value inside that click function: so you still use the old, empty value. Just move that line inside the function.

Categories