Reputation:
<form id="form" name="form">
<input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Asthma">
<input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Congenital Anomalies">
<input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student use Contact lens">
</form>
i have this code in my html
<script type="text/javascript">
// when page is ready
$(document).ready(function() {
// on form submit
$("#form").on('submit', function() {
// to each unchecked checkbox
$(this + 'input[type=checkbox]:not(:checked)').each(function () {
// set value 0 and check it
$(this).attr('checked', true).val(0);
});
})
})
</script>
my problem is everytime i save into my database the result always automatic YES, even i unchecked the checkbox(NO) in the html. i dont know if i am doing right in my javascript
this is my views.py
Asthma = request.POST['Asthma']
Congenital = request.POST['Congenital']
Contact = request.POST['Contact']
V_insert_data = StudentUserMedicalRecord(
Asthma=Asthma,
CongenitalAnomalies=Congenital,
ContactLenses=Contact
)
V_insert_data.save()
models.py
Asthma=models.BooleanField(null=True, blank=True, default=False)
CongenitalAnomalies=models.BooleanField(null=True,blank=True, default=False)
ContactLenses=models.BooleanField(null=True,blank=True, default=False)
even i insert record from my html is unchecked(No), the result always automatic "Yes" in my database, can you please fixed my javascript code? seems like its not working.
Upvotes: 7
Views: 1360
Reputation: 663
Cited text taken from this source: https://docs.joomla.org/Talk:Checkbox_form_field_type
The same problem not only applies to the Joomla project but also to other web apps or websites using checkboxes (especially note the bold part).
Special care needs to be taken with saving an unchecked checkbox from a form!! This is a common mistake for component developers thinking Joomla takes care of this. Joomla doesn't, until now. (Problem in Joomla 2.5 still.)
You see, on saving a form with a checkbox that is unchecked, there is no variable for it in the POST data! So, it's quite common that the value will NOT be overwritten in your DB, especially if it is already on the value that represents "checked" (e.g. 1 ) on the form.
That's what the JavaScript snippet in your question is for.
// when page is ready
$(document).ready(function() {
// on form submit
$("#form").on('submit', function() {
// to each unchecked checkbox
$('input[type=checkbox]:not(:checked)').each(function() {
// set value 0 and check it
$(this).attr('checked', true).val(0);
})
})
})
I removed the $(this +
part because that breaks things.
To clarify: the script checks unchecked checkboxes (to make sure there is a checkbox being posted). But at the same time it changes the value when in checked
state to 0 (!)
So if you have unchecked boxes, they will represent 0's instead of being left out of POST request data. And when you have checked items yourself it leaves them alone and it will represent as a value of 1 within the POST data for the checkbox(es).
Duplicate ID's are also something you need to prevent. It's not valid HTML5.
Also you have this code:
request.POST['Asthma']
I've checked and found it returns a QueryDict
. Found that on this page:
https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict
Example from that page:
QueryDict('a=1&a=2&c=3')
returns: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
This means that e.g. request.POST['Asthma']
would always return a list, which might be cast to a boolean type. So no matter what's in the list, it might cast to True
always.
So when you read on it says this:
QueryDict.__getitem__(key)¶
Returns the value for the given key. If the key has more than one value, it returns the last value.
So better use __getitem__(key)
or its alias here:
QueryDict.get(key, default=None)¶
Uses the same logic as getitem(), with a hook for returning a default value if the key doesn’t exist.
Of course, using the JavaScript snippet is one method you can use. But if you prefer to handle this in your Python code you can just use the QueryDict
like this:
Asthma = request.POST.get('Asthma', '0')
Upvotes: 2
Reputation: 711
Remove all javascript. That's converting all 0s to 1. Use this in views.py
Asthma = request.POST.get('Asthma', 0) # 0 not '0'
Congenital = request.POST.get('Congenital', 0) # 0 not '0'
Contact = request.POST.get('Contact', 0) # 0 not '0'
instead of this:
Asthma = request.POST['Asthma']
Congenital = request.POST['Congenital']
Contact = request.POST['Contact']
-------------Edit------------------
views
Asthma = request.POST.get('Asthma', 0) == '1'
Congenital = request.POST.get('Congenital', 0) == '1'
Contact = request.POST.get('Contact', 0) == '1'
V_insert_data = StudentUserMedicalRecord(
Asthma=Asthma,
CongenitalAnomalies=Congenital,
ContactLenses=Contact
)
V_insert_data.save()
Template
<input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Asthma">
<input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox2" title="Check if Student have Congenital Anomalies">
<input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox3" title="Check if Student use Contact lens">
Upvotes: 1
Reputation: 3920
You don't need javascript for that. Also forget about method="POST"
in your form (the default method is GET
).
In addition, for your views.py
, you need to use get
method of request.POST
to prevent KeyError
exception.
models.py
from django.db import models
class StudentUserMedicalRecord(models.Model):
Asthma = models.BooleanField(null=True, blank=True, default=False)
CongenitalAnomalies = models.BooleanField(null=True, blank=True, default=False)
ContactLenses = models.BooleanField(null=True, blank=True, default=False)
views.py
from django.shortcuts import render
from .models import StudentUserMedicalRecord
def sample_view(request):
if request.method == 'POST':
Asthma = request.POST.get('Asthma', '0')
Congenital = request.POST.get('Congenital', '0')
Contact = request.POST.get('Contact', '0')
instance = StudentUserMedicalRecord(
Asthma=Asthma,
CongenitalAnomalies=Congenital,
ContactLenses=Contact
)
instance.save()
return render(request, 'index.html', {})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Project</title>
</head>
<body>
<form id="form" name="form" method="POST"> {% csrf_token %}
<label>Asthma</label>
<input type="checkbox" value="1" name="Asthma" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Asthma">
<br>
<label>Congenital Anomalies</label>
<input type="checkbox" value="1" name="Congenital" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student have Congenital Anomalies">
<br>
<label>Contact lens</label>
<input type="checkbox" value="1" name="Contact" data-form-field="Option" class="form-check-input display-7" id="checkbox1" title="Check if Student use Contact lens">
<br>
<input type="submit" value="Save">
</form>
</body>
</html>
ModelForms
)You can use django's ModelForm
to prevent such issues with manually making the form.
So in this case, you would have:
forms.py - beside views.py
from django import forms
from .models import StudentUserMedicalRecord
class MedicalRecordForm(forms.ModelForm):
class Meta:
model = StudentUserMedicalRecord
fields = '__all__'
views.py
from django.shortcuts import render
from sample_app.forms import MedicalRecordForm
def sample_view(request):
if request.method == 'POST':
form = MedicalRecordForm(request.POST)
if form.is_valid():
form.save()
else:
form = MedicalRecordForm()
return render(request, 'index.html', {'form': form})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Project</title>
</head>
<body>
<form id="form" name="form" method="POST"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
</body>
</html>
find more about them in the docs.
Upvotes: 1
Reputation: 4519
Remove that Javascript code. You don't need it.
You don't really need to understand Javascript for this problem. The comments are telling you what is happening, but I will try to clarify:
// when page is ready
$(document).ready(function() {
// on form submit -> This means that this code will run when the form is submitted
$("#form").on('submit', function() {
// to each unchecked checkbox -> This means that each checkbox not checked, will run this code below
$(this + 'input[type=checkbox]:not(:checked)').each(function () {
// set value 0 and check it -> This means that
$(this).attr('checked', true).val(0);
});
})
})
If you want to learn more about it, this code is using jQuery with the function each (used to loop through elements) and the attr function (used to modify a HTML element's attribute).
Upvotes: 2