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 %}
I also tried using keydown/keyup, but it would not even produce a call to the function. This is how I modified the JS
$("#{{ form.employee_number.id_for_label }}").keydown(()=>{
var url = $("#warehouseForm").attr('data-employee-activity-lookup-url');
var employeeId = $(this).val();
console.log(1); //Not even this appears
if (employeeId === 6) {
...
}
})
Any ideas on how to make this work?
If your id selector ("#{{ form.employee_number.id_for_label }}") is being parsed into a valid reference ("#id-1234-abc", for example), your next issue will be your conditional:
if (employeeId === 6) {…
That tests whether the input value, $(this).val(), is 6 — not how many characters. For that, you would want something like:
if ( employeeId.length === 6) {…
Related
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>
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
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"
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
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.