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>
Related
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', '')])
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 add two "br" after each of my form fields that are not hidden because otherwise, it uses some space in my form and it doesn't look good.
But for some reason it doesn't appear.
<legend>Ética y Cumplimiento:</legend>
<fieldset style="border: 1px solid #000;">
<br>
<div id="formulario3">
{% for field in form3 %}
{% if field.flags.required %}
{{ field.label(text='*' + field.label.text) }}
{% else %}
{{ field.label }}
{% endif %}
{% if field.errors %}
{{ field(class="is-invalid") }}
<div class="invalid-feedback">
{% for error in field.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ field(class="form-control") }}
{% endif %}
<script>
let elementoseleccionado = document.getElementById({{ field.id }});
if ((document.getElementById('{{ field.id }}')).type === 'hidden') {
$('label[for="{{ field.id }}"]').css('display', 'none');
}
else{
let linebreak = document.createElement("br");
elementoseleccionado.appendChild(linebreak);
elementoseleccionado.appendChild(linebreak);
}
</script>
{% endfor %}
<input type="button" class="btn btn-primary" id="morecumplimiento" value="Más">
<br>
<br>
</div>
The error generated by my code is this one:
The HTML generated is this one:
<legend>Ética y Cumplimiento:</legend>
<fieldset style="border: 1px solid #000;">
<br>
<div id="formulario3">
<label for="exposicion_politica">* Indique si alguna persona mencionada en el presente formulario es/fue una Persona Expuesta Políticamente (PEP)</label>
<select class="form-control" id="exposicion_politica" name="exposicion_politica" required><option value="0">---</option><option value="SI">SI</option><option value="NO">NO</option></select>
<script>
if ((document.getElementById('exposicion_politica')).type === 'hidden') {
$('label[for="exposicion_politica"]').css('display', 'none');
}
else{
let linebreak = document.createElement("br");
if ((document.getElementById('exposicion_politica')) !== null && (document.getElementById('exposicion_politica')).value === ''){
document.getElementById(exposicion_politica).appendChild(linebreak);
document.getElementById(exposicion_politica).appendChild(linebreak);
}
}
</script>
<label for="ap_nom_etica1">*Apellidos y Nombres 1</label>
<input class="form-control" id="ap_nom_etica1" name="ap_nom_etica1" required type="text" value="">
<script>
if ((document.getElementById('ap_nom_etica1')).type === 'hidden') {
$('label[for="ap_nom_etica1"]').css('display', 'none');
}
else{
let linebreak = document.createElement("br");
if ((document.getElementById('ap_nom_etica1')) !== null && (document.getElementById('ap_nom_etica1')).value === ''){
document.getElementById(ap_nom_etica1).appendChild(linebreak);
document.getElementById(ap_nom_etica1).appendChild(linebreak);
}
}
</script>
As you can see the br is not generated and some error apears.
You can use each loop to iterate through your inputs and check if it is visible if yes then use .after to add <br> tag
Demo Code:
$("select , input").each(function() {
//check if visible
if ($(this).is(":visible")) {
//add br after that elements
$(this).after("<br/><br/>")
} else {
//hide label
$(this).prev().css('display', 'none');
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<legend>Ética y Cumplimiento:</legend>
<fieldset style="border: 1px solid #000;">
<br>
<div id="formulario3">
<label for="exposicion_politica">* Indique si alguna persona mencionada en el presente formulario es/fue una Persona Expuesta Políticamente (PEP)</label>
<select class="form-control" id="exposicion_politica" name="exposicion_politica" required>
<option value="0">---</option>
<option value="SI">SI</option>
<option value="NO">NO</option>
</select>
<label for="ap_nom_etica1">*Apellidos y Nombres 1</label>
<input class="form-control" id="ap_nom_etica1" name="ap_nom_etica1" required type="text" value="">
<label for="">*Apellidos y Nom</label>
<input class="form-control" name="ap_nom_etica1" required type="hidden" value="">
<label for="">*Apellidos y Nom</label>
<input class="form-control" name="ap_nom_etica1" required type="text" value="">
</div>
</fieldset>
Other way would be to directly select the inputs & select and add br tag instead of using each loop .
Demo Code :
$("input:visible ,select:visible").after("<br/><br/>")
$("input:hidden ,select:hidden").prev().css('display', 'none');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<legend>Ética y Cumplimiento:</legend>
<fieldset style="border: 1px solid #000;">
<br>
<div id="formulario3">
<label for="exposicion_politica">* Indique si alguna persona mencionada en el presente formulario es/fue una Persona Expuesta Políticamente (PEP)</label>
<select class="form-control" id="exposicion_politica" name="exposicion_politica" required>
<option value="0">---</option>
<option value="SI">SI</option>
<option value="NO">NO</option>
</select>
<label for="ap_nom_etica1">*Apellidos y Nombres 1</label>
<input class="form-control" id="ap_nom_etica1" name="ap_nom_etica1" required type="text" value="">
<label for="">*Apellidos y Nom</label>
<input class="form-control" name="ap_nom_etica1" required type="hidden" value="">
<label for="">*Apellidos y Nom</label>
<input class="form-control" name="ap_nom_etica1" required type="text" value="">
</div>
</fieldset>
I am trying to create a from on my shopify store that will collect an email address and a "Goal" however I believe the default functionality of shopify requires a password to create an account for the shopify store. I want to get around the password requirement. I have pasted what I have so far, any help would be amazing.
{% form 'create_customer' %}
{{ form.errors | default_errors }}
{% if form.posted_successfully? %}
<script>
window.location = "https://www.thankyoupage";
</script>
{% endif %}
<div class="clearfix large_form">
<label for="email" class="login">Email Address</label>
<input type="email" value="" name="customer[email]" id="email" class="large" size="30" />
</div>
<div class="clearfix large_form">
<label for="goal">Goal </label>
<select name="customer[note][Goal]" id="goal">
<option value=""></option>
<option value="Lose Weight">Goal 1 </option>
<option value="Eat Healthy">Gaol2</option>
<option value="Peak Performance">Goal 3</option>
</select>
</div>
<div class="clearfix large_form" style="display:none;">
<label for="password" class="login">Password</label>
<input type="password" value="" name="customer[password]" id="password" class="large password" size="30" is_required="0" />
</div>
<button type="submit" value="Create">Get Started</button>
{% endform %}
If you prefill the field with a default (random) value, the form check requirements should be satisfied.
I am trying to validate code in javascript. Here is my code:
if(document.getElementById("name").value == ""){
alert("Name is a required field");
document.getElementById("name").focus();
return false;
}
name is id in my html page:
<div class="app-form-box">
{% if review %}
{% if not review.name %}
<input type="text" alt="" onkeyup="return validateField(name)" tabindex="2" name="name" id="name" class="disabled inputtxtlarge" onfocus="highlightInput(this.id)" onblur="return (!validateField(name) || unhighlightInput(this.id))" maxlength="50" value="{{name|moonescape}}" disabled="disabled"/><span> </span>
{% else %}
<input type="text" alt="" onkeyup="return validateField(name)" tabindex="2" name="name" id="name" class="inputtxtlarge" onfocus="highlightInput(this.id)" onblur="return (!validateField(name) || unhighlightInput(this.id))" maxlength="50" value="{{name|moonescape}}"/><span> </span>
{% endif %}
{% else %}
<input type="text" alt="" onkeyup="return validateField(name)" tabindex="2" name="name" id="faname" class="inputtxtlarge" onfocus="highlightInput(this.id)" onblur="return (!validateField(name) || unhighlightInput(this.id))" maxlength="50" value="{{name|moonescape}}"/><span> </span>
{% endif %}
<div class="servererror">
{% if form_errors.name %}
* {{ form_errors.name|join:"| " }}<br/>
{% endif %}
</div>
</div>
But I am getting OBJECT REQUIRED. Please suggest how to put check in js file for this. Thanks