how to dynamically show form input fields base on user selection from dropdown options - javascript

I have this form that is used to enter student grades per subject now on this form I have 3 dropdown boxes that are dependent on each other, what I want to accomplish is that after the user selects the classroom that the students are in, I want the input fields for each subject to appear on the same form that is only in that class that the user selected so that the user can enter the grades of the students per subject but I am having a hard time figuring out how to implement such behavior. in short,i want to show input fields for subjects base on the classroom the user selected
form.py
<div class="container-fluid">
<form id="result-form" method="post">
{% csrf_token %}
<!-- Modal -->
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel"> {% block modal-title%} Add Result {% endblock%}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12" id="msg8" style="font-size: 2rem; color:rgb(255, 144, 47)"></div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Class Name</label>
{% render_field form.room class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Exam Name</label>
{% render_field form.exam class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Student</label>
{% render_field form.student class+="form-control select2" %}
</div>
<div class="hidden" id="subject-fields"></div>
<div class="form-group mb-3 pt-2">
<button type="button" id="resBtn" class="btn btn-info" title="Add">Submit</button>
</div>
</div>
</div>
</form>
</div>
{% block script%}
<script>
$(document).ready(function () {
$('#id_room').change(function(){
var url = "{% url 'load_exams' %}"
var class_id = $(this).val();
$.ajax({
url: url,
data: {
'room':class_id
},
success: function(data){
$("#id_exam").html(data)
}
})
})
$('#id_room').change(function () {
var url = "{% url 'load_students' %}"
var class_id = $(this).val();
$.ajax({
url: url,
data: {
'room': class_id
},
success: function (data) {
$("#id_student").html(data)
}
})
})
$('.select2').select2({
placeholder: 'Please Select Here',
width: '100%',
dropdownParent: $('#addmodal')
});
$('#resBtn').click(function () {
let room = $('#id_room').val();
let exam = $('#id_exam').val();
let student = $('#id_student').val();
let csr = $('input[name="csrfmiddlewaretoken"]').val();
if (room == '' && name == '') {
$('#msg4').html('All fields are required').fadeIn('slow');
$('#msg4').delay(7000).fadeOut('slow');
} else {
mydata = {
exam: exam, csrfmiddlewaretoken: csr, room: room, student: student
};
console.log(mydata)
$.ajax({
url: "{% url 'add-result' %}",
data: mydata,
type: 'POST',
success: function (data) {
if (data.status == 'Save') {
$('#msg8').html('Result Successfully Added').fadeIn('slow');
$('#result-form')[0].reset();
$('#msg8').delay(3000).fadeOut('slow');
setTimeout(function () {
$('#addmodal').modal('hide')
}, 3000)
location.reload()
} else {
alert('Error with saving form')
}
}
})
}
});
})
</script>
{% endblock%}
forms.py
# deal with entering results
class ResultForm(forms.ModelForm):
class Meta:
model = Result
fields = ["room", "exam","student","percentage"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["exam"].queryset = Exam.objects.none()
if "room" in self.data:
try:
class_id = int(self.data.get("room"))
self.fields['exam'].queryset = Exam.objects.filter(room=class_id).order_by('name')
except(ValueError,TypeError):
pass
elif self.instance.pk:
self.fields['exam'].queryset = self.instance.classroom.exam_set.order_by('name')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["student"].queryset = Exam.objects.none()
if "room" in self.data:
try:
class_id = int(self.data.get("room"))
self.fields['student'].queryset = Student.objects.filter(room=class_id).order_by('name')
except(ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['student'].queryset = self.instance.classroom.exam_set.order_by('name')
# deal with entering grade per subject
class MarkForm(forms.ModelForm):
class Meta:
model = Mark
fields = ["result", "course","grade"]

Related

How do you implement input( or form) dependent on a select menu(drop down list)?

I'm working on grading system and I'm currently working on the form that's deals with the user entering the students results now the form I have, has 2 drop-down list(classroom, students) that are dependent. The issue and where I'm stuck is
When the user select the classroom the second drop-down menu will only show the students in that class, I have already figure that out..the issue is I want the input fields for how much subject the student is doing to appear so that the user can enter the grades for each subject specific to that student in the class
Eg if I select classroom 1b and selected student Mary.. if Mary is doing 5 subjects then 5 input field should appear so that I can enter the mark for the subjects
Link with a video showing what I'm talking about video showing an examplehttps://drive.google.com/file/d/11FoCZyOBVdUhTcvCqA1Ke0fEgRmMVC-G/view?usp=drivesdk
Models.py
Class Classroom(models.Models): name = models.charfield()
Class marks (models.Models): classroom = models.foreignkey(Classroom) Grade = models.Floatfield()
Html form
<div class="container-fluid">
<form id="result-form" method="post">
{% csrf_token %}
<!-- Modal -->
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel"> {% block modal-title%} Add Result {% endblock%}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12" id="msg8" style="font-size: 2rem; color:rgb(255, 144, 47)"></div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Class Name</label>
{% render_field form.room class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Exam Name</label>
{% render_field form.exam class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Student</label>
{% render_field form.student class+="form-control select2" %}
</div>
<div class="hidden" id="subject-fields"></div>
<div class="form-group mb-3 pt-2">
<button type="button" id="resBtn" class="btn btn-info" title="Add">Submit</button>
</div>
</div>
</div>
</form>
</div>
{% block script%}
{% endblock%
script
$(document).on('click', '#submit-btn', function(event){
var response_data = []
var subject_name= $('.course');
var subject_objs = $('.subject_id');
for(i=0;i<subject_name.length;i++){
var subject_id = $(subject_objs[i]).find('input').val();
var grade_input = {
"Marks": subject_id,
}
response_data.push(grade_input);
}
$.ajax({
type: "POST",
url: "{% url 'marks' %}",
data: response_data,
success: function(response){
alert("Success");
}
});
});
This is how your view should look like.
def question_choice_view(request):
if request.method == "POST":
question_choice_data = request.POST['data']
I am not a jQuery User. As far as i can see i would put a eventlistener on the student form via .addEventListener('change', (event)See here. This would fire a function every time something changes on the select option. With that you could also collect the selected option values of the classroom and student name and make a request to get the subject names for the chosen student. After successful response i would insert the subject fields via JavaScript in the DOM.
**
function createInput(item) {
// This function takes a item and creates a new input
var newLabel = ' <br><label for="$item-mark">$item:</label>'
var newInput = '<input type="text" id="$item-mark-id" name="$item-mark"><br><br>';
newLabel = newLabel.replaceAll("$item", item)
newInput = newInput.replaceAll("$item", item)
// combine into a single str
newInput = newLabel + newInput
var studInput = document.getElementById("student-id");
// insert element inputs after student
studInput.insertAdjacentHTML('afterend', newInput);
}
function cleanOldInputs(item) {
var oldELement = item + "-mark-id"
oldELement = document.getElementById(oldELement)
if (oldELement) {
// remove old label and input
oldELement.previousSibling.remove()
oldELement.remove()
} else {}
}
function getAPIcall() {
// This is what your API sends
var responsObject = ["writing", "creativity"];
// loop throug
responsObject.forEach(item => {
// if you already picked a student clean old inputs from DOM
cleanOldInputs(item)
// send to function for input creation
createInput(item)
})
}
// get the Student Input
var studentSelect = document.getElementById("student-id");
studentSelect.addEventListener("click", function() {
// Fire anything you like
getAPIcall()
});
<form action="/action_page.php">
<label for="student">Choose a student:</label>
<select name="student" id="student-id">
<option value="harry">harry</option>
<option value="ivy">ivy</option>
</select>
</form>
Quick and dirty**

JavaScript submit not working Django From

I have a simple form that uses JavaScript to validate and submit the form using POST to the database.
The script works for 2 forms but won't submit for other forms for some reason and I can't work out why. I've even copied the existing form and JS replaced it with new names and it still doesn't work and I cannot figure out why. I've tried to debug, but I'm getting http200 for every request so not throwing any errors that I can see.
Working version:
var investor_form = document.getElementById("add-investor");
investor_form.addEventListener("submit", function (e) {
e.preventDefault();
if (validated(this)) {
this.classList.add("was-validated");
var i_name = document.getElementById("investor-name").value;
var i_website = document.getElementById("investor-website").value;
var i_portfolio = document.getElementById("investor-portfolio").value;
var i_comment = document.getElementById("ckeditor-classic").value;
const csrftoken = document.getElementsByName("csrfmiddlewaretoken")[0].value;
const formdata = new FormData();
formdata.append("investor_name", i_name);
formdata.append("investor_website", i_website);
formdata.append("investor_portfolio", i_portfolio);
formdata.append("investor_comment", i_comment);
const xhr = new XMLHttpRequest();
xhr.open("POST", "/apps/add_investor");
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(formdata);
xhr.onload = () => {
window.location.reload();
};
}
})
// Form validation
function validated(form) {
console.log(form)
var i_name = document.getElementById("investor-name");
var i_website = document.getElementById("investor-website");
var i_portfolio = document.getElementById("investor-portfolio");
i_name_value = i_name.value.trim();
i_website_value = i_website.value.trim();
i_portfolio_value = i_portfolio.value.trim();
if (i_name_value === "") {
message = "Please fill investor name field"
setErrorFor(i_name, message);
} else {
setSuccessFor(i_name)
}
if (i_website_value === "") {
message = "Please fill investor website field"
setErrorFor(i_website, message);
} else if (!isUrl(i_website_value)) {
message = "Website is not valid"
setErrorFor(i_website, message);
} else {
setSuccessFor(i_website)
}
if (i_portfolio_value === "") {
message = "Please fill investor portfolio field"
setErrorFor(i_portfolio, message);
} else if (!isUrl(i_portfolio_value)) {
message = "Porfolio is not valid"
setErrorFor(i_portfolio, message);
} else {
setSuccessFor(i_portfolio)
return true;
}
}
// For Display Eroor
function setErrorFor(element, message) {
element.classList.remove('is-valid');
element.classList.add('is-invalid');
parent = element.parentNode;
for (var i = 0; i < parent.childNodes.length; i++) {
if (parent.childNodes[i].className == "invalid-feedback") {
notes = parent.childNodes[i];
notes.innerHTML = message;
break;
}
}
}
// For success Message
function setSuccessFor(element) {
element.classList.remove('is-invalid');
element.classList.add('is-valid');
}
// Check URL Pattern
function isUrl(url) {
var re = /(ftp|http|https):\/\/(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?/;
return re.test(url)
}
Non-working version with name changes
// Project Form submit
var project_form = document.getElementById("add-project");
project_form.addEventListener("submit", function (e) {
e.preventDefault();
if (validated(this)) {
this.classList.add("was-validated");
var i_name = document.getElementById("project-name").value;
var i_website = document.getElementById("project-website").value;
var i_comment = document.getElementById("ckeditor-classic").value;
const csrftoken = document.getElementsByName("csrfmiddlewaretoken")[0].value;
const formdata = new FormData();
formdata.append("project_name", i_name);
formdata.append("project-website", i_website);
formdata.append("project_comment", i_comment);
const xhr = new XMLHttpRequest();
xhr.open("POST", "/apps/add_project");
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(formdata);
xhr.onload = () => {
window.location.reload();
};
}
})
// Form validation
function validated(form) {
console.log(form)
var i_name = document.getElementById("project-name");
var i_website = document.getElementById("project-website");
i_name_value = i_name.value.trim();
i_website_value = i_website.value.trim();
if (i_name_value === "") {
message = "Please fill project name field"
setErrorFor(i_name, message);
} else {
setSuccessFor(i_name)
}
if (i_website_value === "") {
message = "Please fill project website field"
setErrorFor(i_website, message);
} else if (!isUrl(i_website_value)) {
message = "Website is not valid"
setErrorFor(i_website, message);
} else {
setSuccessFor(i_website)
return true;
}
}
// For Display Eroor
function setErrorFor(element, message) {
element.classList.remove('is-valid');
element.classList.add('is-invalid');
parent = element.parentNode;
for (var i = 0; i < parent.childNodes.length; i++) {
if (parent.childNodes[i].className == "invalid-feedback") {
notes = parent.childNodes[i];
notes.innerHTML = message;
break;
}
}
}
// For success Message
function setSuccessFor(element) {
element.classList.remove('is-invalid');
element.classList.add('is-valid');
}
// Check URL Pattern
function isUrl(url) {
var re = /(ftp|http|https):\/\/(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?/;
return re.test(url)
}
I've just done a find and replace for investor to project and then I have created copies of the forms/model/views/urls etc and updated to project
but it just won't update the database.
If I go into Django admin I can manually add the records, so I know the migration has worked.
response when clicking submit
[30/Oct/2021 20:10:36] "GET /apps/add_project HTTP/1.1" 200 32840
[30/Oct/2021 20:10:59] "POST /apps/add_project HTTP/1.1" 200 59
[30/Oct/2021 20:10:59] "GET /apps/add_project HTTP/1.1" 200 32840
views.py
class addProjectView(View):
template_name = 'pages/add_project.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name)
def post(self, request, *args, **kwargs):
form = addProjectForm(request.POST)
if form.is_valid():
form.save()
data = {"success": "successfully added"}
else:
data = {"error": form.errors}
return JsonResponse(data, safe=False)
add_project_view = addProjectView.as_view()
Models.py
class Project(models.Model):
project_name = models.CharField(max_length=255, blank=False)
project_website = models.URLField(max_length=255, blank=False)
project_comment = models.TextField()
def __str__(self):
return str(self.project_name)
Forms.py
class addProjectForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(addProjectForm, self).__init__(*args, **kwargs)
class Meta:
model = Project
fields = '__all__'
form html add_project.html
{% extends 'partials/base.html' %}
{% load static %}
{% block head_title%}
<title>Add Project | Dashboard</title>
{% endblock %}
{% block content %}
<div class="main-content">
<div class="page-content">
<div class="container-fluid">
<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
<h4 class="mb-sm-0 font-size-50">Add Project</h4>
<div class="page-title-right">
<ol class="breadcrumb m-0">
<li class="breadcrumb-item">Pages</li>
<li class="breadcrumb-item active">Project</li>
</ol>
</div>
</div>
</div>
</div>
<!-- end page title -->
</div> <!-- container-fluid -->
</div>
<div class="card-body">
<form class="needs-validation" id="add-project" novalidate method="post" enctype="multipart/form-data" onsubmit="return false;">
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="project-name-label">Project Name</label>
<input type="text" class="form-control" id="project-name" placeholder="Project Name">
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please fill project name.
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="project-url-input" class="form-label">Project Website</label>
<input class="form-control" type="url" placeholder="https://example.com" id="project-website">
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please provide a valid web address.
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Comments</h4>
<p class="card-title-desc">Please add any comments or notes</p>
</div>
<div class="card-body">
<textarea id="ckeditor-classic"></textarea><br>
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</div>
</div>
</form>
<!-- end col -->
</div>
<button type="button" class="btn btn-primary" id="toastMessage" hidden></button>
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div class="toast align-items-right text-white bg-primary border-0" id="toast-message" role="alert"
aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
Successfully added Project!
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"
aria-label="Close"></button>
</div>
</div>
</div>
<!-- End Page-content -->
{% endblock %}
{% block extra_js %}
<!-- ckeditor -->
<script src="{% static 'libs/#ckeditor/ckeditor5-build-classic/build/ckeditor.js' %}"></script>
<!-- init js -->
<script src="{% static 'js/pages/form-editor.init.js' %}"></script>
<!-- pristine js -->
<script src="{% static 'libs/pristinejs/dist/pristine.min.js' %}"></script>
<!-- form validation and XHR call -->
<script src="{% static 'js/pages/project.init.js' %}"></script>
{% endblock %}
Any ideas why its not working or how I can debug this?
Thanks

Duplicated element after Ajax run

I am trying to Auto-complete form fields using Ajax and Jquery.
First I used Django and the views.py function is:
def CreateWellMon(request):
if request.method == 'POST':
form = SurveillanceDesPuits_F(request.POST or None)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellMonitor')
else:
try:
PUITS_id = request.GET.get('PUITS')
record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
record2 = SurveillanceDesPuits.objects.get(id= record[0].id)
form = SurveillanceDesPuits_F(instance=record2)
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
except:
record2 = SurveillanceDesPuits.objects.all().first()
form = SurveillanceDesPuits_F(instance=record2)
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
So here I just selected the last record from the database at first. After when the user chooses a Well it reloads the last record of the element.
my HTML page code is:
{% extends 'Home/base2.html' %}
{% block content %}
{% load crispy_forms_tags %}
<div class="w3-panel w3-border w3-light-grey w3-round-large sizeA"> <h2>Well Information</h2> <h2 class="border-bottom pb-1 mb-3"><b>Add New montoring record 3</b></h2> </div>
{% if form %}
<div class="border p-3 mb-3 mt-3 w3-round-large w3-light-grey border-dark">
<form method="POST" id="SurveillanceDesPuits_F" data-record-url="{% url 'Add_wellMntr' %}">
{% csrf_token %}
<!-- form from views.py-->
<div class="border p-2 mb-3 mt-3 border-secondary">
<div class="form-row">
<div id= "PUITS" class="form-group col-md-3 mb-0">
{{form.PUITS|as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.CS |as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.MODE|as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.SITUATION |as_crispy_field}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3 mb-0">
{{ form.DATE_TEST|as_crispy_field }}
</div>
<div id='DUSE' class="form-group col-md-3 mb-0">
{{ form.DUSE|as_crispy_field }}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.PRES_TBG|as_crispy_field }}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.PRES_CSG|as_crispy_field }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.OBSERVATION|as_crispy_field }}
</div>
</div>
</div>
<input class="btn btn-success mb-4" type="submit" value="ADD Record">
</form>
</div>
{% endif %}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript"> $(document).ready(function(){
$("#id_PUITS").change(function(){
var url = $("#SurveillanceDesPuits_F").attr("data-record-url");
var PUITSId = $(this).val();
$.ajax({
type: 'GET' ,
url: url,
data: {
'PUITS': PUITSId
},
success: function (data){
$('#SurveillanceDesPuits_F').html(data);
}
});
});
return false;
}); </script>
{% endblock content %}
The problem is that after selecting a well the AJAX duplicates some elements in the page as described in the photo.
and how I do to solve this and keep the selected well because it is a choice field?
First I made a change in models.py, I deleted to_field='WellID', so it will keep the selected well after the AJAX call.
class SurveillanceDesPuits(models.Model):
PUITS = models.ForeignKey(Surveill_Wells , on_delete=models.CASCADE)
DATE_TEST= models.DateField()
....
then I changed the views.py:
def CreateWellMon(request):
if request.method == 'POST':
form = SurveillanceDesPuits_F(request.POST or None)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellMonitor')
else:
try:
PUITS_id = request.GET.get('PUITS')
record2 = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
return JsonResponse({'record2': list(record2.values())}, safe=False)
except:
form = SurveillanceDesPuits_F()
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
the last change is in the HTML page and the ajax code call will be as:
<script type="text/javascript">
$.ajax({
type: 'GET' ,
url: url,
data: {'PUITS': PUITSId },
dataType: "json",
success: function (response){
var response = JSON.parse(response);
const object = response[0]
$("#id_PUITS").val(object.fields.PUITS);
$("#id_DATE_TEST").val(object.fields.DATE_TEST);
$("#id_MODE").val(object.fields.MODE);
$("#id_CS").val(object.fields.CS);
$("#id_SITUATION").val(object.fields.SITUATION);
$("#id_DUSE").val(object.fields.DUSE);
$("#id_PRES_TBG").val(object.fields.PRES_TBG);
$("#id_PRES_CSG").val(object.fields.PRES_CSG);
$("#id_PRES_AVD").val(object.fields.PRES_AVD);
$("#id_RESEAU_GL").val(object.fields.RESEAU_GL);
$("#id_ANNULAIRE_TECH").val(object.fields.ANNULAIRE_TECH);
$("#id_OBSERVATION").val(object.fields.OBSERVATION);
$("#id_Controle_Pression_ENSP").val(object.fields.Controle_Pression_ENSP);
$("#id_Test_Puits").val(object.fields.Test_Puits);
$("#id_Controle_Pression_DP").val(object.fields.Controle_Pression_DP);
},
});
return false;
});
</script>
this will avoid the duplicated page caused by the
$("#SurveillanceDesPuits_F").html(response);
Many thanks

Displaying comments using Ajax

i am working on a project using Django. There are lists of users posts in homepage and each post has a comment form. I was able to implement comment properly on views, but the issue now is when I submit a comment it display empty string instead of the comment, the comment display in chrome console. How do i display comment on each post by user when a form is submitted. I attached an image to my questioin to clarify my question.
home.html
<div id="newfeeds-form">
{% include 'ajax_newfeeds_comments.html' %}
</div>
ajax_newfeeds_comments.html
<!-- New Feeds comment Text -->
{% for post in all_images %}
<div class="container newfeeds-comment" id="display-comment">
{% for comment in post.comments_set %}
<div class="row">
<div class="col-1 col-md-1 col-lg-1">
{% if comment.user.profile.profile_pic %}
<img src="{{ comment.user.profile.profile_pic.url }}" class="d-flex rounded-circle" alt="image" height="28" width="28">
{% endif %}
</div>
<div class="col-10 col-md-10 col-lg-10 p-2 ml-1" id="user-commentpost">
<span class="comment-post truncate">
<span class="name text-lowercase">{{ comment.user }}</span>
{{ comment.comment_post }}</span>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
<span class="md-form">
<form enctype="multipart/form-data" class="feeds-form form-inline md-form form-sm" method="POST" action="{% url 'site:home' %}" id="newfeeds-form{{ post.id }}">
{% csrf_token %}
<input type="hidden" value={{post.id}} name="post_comment">
<img src="{{ request.user.profile.profile_pic.url }}" class="rounded-circle avatar-img" height="28" width="28">
<textarea name="comment_post" class="textinput textInput animated fadeIn" placeholder="Add a comment..." required="" id="id_comment_post{{ post.id }}" onkeyup=""></textarea>
<button type="submit" class="submit" id="submit1-{{post.id}}"><i class="fas fa-paper-plane"></i></button>
</form
</span>
Views:
def home_view(request):
#All posts in new feed
all_images = Post.objects.filter(
Q(poster_profile=request.user, active=True)|
Q(poster_profile__from_user__to_user=request.user, active=True)|
Q(poster_profile__to_user__from_user=request.user, active=True)|
Q(poster_profile__profile__friends__user=request.user, active=True)).distinct().exclude(
Q(hide_post=request.user, active=True)|
Q(poster_profile__profile__blocked_users__user=request.user, active=True))
#Comment form homepage
if request.method == 'POST':
post_id = request.POST.get("post_comment")
post_obj = Post.objects.get(pk=post_id)
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.user = request.user
comment.commented_image = post_obj
comment.save()
# messages.info(request,'You submitted a comment')
#return redirect('/')
else:
form = CommentForm()
context = {
'form': form,
'all_images': all_images,
}
if request.is_ajax():
html = render_to_string('ajax_newfeeds_comments.html', context, request=request)
return JsonResponse({'form': html})
return render(request,'home.html', context)
Ajax:
<script type="text/javascript">
//HomeFeeds Comment
$(document).ready(function() {
$('.feeds-form').on('submit', onSubmitFeedsForm);
$('.feeds-form .textinput').on({
'keyup': onKeyUpTextInput,
'change': onKeyUpTextInput
});
function onKeyUpTextInput(event) {
var textInput = $(event.target);
textInput.parent().find('.submit').attr('disabled', textInput.val() == '');
}
function onSubmitFeedsForm(event) {
event.preventDefault();
console.log($(this).serialize());
var form = $(event.target);
var textInput = form.find('.textinput');
var hiddenField = form.find('input[name="post_comment"]');
$.ajax({
type: 'POST',
url: "{% url 'site:home' %}",
data: form.serialize(),
dataType: 'json',
beforeSend: function() {
form.find('.submit').attr('disabled', true);
},
success: function(response) {
$('#newfeeds-form' + hiddenField.val()).html(response.form);
textInput.val('');
var numberOfCommentsElement = $('#number-of-comments');
numberOfCommentsElement.text(parseInt(numberOfCommentsElement.text()) + 1);
},
error: function(rs, e) {
console.log(rs.resopnseText);
},
complete: function() {
textInput.trigger('change');
}
});
}
});
</script>
You don't need ajax actually, you can simply:
let value = $('myInput').val();
$('myCommentContainer').prepend(`
Format the comment as you want ${value}
`)
$('myInput').val('') // To empty the value
now call the ajax normally:
$({
type: 'POST',
url: "{% url 'site:home' %}",
data: form.serialize(),
dataType: 'json',
beforeSend: function() {
form.find('.submit').attr('disabled', true);
},
success: function(response) {}
})
Done, leave the success empty
appending it within the ajax success will make it slower anyway!

AJAX update list of object

Can someone help me and say whats wrong I did?
In my django project I have product_detail page which has comment part. I am tring to update comments list after successfully adding new comment with AJAX. Unfortunatly it updates all page. I am little bit comfused and need advice. I need to update only list of comments not all page.
product_detail.html:
<div class="card">
<div class="card-block">
<table id="comment-table">
<thead>
<tr>
<th>Author</th>
<th>Date</th>
<th>Comment Text</th>
</tr>
</thead>
<tbody>
{% include 'project/comment_list.html' %}
</tbody>
</table>
</div>
<div class="card-footer">
<form method="post" class="comment-form" id="comment-form" action="{% url 'project:comment_add' project_code=project.code product_code=product.code %}">
{% csrf_token %}
{% for field in form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
{% render_field field class="form-control" %}
{% for error in field.errors %}
<p class="help-block">{{ error }}</p>
{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
</div>
views.py:
def comment_add(request, project_code, product_code):
data = dict()
project = get_object_or_404(Project, pk=project_code, status='open')
product = get_object_or_404(Product, pk=product_code)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.author = request.user
comment.save()
product.comments.add(comment)
data['form_is_valid'] = True
data['html_comment'] = render_to_string('project/comment_list.html', {'product': product})
form = CommentForm()
else:
data['form_is_valid'] = False
else:
form = CommentForm()
context = {'project': project, 'product': product, 'form': form}
return render(request, 'project/product_detail.html', context)
js:
$(function () {
var saveForm = function () {
var form = $(this);
$.ajax({
url: form.attr("action"),
data: form.serialize(),
type: form.attr("method"),
dataType: 'json',
success: function (data) {
if (data.form_is_valid) {
$("#comment-table tbody").html(data.html_comment);
}
else {
$("#comment-form").html(data.html_comment_form);
}
}
});
return false;
};
$("#comment-form").on("submit", ".comment-form", saveForm);
});
The problem is type="submit" native refresh new page. You have to stop form submitting. Try something like this:
$("#comment-form").submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
// here your ajax code
});

Categories