I am using jquery to clone elements in a form and send all the data to a fastapi app. The problem I am finding is fastapi is not picking up the extra elements in the form.
Here is the code:
<button id="{{x.employee_id}}" class="btn btn-success eventBtn">Add Subject</button>
<form action="/cxc?id={{x.employee_id}}" method="POST">
<div id="cxc_form{{x.employee_id}}">
<div id="add_form{{x.employee_id}}">
<div class="row">
<div class="col">
<label class="form-label" for="area">Area of study:</label><br>
<select class="form-control" name="area0" id="area0">
{% for area in areas %}
<option value="{{area.qualification_area_id}}">{{area}}</option>
{% endfor %}
</select>
</div>
<div class="col">
<label class="form-label" for="deg">Grades:</label><br>
<select class="form-control" name="deg0" id="deg0">
{% for weight in weight %}
<option value="{{weight.weight_id}}">{{weight}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="row">
<div class="col">
<label class="form-label" for="country">Country:</label><br>
<select class="form-control" name="country0" id="country0">
{% for country in countries %}
{% if country.country_id == 186 %}
<option value="{{country.country_id}}" selected>{{country.name}}</option>
{% else %}
<option value="{{country.country_id}}">{{country.name}}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="col">
<label class="form-label" for="yr">Year obtained:</label><br>
<input class="form-control" type="date" id="yr0" name="yr0" placeholder="Year received">
</div>
</div>
<hr>
</div>
</div>
<input class="btn btn-primary" type="submit" value="Add">
</form>
And the jquery:
let i = 1
$(document).ready(function() {
$(".eventBtn").click(function(e){
let id = e.target.id;
let f = "#add_form" + id
let c = "#cxc_form" + id
let old = $(f).clone()
old.find("select").each(function() {
this.name = this.name.replace('0', i)
this.id = this.id.replace('0', i)
})
old.find("input").each(function() {
this.name = this.name.replace('0', i)
this.id = this.id.replace('0', i)
})
$(old).appendTo(c);
i = i+1
});
});
And fastapi:
#app.post("/cxc")
async def add_cxc(id: int, request: Request, db: Session = Depends(get_db)):
form = await request.form()
print(form)
Does any one know why it is not giving me the data from the cloned elements. All I am getting in my request is
FormData([('area0', '1'), ('deg0', '1'), ('country0', '186'), ('yr0', '')])
Related
I'm trying to use js to save values in selected options. It works if js put it in my HTML template. Like this:
{% load static %}
{% include "header.html" %}
{% block content %}
<script src="{% static 'ReportingTool/js/sort_text.js' %}"></script>
<script src="{% static 'ReportingTool/js/sort_number.js' %}"></script>
...
<form method="GET" action=".">
<div class="row">
<div class="border border-2 p-2 g-2">
<label for="periodMin">Start date</label>
<input type="date" class="myselect form-select form-select-sm" id="periodMin"
name="period_min">
<label for="periodMax">End date</label>
<input type="date" class="myselect form-select form-select-sm" id="periodMax"
name="period_max">
</div>
<div class="border border-2 p-2 g-2">
<label for="structDivisions">Structural divisions</label>
<select id="structDivisions" class="myselect form-select form-select-sm"
name="struct_division">
<option selected>Choose...</option>
{% for SD in struct_divisions %}
<option id="{{ SD.id }}" value="{{ SD }}"> {{ SD }}</option>
{% endfor %}
</select>
<label for="workers">Worker</label>
<select id="workers" class="myselect form-select form-select-sm" name="worker">
<option selected>Choose...</option>
{% for worker in workers %}
<option value="{{ worker }}">{{ worker }}</option>
{% endfor %}
</select>
</div>
<div class="border border-2 p-2 g-2">
<label for="workDone">Work done</label>
<select class="myselect form-select form-select-sm" id="workDone" name="work_done">
<option selected>Choose...</option>
{% for work in workstype %}
<option value="{{ work }}">{{ work }}</option>
{% endfor %}
</select>
<label for="scope_min">Scope min</label>
<input type="number" min=0 class="myselect form-control form-control-sm" id="scope_min"
name="work_scope_min">
<label for="scope_max">Scope max</label>
<input type="number" min=0 class="myselect form-control form-control-sm" id="scope_max"
name="work_scope_max">
<label for="notes">Notes contains</label>
<input type="text" class="myselect form-control form-control-sm" id="notes"
name="work_notes_contains">
</div>
<div class="row border border-2 p-2 g-2">
<button type="submit"
value="sumbit"
name="button_search"
class="btn btn-outline-secondary w-100"
title="Search">
🔍
</button>
<button
name="button_export"
class="btn btn-outline-secondary w-100"
onclick=" location.href='{% url 'export_report' %}'"
title="Export csv">
💾
</button>
</div>
</div>
</form>
...
<script>
let selItems = JSON.parse(sessionStorage.getItem("SelItem")) || [];
$(function() {
if (selItems) {
selItems.forEach(obj => {
const [k, v] = Object.entries(obj)[0]
$("#" + k).val(v)
})
}
$('.myselect').on("change", function() {
selItems = $('.myselect').map(function() {
return { [this.id]: this.value }
}).get();
sessionStorage.setItem("SelItem", JSON.stringify(selItems))
});
});
</script>
{% endblock content %}
{% include "footer.html" %}
But if I put the script in a separate file:
{% load static %}
{% include "header.html" %}
{% block content %}
<script src="{% static 'ReportingTool/js/sort_text.js' %}"></script>
<script src="{% static 'ReportingTool/js/sort_number.js' %}"></script>
<script src="{% static 'ReportingTool/js/select.js' %}"></script>
select.js:
let selItems = JSON.parse(sessionStorage.getItem("SelItem")) || [];
$(function() {
if (selItems) {
selItems.forEach(obj => {
const [k, v] = Object.entries(obj)[0]
$("#" + k).val(v)
})
}
$('.myselect').on("change", function() {
selItems = $('.myselect').map(function() {
return { [this.id]: this.value }
}).get();
sessionStorage.setItem("SelItem", JSON.stringify(selItems))
});
});
it doesn't work. He doesn't understand what event he reacts to? I tried to add the name of the function and call click on the event. Nothing helps
What am I doing wrong?
change this:
<script src="{% static 'ReportingTool/js/select.js' %}"></script>
To
<script src="{% static '/ReportingTool/js/select.js' %}"></script> #You forgot to add forward slash(/) before ReportingTool.
Try and see if this is works
I am trying to make a loading screen when submitting a form. When I submit a form the page starts to load until the backend responds by downloading an excel file. The idea is to have the effect of "load screen" only until the file manages to download.
html:
<form action="{% url 'downloadStatusPickingCustomerByCollection' %}" method="POST">{% csrf_token %}
<div class="pnl-collection">
<div>
<div class="tituloPnl">
<h3>Estado Ordenes de Venta por Colección</h3>
</div>
<div class="btnExport">
<button onclick="loadDisplay()" class="btn btn-light" type="submit">Exportar</button>
</div>
</div>
<div class="filtro">
<div>
<div class="title-select"><span>Colección</span></div>
</div>
<div>
<select class="form-select form-select-sm form-down-report" name="collection-StatusCustomer-name" id="" required>
<option value="">- SELECCIONE COLECCIÓN -</option>
{% if collections %}
{% for collection in collections%}
<option value="{{collection.Name}}">{{collection.Name}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
</div>
</form>
javascript:
function loadDisplay() {
if (document.querySelector(".form-down-report").value != "") {
document.getElementById("preloader-camion").style.display = 'block';
jquery(window).load(
function () {
document.getElementById("preloader-camion").style.display = 'none';
});
}
}
I have the bakcend developed in django so in the form route you can see a django "url tag".
My html file has a select, with three different options. If you select one it will display different inputs depending on what option you choose, but these inputs are required by default, and I can't send the form if I don't fill all the inputs.
function yesnoCheck(that) {
if (that.value == "1") {
document.getElementById("ifStudent").style.display = "block";
} else {
document.getElementById("ifStudent").style.display = "none";
}
if (that.value == "2") {
document.getElementById("ifAcademic").style.display = "block";
} else {
document.getElementById("ifAcademic").style.display = "none";
}
if (that.value == "3") {
document.getElementById("ifWorker").style.display = "block";
} else {
document.getElementById("ifWorker").style.display = "none";
}
}
<div class="select">
<select onchange="yesnoCheck(this);" name="school_role" required>
<option value="">--------</option>
<option value="1">Student</option>
<option value="2">Academic</option>
<option value="3">Employee</option>
</select>
</div>
<div id="ifStudent" style="display: none;">
<label class="label">Account number</label>
<input class="input" type="text" name="account_number" value="{{ studentform.account_number.value }}" placeholder="Account number">
<div class="help is-danger">
{% for error in studentForm.account_number.errors %}{{ error }}{% endfor %}
</div>
<div id="ifEmployee" style="display: none;">
<label class="label">Employee Number</label>
<input class="input" type="text" name="employee_number" value="{{ employeeForm.employee_number.value }}" placeholder="Employee number">
<div class="help is-danger">
{% for error in employeeForm.employee_number.errors %}{{ error }}{% endfor %}
</div>
<div id="ifAcademic" style="display: none;">
<label class="label">Academic number</label>
<input class="input" type="text" name="academic_number" value="{{ academicForm.academic_number.value }}" placeholder="Academic number">
<div class="help is-danger">
{% for error in academicForm.academic_number.errors %}{{ error }}{% endfor %}
</div>
Add required attribute to all inputs. I'm not confident in code style, but as a logical example:
<input ... name="account_number" required="{{school_role === 1}}" ... />
Add </div> to each section
Give each div a class of hide
Toggle the hide on change of the select
toggle the required
const ifs = [...document.querySelectorAll("[id^=if]")];
document.getElementById("school_role").addEventListener("change", function() {
const val = this.options[this.selectedIndex].textContent;
ifs.forEach(ifDiv => {
ifDiv.classList.toggle("hide", !ifDiv.id.includes(val))
const input = ifDiv.querySelector("input");
if (ifDiv.classList.contains("hide")) input.removeAttribute("required")
else input.setAttribute("required", true)
});
})
.hide {
display: none;
}
<div class="select">
<select name="school_role" id="school_role" required>
<option value="">--------</option>
<option value="1">Student</option>
<option value="2">Academic</option>
<option value="3">Employee</option>
</select>
</div>
<form>
<div id="ifStudent" class="hide">
<label class="label">Account number</label>
<input class="input" type="text" name="account_number" value="" placeholder="Account number">
<div class="help is-danger">
{% for error in studentForm.account_number.errors %}{{ error }}{% endfor %}
</div>
</div>
<div id="ifEmployee" class="hide">
<label class="label">Employee Number</label>
<input class="input" type="text" name="employee_number" value="" placeholder="Employee number">
<div class="help is-danger">
{% for error in employeeForm.employee_number.errors %}{{ error }}{% endfor %}
</div>
</div>
<div id="ifAcademic" class="hide">
<label class="label">Academic number</label>
<input class="input" type="text" name="academic_number" value="" placeholder="Academic number">
<div class="help is-danger">
{% for error in academicForm.academic_number.errors %}{{ error }}{% endfor %}
</div>
</div>
<input type="submit">
</form>
I'm trying to get the user enter a username and access that value from a separate js file. The page redirects from one html to another after the user enters the name in the server (python) code. Is it causing the issue? Because, no matter what method (name, id, form, input field) I try it doesn't work. If I run the script from within the html file then I'm able to access it. Any help is appreciated!
const userStore = window.localStorage;
document.addEventListener('DOMContentLoaded', () => {
// Connect to websocket
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
if (!userStore.getItem('username')){
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#username').onsubmit = function() {
const name = document.querySelector('#username').value;
alert(`Welcome back ${name}!`);
};
});
} else {
userStore.setItem('username', document.querySelector("#username"));
}
{% extends "layout.html" %}
{% block title %}
Title
{% endblock %}
{% block main %}
<section id="cover" class="min-vh-100">
<div id="cover-caption">
<div class="container">
<div class="row text-white">
<div class="col-xl-5 col-lg-6 col-md-8 col-sm-10 mx-auto text-center form p-4">
<h1 class="display-4 py-2">Enter your Username.</h1>
<div class="px-2">
<form id="form" action="/flackchat" method="POST" class="justify-content-center">
<div class="form-group">
<label class="sr-only">Name</label>
<input id="username" type="text" class="form-control" name="username" placeholder="Username">
</div>
<button type="submit" class="btn btn-primary btn-lg">Continue</button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
I have a following code in jQuery:
$(".edit-trigger").on("click", function () {
url = $(this).data('url');
$.get(url, function(data) {
$("#modal .modal-content").html(data);
});
});
and it is loading following code (data) into modal window:
<form id="personal_info_form" class="modal-form">
<input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
<div class="modal-content">
{% for field in form %}
<div class="row">
<div class="input-field col s12">
{{ field }}
<label for="{{ field.id }}" data-error="wrong">{{ field.label }}</label>
</div>
</div>
{% endfor %}
</div>
<div class="modal-footer">
<button class="modal-action modal-close">Anuluj</button>
<button type="submit">Akceptuj</button>
</div>
</form>
<script>
M.updateTextFields();
</script>
The issue is that script in loaded code is not always executed. Is it possible to ensure execution of that script?