I'm trying to have only one of two forms POST depending on which button from a btn-group is selected. Currently all of the forms POST with no issue, but there are two forms where only one or the other value is needed. I've unsuccessfully tried to parse the not needed value out at the app.py, so I decided to try and make this so only one or the other value gets posted.
Here is the code from the .html where I'm having trouble, it's a fieldset from a larger form the rest of which is working for now.
<fieldset id="program_value_form_id">
<legend for="value_range" >Value Range:</legend>
<p>
<div role="group" aria-label="Basic radio toggle button group">
<input type="radio" onchange="swapConfig(this)" name="btnradio_valuer" id="btnradio_value1" autocomplete="off" value="valuerange1" checked>
<label for="btnradio_value1">100-200</label>
<input type="radio" onchange="swapConfig(this)" name="btnradio_valuer" id="btnradio_valuer2" autocomplete="off" value="valuerange2">
<label for="btnradio_valuer2">400-500mhz</label>
</div>
</p>
<div id="btnradio_valuer1Swap">
<label for="value" >Value:</label>
<p>
<div >
<input id="value1" type="number" placeholder="xxx.xxx 100-200" name="value1" step="0.001" min="100" max="200">
<span ></span>
</div>
</p>
</div>
<div id="btnradio_valuer2Swap" style="display:none">
<label for="value" >Value:</label>
<p>
<div >
<input id="value2" type="number" placeholder="xxx.xxx 400-500" name="value2" step="0.001" min="400" max="500">
<span ></span>
</div>
</p>
</div>
</fieldset>
The forms swap depending on button click. Here is the js for that I got from on here to swap them.
<script>
function swapConfig(x) {
var radioName = document.getElementsByName(x.name);
for(i = 0 ; i < radioName.length; i ){
document.getElementById(radioName[i].id.concat("Swap")).style.display="none";
}
document.getElementById(x.id.concat("Swap")).style.display="initial";
}
</script>
I have tried if statements and if's inside of for's, none have worked. In frustration I've deleted them, but I could try and rewrite them again if they are needed though I wouldn't expect much from them since my html experience is limited. Please let me know if there needs to be any corrections to what I've written or if there is a better way or place to do what I am trying to do.
CodePudding user response:
The following example allows you to exclude and hide parts of the form.
When a fieldset or input is disabled, it is no longer part of the form data that can be queried on the server side. For this reason, depending on the value of the radio buttons, parts of the form that are referenced by specifying dataset properties are disabled. The JavaScript code activates and deactivates the elements of the form that are not required.
The appearance of certain elements can also be changed using the diabled property. Additional style sheet rules are required for this. Thus an entire row of the form is hidden when the contained input field is deactivated.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous">
<style>
/*
Toggle the appearance of the row containing an input field whose property
has been set to disabled.
*/
div.row:has(input.value-control[disabled]) {
display: none;
}
</style>
</head>
<body>
<div >
<form method="post">
<div >
<!-- The button group to switch between the form parts. -->
<div role="group" aria-label="Basic radio toggle button group">
<!-- The data-target and data-parent properties reference the parts to be switched. -->
<input
id="btnradio1"
name="btnradio"
type="radio"
autocomplete="off"
data-parent=".value-control"
data-target="#value-control-1"
checked
>
<label for="btnradio1">100-200 Mhz</label>
<input
id="btnradio2"
name="btnradio"
type="radio"
autocomplete="off"
data-parent=".value-control"
data-target="#value-control-2"
>
<label for="btnradio2">400-500 Mhz</label>
</div>
</div>
<div >
<label for="value-control-1" >Value:</label>
<div >
<!--
The references of the radio buttons refer to the class and id attributes
of the input field.
-->
<input
id="value-control-1"
name="value"
type="number"
step="0.001" min="100" max="200"
placeholder="xxx.xxx 100-200"
required
>
</div>
</div>
<div >
<label for="value-control-2" >Value:</label>
<div >
<input
id="value-control-2"
name="value"
type="number"
step="0.001" min="400" max="500"
placeholder="xxx.xxx 400-500"
required
disabled
>
</div>
</div>
<div >
<button type="submit" >Submit</button>
</div>
</form>
</div>
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg OMhuP IlRH9sENBO0LRn5q 8nbTov4 1p"
crossorigin="anonymous"></script>
<script type="text/javascript">
(() => {
// Wait for the document content to load. This listener is not absolutely
// necessary at this point, since the script element is at the end of the document.
window.addEventListener('DOMContentLoaded', () => {
// Select the toggle buttons based on their properties.
const radioSel = 'input[name="btnradio"][data-target][data-parent]';
const radioBtns = document.querySelectorAll(radioSel);
radioBtns.forEach(btn => {
// Register a listener for the change event for each element found.
btn.addEventListener('change', evt => {
// Change the disabled property of the referenced elements.
const parent = document.querySelectorAll(evt.target.dataset.parent);
const target = document.querySelector(evt.target.dataset.target);
parent.forEach(elem => elem.disabled = true );
target && (target.disabled = !evt.target.checked);
});
});
});
})();
</script>
</body>
</html>
from flask import (
Flask,
render_template,
request
)
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
print(request.form.get('value', type=float))
return render_template('index.html')
``