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

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"

Related

How to populate checkboxes in a table with values from a Django model

My html table has a column that contains a checkbox. The user can check or uncheck it. The value (boolean) is stored in the Django model Subscriber under Subscriber.participates. All objects of Subscriber are imported into the HTML using a Django view (context = {'subscribers' : Subscriber.objects.all(),}).
When loading the table, the checkboxes must be set to the correct value. To that purpose I have written a javascript function, which is invoked in the <input> element. However, the checkboxes all remain unchecked, though I have verified through /admin/ in Django that some of the values in the dbase are indeed "TRUE". firstName and lastName load without any problem into the table. What did I do wrong?
<head>
<meta charset="UTF-8">
<title>Participants</title>
<script>
function checkBox() {
if({{ x.participates }}){
document.getElementById("checkbox").checked = true;
} else {
document.getElementById("checkbox").checked = false;
}
}
</script>
</head>
<body>
<table>
{% for x in subcribers %}
<tr>
<form action="updateSuscribers/{{ x.id }}" method="post">
{% csrf_token %}
<td>{{ x.firstName }}</td>
<td>{{ x.lastName }}</td>
<td>
<input id="checkbox" type="checkbox" name="participates" onload="checkBox()">
</td>
</form>
</tr>
{% endfor %}
</table>
</body>
you don't need a js function to render existing data with the Checked/Unchecked Box.
assuming boolean field name is_subscribed
{% for sub in subscribers %}
{% if sub.is_subscribed %}
<input type="checkbox" checked>
{% else %}
<input type="checkbox">
{% endif %}
{% endfor %}
but Yes you gonna need js click event if you want it to update using the Click on Realtime without Refreshing page

Django request.method == 'POST' returning false

Currently working on my first django web application so still quite rusty.
Trying to create a page that allows a lecturer to create a new class, the class is then added to the lecturers list of classes.
As far as I can tell, from following a tutorial, the request.method in my views.py should return a POST, but is currently returning GET.
Because of this, the new class created is never saved to the database.
here is my views.py
def create_class(request):
if request.user.is_lecturer:
print(" ")
print("user is lecturer")
form = classForm()
print(request.method)
if request.method == 'POST':
print("")
print("request method equals post")
form = classForm(request.POST)
if form.is_valid():
lecturer = LecturerProfile.objects.get(lecturer=request.user)
subject = Class.objects.get_or_create(class_name=form.cleaned_data["class_name"],
class_description=form.cleaned_data["class_description"],
lecturer=lecturer)
LecturerProfile.Classes.add(subject)
form.save(commit=True)
return index(request)
else:
print("")
print(form.errors)
else:
print("")
print("request method fail")
else:
return HttpResponse("You are not allowed here")
return render(request, 'student_feedback_app/create_class.html', {'form':form})
forms.py
class classForm(forms.ModelForm):
subject = forms.CharField(max_length=40, help_text="Class Name", required=False)
class_description = forms.CharField(max_length=200, required=False, help_text="Class Description")
slug = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = Class
fields = ('subject', 'class_description',)
my create_class.html
<!DOCTYPE html>
<html>
<head>
Create a new class
<h1> Create a new class</h1>
</head>
<body>
<div>
<form id="" method="post" action="/lecturer/classes/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<br>
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<br>
<input type="submit" name="submit" value="Create Class" /> </form>
</div>
</body>
</html>
The errors that I get out at the terminal are
user is lecturer GET
request method fail
[11/Nov/2018 16:27:24] "GET /lecturer/create-class/ HTTP/1.1" 200 923
Not Found: /lecturer/create-class/js/plugins/jqBootstrapValidation.js
[11/Nov/2018 16:27:24] "GET /lecturer/create-class/js/plugins/jqBootstrapValidation.js HTTP/1.1" 404 4369
From the errors it would seem like it must be something to do with Bootstrap that the error is coming from, although i haven't used this for anything.
I even took out the base_template.html and wrote the create_class.html normally incase something from it was using javascript and bootstrap, but got the same output.
Any help is very appreciated

django bootstrap datetimepicker

i am trying to implement the datepicker using the django bootstrap datepicker widget, but the datepicker is not showing on the webpage ("welcome.html)
i have passed the form to the views and called the form in the webpage
any help will be appreciated
forms.py
class DateForm(forms.Form):
todo = forms.CharField(
widget=forms.TextInput(attrs={"class":"form-control"}))
date_1=forms.DateField(widget=DatePicker(
options={"format": "mm/dd/yyyy",
"autoclose": True }))
def cleandate(self):
c_date=self.cleaned_data['date_1']
if c_date < datetime.date.today():
raise ValidationError(_('date entered has passed'))
elif c_date > datetime.date.today():
return date_1
def itamdate(self):
date_check=calendar.setfirstweekday(calendar.SUNDAY)
if c_date:
if date_1==date_check:
pass
elif date_1!=date_check:
raise ValidationError('The Market will not hold today')
for days in list(range(0,32)):
for months in list(range(0,13)):
for years in list(range(2005,2108)):
continue
views.py
def imarket(request):
#CREATES A FORM INSTANCE AND POPULATES USING DATE ENTERED BY THE USER
if request.method=='POST':
form = DateForm(request.POST or None)
#checks validity of the form
if form.is_valid():
itamdate=form.cleaned_data['date_1']
return HttpResponseRedirect(reverse('welcome.html'))
return render(request, 'welcome.html', {'form':form})
welcome.html
{% extends 'base.html' %}
{% load bootstrap %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="//cdn.bootcss.com/bootstrap-datetimepicker/4.17.44/js/bootstrap-datetimepicker.min.js"></script>
{% block content %}
<title>welcome</title>
<form action = "{% url "imarket"}" method = "POST" role="form">
{% csrf_token %}
<table>
{{form|bootstrap_horizontal}}
</table>
<div class = "form-group">
<input type ="submit" value= "CHECK" class="form control"/>
</div>
</form>
{% endblock %}
The bootstrap datepicker wasn't working , so i added the jquery datepicker to directly to my forms. py using this answer
my updated forms.py
class DateForm(forms.Form):
todo = forms.CharField(
widget=forms.TextInput(attrs={"class":"form-control"}))
date_1=forms.DateField(widget=forms.DateInput(attrs={'class':'datepicker'}))
my updated welcome.html
{% extends 'base.html' %}
{% load bootstrap %}
{% block content %}
<title>welcome</title>
<form action = "{% url "imarket"}" method = "POST" role="form">
{% csrf_token %}
<table>
{{form|bootstrap}}
<script>
$(document).ready(function() {
$('.datepicker').datepicker();
});
</script>
</table>
<div class = "form-group">
<input type ="submit" value= "CHECK" class="form control"/>
</div>
</form>
{% endblock %}
datepicker should be initialized in the html page.
if you are using bootstrap download datepicker from Datetimepicker for Bootstrap 4
then
in the head section include
font awesome css
boostrap4 css
bootstrap-datetimepicker.min.css
in the body section include
moment.min.js
bootstrap.min.js
bootstrap-datetimepicker.min.js
define your form
from django import forms
class DateRangeForm(forms.Form):
start_date = forms.DateTimeField(required=True)
end_date = forms.DateTimeField(required=True)
in the template render the form
<form action="/your-name/" method="post">
{% csrf_token %}
{{ dt_range_form }}
<input class="btn btn-primary btn-sm" type="submit" value="Refresh">
</form>
in the script section add
$("#id_start_date").datetimepicker();
And here you have your datetimepicker! For me Time icon is still not showing up! Need to debug it.

Django: How can I create a dynamic form that changes on user click?

I'm making a workout calendar website where a user can add workouts with varying amounts of lift, sets and reps, etc. Thus, I need a form that adds a field when a user clicks a button. I've made a template and some javascript to describe what it is I want to achieve exactly:
url:
url(r'^add/(?P<year>[0-9]+)/(?P<month>[0-9]+)/(?P<day>[0-9]+)/$', views.add_workout, name = 'add_workout')
template:
{% block hidden %}
{% include "workoutcal/liftrow.html" %} {# To be used by Javascript #}
{% include "workoutcal/cardiorow.html" %}
{% endblock %}
<form action="{% url 'add_workout' date.year date.month date.day %}" method="post">
<div class="row">
<div class="col-xs-2">
<p id="date">{{ date.year }}-{{ date.month }}-{{ date.day }}</p>
<input type="hidden" name="date" value="{{ date }}">
</div>
</div>
<h2 class="col-xs-12">Lifts</h2>
<div id="liftrows">
{% for i in range %}
{% include "workoutcal/liftrow.html" %}
{% endblock %}
</div>
<div class="row">
<div class="col-xs-0"></div>
<label class="col-xs-2"><button type="button" id="addliftbutton">One more lift</button></label>
</div>
<h2 class="col-xs-12">Cardio</h2>
<div id="cardiorows">
{% include "workoutcal/cardiorow.html" %}
</div>
<div class="row">
<label class="col-xs-2"><button type="button" id="addcardiobutton">One more cardio</button></label>
</div>
<div class="row">
<div class="col-xs-10"></div>
<label class="col-xs-2"><input type="submit" id="submitbutton" value="Save Workout"></label>
</div>
</form>
javascript:
//Adding onclick to buttons
document.getElementById('addliftbutton').onclick = addLiftRow;
document.getElementById('addcardiobutton').onclick = addCardioRow;
for (var i=0; i<setsBoxes.length; i++){
setsBox = setsBoxes[i];
setsBox.onchange = insertRepFields;
}
function addLiftRow(){
var liftRowElements = document.getElementById('liftrows');
var hidden_liftrow = document.getElementById('hidden').getElementsByClassName('lift')[0];
var new_liftrow = hidden_liftrow.cloneNode(true);
liftRowElements.appendChild(new_liftrow);
}
function addCardioRow(){
var cardiorows = document.getElementById('cardiorows');
var hidden_cardiorow = document.getElementById('hidden').getElementsByClassName('cardio')[0];
var new_cardiorow = hidden_cardiorow.cloneNode(true);
cardiorows.appendChild(new_cardiorow);
}
function insertRepFields(){} // big function that inserts as many input fields as the number inside the box whose event called the function.
2 questions:
1. Is there a better way to do this in Django?
2. If this is the best way, how do I go about sending the data of my massive form back to django? Since I don't know exactly how many fields there will be, I don't know how to create a form that accepts a variable amount of fields, and fields within fields.
Here's how a filled-in form could look:
The best way to accomplish that is inserting inputs with the same name and then in Django get all those inputs as a list like:
def view(request):
inputs = request.POST.getlist('your_input_name')
for i in inputs:
Model.objects.create() # Save your model

How to write JQuery function to display text in special location of Django template

I'm trying to create my first ajax function in Django.
I want to change my code using JQuery, the idea is pretty simple:
User type a subject name and this name is displayed in subject-list below the form,
The problem is I don't really know what to type in JQuery function.
JQuery:
function create_subject() {
$("input").focus(function(){
var subject = $(this).val();
$(".btn-create").click(function(){
/* What I need to write in here */
});
});
}
In HTML "subjects" refer to database.
HTML
<div id="subjects-list">
{% if user.username %}
<ul>
{% if subjects %}
<form method="post" action=".">{% csrf_token %}
{% for subject in subjects %}
-------- TYPED TEXT SHOULD BE HERE --------> <li>{{ subject.name }}</li>
{% endfor %}
</form>
{% else %}
<p>No Subjects for this user</p>
{% endif %}
</ul>
{% else %}
You are in else
{% endif %}
</div>
That's how HTML looks in "View Page Source"
<div id="create-subject">
<form method="post" action="."> <div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='cfbd1893742c3ab9936bacaae9653051' /></div>
<p><label for="id_name">Subject Name:</label> <input id="id_name" type="text" name="name" size="9" /></p>
<input type="button" name="subject-create-b" value="Create Subject" class="btn-create"/>
</form>
</div>
<div id="subjects-list">
<ul>
<form method="post" action="."><div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='cfbd1893742c3ab9936bacaae9653051' /></div>
<li>Math 140<span id="subject-link"></span></li>
</form>
</ul>
</div>
</div>
And that's my form
forms.py
class SubjectCreationForm(forms.Form):
name = forms.CharField(label="Subject Name", widget=forms.TextInput(attrs={'size':9}))
class Meta:
exclude = ('created_by', 'created_time', 'num_of_followers', 'vote')
def clean_name(self):
name = self.cleaned_data['name']
if len(name)>1:
return name
else:
raise forms.ValidationError("Subject name should be longer")
In order to do what (I think) you want to do which is some basic AJAX using Django as your backend, you'll need the following:
A view which returns the data you want to load
There are a number of ways you can represent the data, but to keep it simple, I'll use HTML.
Javascript to load that view (using JQuery if you like)
Your code might look like this for the first part:
urls.py:
...
(r'^get-subjects/$', 'yourapp.views.get_subjects'),
...
views.py:
...
def get_subjects(request):
subjects = # code to fetch your subjects.
return render_to_response('subjects_template.html', {'subjects': subjects})
...
subjects_template.html:
{% for subject in subjects %}
<li>{{ subject.name }}</li>
{% endfor %}
For the second part, it might look like this:
main_template.html:
...
<ul id="subjects-list"></ul>
<script>
function loadSubjects() {
$.ajax({
url: "/get-subjects",
success: function (data) {
$("#subjects-list").html(data);
}
});
}
</script>
...
[1] render_to_response()
[2] jQuery.ajax()
This will get you most the way there. When you want to reload the list, you call the loadSubjects() function.
As far as creating the subjects go, that is a different thing. What you'll want to look into is how to do an HTML form submission without leaving the page. There are plenty of tools and libraries to do that stuff with a nice api. If you want to stick with JQuery, you might consider this plugin for a nicer api.
function create_subject() {
$("input").focus(function(){
var subject = $(this).val();
$(".btn-create").click(function(){
$('#subjects-list').append(subject);
});
});
}
that said, you probably don't want to assign the click handler every time the input is focused. i'd move that out of the focus handler.

Categories