DOM not validating form - javascript

DOM is driving me crazy! I did everything right but still not working. I am trying to validate form in Jinja via DOM or Javascript using innerHTML before submitting the form in flask. I know I am doing the right thing but the div doesn't change. I need your help guys. What am I doing wrong ?
{% extends "layout.html" %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data" class="form">
<fieldset>
<legend> <h5>{{ legend }} </h5></legend>
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.course_name.label(for="name") }}<br>
{% if form.course_name.errors %}
{% for error in form.course_name.errors %}
{{ form.course_name(size=100, class="form-control", id="name", placeholder="Enter course name") }}<br>
<span style="color: red;">{{ error }}</span>
<h1 id="nameeee" style="color: red;"></h1>
{% endfor %}
{% else %}
{{ form.course_name(size=100, class="form-control", id="name", placeholder="Enter course name") }}<br>
{% endif %}
</div>
<p>
{{ form.submit(class="btn btn-primary", id="submit") }}
</p>
</form>
<script type="text/javascript">
const name_course = document.getElementById('name');
const submit = document.getElementById('submit');
const name = document.getElementById('nameeee')
submit.addEventListener('click', () =>{
if (name_course.value.length < 1){
name.textContent = "Name must not be empty";
alert(name_course.value.length);
};
});
</script>
{% endblock %}

Not sure on what you mean by right thing but the div doesn't change. Please expand on this in the comments if the proposed solution below doesn't solve the problem.
I believe in this case the jinja HTML render
{{ form.submit(class="btn btn-primary", id="submit") }}
does not achieve the purpose of submitting the form to the back-end. It's is not equivalent to having a submit button, as so
<button type="submit"> Send </button>
that performs the method and action set on your opening form tag. Try with this <p>{{ form.submit() }}</p> and see if it solves the problem.

It did not work because the h1 was placed inside the loop. So I had to take the h1 out of the loop.
<h1 id="nameeee" style="color: red;"></h1>

Related

How to get only checked elements from a form in shopify?

{% assign type_bonbon = "Sans sucre, Gélifié, Guimauve, Nougat, Acide, Doux" | split : ", " %}
<section class="page__content">
{% capture contact_form %}
<div class="contact">
{% form 'contact', class: 'contact__form' %}
<div class="form__control">
<label class = "form__label" for="contact__type_bonbon">Types de bonbons</label>
{% for type in type_bonbon %}
<div class = "checkbox">
<input type="checkbox" id="contact__type_bonbon" name="contact[type]" value="{{type_bonbon}}">{{type}}
</div>
{% endfor %}
</div>
{% endform %}
</div>
{% endcapture %}
</section>
Hello everyone,
I am struggling to Get every checked values within the checkbox.
Right now im getting only the last checked value
I know in PHP we would use the GET method in order to put the "checked" method to every checkbox checked, however, idk how to proceed in shopify.
Thank you again
I just checked and I was able to replicate the behavior that you mentioned above about receiving only the last checked value. I don't know if it is a bug or feature from Shopify, but you can use a workaround like below where each field is named differently. Another minor thing is the ID attribute needs to be unique while it generates the same in your for loop above. Besides, that for value it should have been value="{{type}}" instead of value="{{type_bonbon}}" as type_bonbon is an array.
{% assign type_bonbon = "Sans sucre, Gélifié, Guimauve, Nougat, Acide, Doux" | split : ", " %}
<section class="page__content">
{% capture contact_form %}
<div class="contact">
{% form 'contact', class: 'contact__form' %}
<div class="form__control">
<label class = "form__label" for="contact__type_bonbon">Types de bonbons</label>
{% for type in type_bonbon %}
<div class = "checkbox">
<input type="checkbox" name="contact[type-{{type}}]" value="{{type}}">{{type}}
</div>
{% endfor %}
</div>
{% endform %}
</div>
{% endcapture %}
</section>
Only this line of code is changed, to generate new field name for each type.
<input type="checkbox" name="contact[type-{{type}}]" value="{{type}}">{{type}}

How can I modify this JS function so that it runs whenever the field is equal a certain length?

I have a function that currently runs whenever the user clicks/tabs out of the employee_number field. I would like it to run whenever the length of the numbers entered is equal to 6, without having to leave the field, since when I try using the tab, it conflicts with loading the next field which is a drop-down that is part of the function ran.
I tried by running it using .change and putting the constraint within the function, but it did not work and I don't know what else to try.
enter_exit.html
{% extends "base.html" %}
{% load core_tags staticfiles %}
{% block main %}
<form id="warehouseForm" action="" method="POST" data-employee-activity-lookup-url="{% url 'operations:employee_activity_search' %}" novalidate >
{% csrf_token %}
<div>
<div>
<div id="employee-name" style="margin-bottom: 10px"> </div>
<label>Employee #</label>
{{ form.employee_number }}
</div>
<div=>
<label>Work Area</label>
{{ form.work_area }}
</div>
<div style="display: none" id="my-hidden-div">
<label>Station</label>
{{ form.station_number }}
</div>
</div>
<div>
<div>
<button>Enter Area</button>
<button>Exit Area</button>
</div>
</div>
</form>
<script>
// Grab the employee name and their current active work log (if any)
$(document).on('blur', "#{{ form.employee_number.id_for_label }}", function(){
var url = $("#warehouseForm").attr('data-employee-activity-lookup-url');
var employeeId = $(this).val();
# ... more fields ...
if (employeeId !== "") {
# .. Rest of function ...
})
</script>
{% endblock main %}
Instead of using on blur have you tried using .keyup or .keydown?
Here's a simple version of it working in CodePen:
$("#test1").keydown(()=>{
if($("#test1").val().length>6)
console.log('6+');
})
https://codepen.io/orunnals/pen/JjoRGLX

Ajax working on Localhost but not on Live Server

I'm working on a website on which users can comment something below the posts, running on Python & Django.
As soon as a user comments something, then I'm updating comments without refreshing the web-page. Here's the code,
In views.py
postType1 = sorted(Posts.objects.filter( . . . ), key=lambda x: random.random())
postType2= Posts.objects.filter( . . . )
In template,
// BLOCK - 1
{% for post in postType1 %}
<p>{{ post }}</p>
<div class="comm_update" action="{% url 'comment:create' post.id %}">
<form class="comm_form" action="{% url 'comment:create' post.id %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<textarea id="id_comment"></textarea><br /><br />
<button type="submit">Submit</button>
</form>
</div>
{% endfor %}
<hr />
// BLOCK - 2
{% for post in postType2 %}
<p>{{ post }}</p>
<div class="comm_update" action="{% url 'comment:create' post.id %}">
<form class="comm_form" action="{% url 'comment:create' post.id %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<textarea name="comment_text" id="id_comment"></textarea><br />
<button type="submit">Submit</button>
</form>
</div>
{% endfor %}
Auto updating comments without refreshing webpage,
$(document).on("submit", ".comm_form", function(t) {
t.preventDefault();
var o = $(this),
e = $.post(o.attr("action"), o.serialize()),
n = o.attr("action");
e.done(function(t) {
var e = $(t).find(".comm_update[action='" + n + "']");
o.closest(".comm_update").html(e), o[0].reset()
})
});
On localhost everything is working fine.
*But on live server the first block BLOCK - 1 is not updating the comments, instead when user presses submit entire comment section disappears.
How can we fix this issue?
Thank You!

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