Adding Plus minus button in form with POST and scrf_tocken - javascript

With Django I generate a list of items, with the number of them.
To be more convenient, I would like to add a plus and a minus button.
I found a simple solution, but when I try to put this in my form with the POST method, if click the page refresh or POST ?
I don't want to refresh the page every time, I have a validate button and all the value will be treat in one time.
<form class"form-inline" action="{% url 'stock:stock' %}"method="post" >{% csrf_token %}
{% for stock in stocks %}
<div>
<button id="minusButton">-</button>
<input type="number" name="stock" id="stock" value="{{stock.stock}}" >
<button id="plusButton">+</button>
</div>
{% endfor %}
</form>
<script>
textInput = document.querySelector('#numberInput');
plusButton = document.querySelector('#plusButton');
minusButton = document.querySelector('#minusButton');
plusButton.onclick = () => textInput.value = parseInt(textInput.value) + 1;
minusButton.onclick = () => textInput.value = parseInt(textInput.value) - 1;
</script>
If anyone know how to manage?

Related

Dynamically added input fields aren't being submitted in request.form

I have a form in my input.html page and I have a set of input fields that is both programmatically generated by jinja2 and dynamically generated with Javascript. The inputs that are generated by jinja2 all show up in my request.form when I hit submit (i.e. into my POST function), but the dynamically created fields (with the + button next to a given element) aren't showing up. Which is strange, because if I inspect the page after adding a few new inputs, they... should?
Any ideas?
HTML
(explanation: this iterates through a ~dict and x has two text fields called question and tech-key (ex// "int"). This should print out the question with a 'plus sign' to allow the user to add new input fields dynamically. I include one by default (ex// name="{{x['tech_key']}}1" means name="int1". Every new input field that gets added increments (int1, int2, int3, etc...)
<div class="col-md-9">
{% for k,v in inps['sheet'].items() %}
{% for x in v %}
<div class="{{x['tech_key']}}">
<b>{{x['question']}}</b>
<button class="add_form_field" data-key="{{x['tech_key']}}"><b>+</b></button><br>
<div><input type="text" name="{{x['tech_key']}}1" size="80px"></div>
</div>
{% endfor %}
{% endfor %}
</div><br>
JavaScript
(explanation: This allows me for each individual named div (ex: the <div class="int"> above), to add new input fields when I click the + sign next to my product. I have them connected to the original form. They aren't pushing when I hit submit.
// adds new input fields when the + is clicked on a given question
$(document).ready(function() {
var max_fields = 10;
var add_button = $(".add_form_field");
var x = 1;
$(add_button).click(function(e){
use = $(this).attr("data-key")
var wrapper = "."+use
e.preventDefault();
if(x < max_fields){
x++;
var field_name = use + x
$(wrapper).append('<div><br><input type="text" form="input_form" name="'+field_name+'"/ size=80px><a class="'+field_name+'"><button><b>-</b></button></a></div>'); //add input box
}
$("."+field_name).click(function(){
$(this).closest('div').remove(); x--;
})
});
});
HTML copied directly from my page when I add two new input fields:
<div class="int">
<b>Did you conduct any interviews this quarter?</b>
<button class="add_form_field" data-key="int" data-ol-has-click-handler=""><b>+</b></button>
<div>
<br><input type="text" name="int1" size="80px">
</div>
<div>
<br><input type="text" form="input_form" name="int2" size="80px">
<a class="int2"><button><b>-</b></button></a>
</div>
<div>
<br><input type="text" form="input_form" name="int3" size="80px">
<a class="int3"><button><b>-</b></button></a>
</div>
</div>

How to avoid page reloading in my django front end?

every time I press submit button page gets reloaded.I have included preventdefault on submit.But it is not working.
Please help me.
This is part of html code .
Every time on submit I got redirected to another page.
I don't want page to reload. How to fix this.
<form id='form' method="POST">
{% csrf_token %}
{{form.as_p}}
<input type='hidden' id='myusername' value='{{user}}'>
<input type="submit" class='btn btn-primary'>
</form>
{% block script %}
<script src='https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.js'></script>
<script>
var loc=window.location
var wsStart='ws://'
var formData=$("#form")
var me=$("#myusername").val()
var Holder=$("#items")
var msgInput=$("#id_message")
if(loc.protocol=='https:'){
wsStart='wss://'
}
var endpoint=wsStart + loc.host + loc.pathname+'/'
var socket=new ReconnectingWebSocket(endpoint)
socket.onmessage=function(e){
console.log('message',e)
var Data=JSON.parse(e.data)
chatHolder.append('<li>'+Data.message+' via '+Data.username+'</li>')
}
socket.onopen=function(e){
console.log('open',e)
formData.submit(function(event){
event.preventDefault()
var msgText=msgInput.val()
var finalData={
'message':msgText
}
socket.send(JSON.stringify(finalData))
formData[0].reset()
})
}
socket.onerror=function(e){
console.log('error',e)
}
socket.onclose=function(e){
console.log('close',e)
}
</script>
{% endblock %}
store the content from your form in a context dict then pass it to the new page maybe?

How to call JS function whenever a field equals 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 %}
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) {…

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

Javascript Confirm continues regardless of user answer

I have an html template that I use with my Django website code. In the template are a couple of forms. Two of the forms are datefields and I have a confirm popup that is activated on submission if the user fills them in. I wanted the popup to exit the form submission and return to the page if the user clicks 'cancel', and to continue submitting the form if the user clicks 'ok'.
The confirm popup shows up correctly but the form submission continues no matter what the user clicks. How do I change it so that the form submission exits if the user clicks 'cancel'?
Javascript looks like this:
<script type="text/javascript">
var checkFields = ["SPAN_START","SPAN_END"];
function checkForm( theForm ) {
for (i in checkFields ) {
var fieldName = checkFields[ i ];
var theField = theForm[ fieldName ];
if ( theField.value ) {
var retVal = confirm("Are you sure you want to specify a date?");
if (retVal == true){
theField.submit()
return true;
} else {
return false;
}
}
}
}
</script>
The html where it is used looks like this:
<form action="/InterfaceApp/Nominal_Request/" method="post" class="form" onsubmit="checkForm( this )">
{% csrf_token %}
<div class="panel-body text-center">
{% bootstrap_form form_span_start %}
{% bootstrap_form form_span_end %}
{% buttons %}
<button type="submit" class="btn btn-primary center-block" value="Submit" name="Range">
{% bootstrap_icon "fire" %} Generate Range of Requests
</button>
{% endbuttons %}
</div>
</form>
Can anyone tell me how to cancel the submission of the form if the user clicks 'cancel'??
Much appreciated.
You have to return the value of the function to the inline event handler
onsubmit="return checkForm( this )"
preferably you wouldn't use inline event handlers at all, but addEventListener instead.

Categories