Reputation: 69
I have a csv file in the form of dataframe which consist of location, Device and unit. Locations may be repeated locations with different units and devices.
I want 4 dropdown menu with
And a submit button, which displays all the selected fields.
On selection of location, it should display all unique locations based on the selection of location like PA, select unit will display like
Unit
>:LAN
>:WAN
Subunit
>. LAN Switch
>. WAN switch
Device
> D2
> D4
This is a example of the problem statement. Original file consist thousand locations and related units.
> Location Device Unit
> USA D1 LAN core
> PA D2 LAN Switch
> BLR D3 LAN core
> PA D4 WAN switch
> MEL D5 DC metro
app.py:
from flask import Flask, render_template, request
import pandas as pd
app = Flask(__name__)
app.debug = True
@app.route('/', methods=['GET'])
def dropdown():
total_data = pd.read_csv("CPS.csv")
print(total_data)
data = total_data['LOCATION'].unique()
print(data)
return render_template('index.html', data=data)
if __name__ == "__main__":
app.run()
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dropdown</title>
</head>
<body>
<select name= data method="GET" action="/">
{% for row in data %}
<option value= "{{row}}" SELECTED>{{row}}</option>"
{% endfor %}
</select>
</body>
</html>
Upvotes: 3
Views: 3007
Reputation: 2149
If you want to avoid going through an ajax request then you should consider registering your datas on the client side, by using technologies such as IndexedDB.
But if you want to keep your information on the server side, and access it dynamically, here's how you can implement that:
from flask_wtf import FlaskForm
from wtforms import SelectField
from flask import Flask, render_template, request, jsonify
import pandas as pd
class LocationsForm(FlaskForm):
locations = SelectField('Locations')
@app.route('/', methods=['GET', 'POST'])
def dropdown():
total_data = pd.read_csv("CPS.csv")
data = total_data['LOCATION'].unique().tolist()
form = LocationsForm()
form.locations.choices = [(i, i) for i in data]
return render_template(form=form)
@app.route('/device_choice/<value>')
def device_choice(value):
location_choosen = value
df = pd.read_csv("CPS.csv")
df = df.set_index(["LOCATION"])
df1 = df.loc[location_choosen, 'Device'].tolist()
return jsonify({'Devices': df1})
@app.route('/unit_choice/<value>')
def unit_choice(value):
# YOU CAN IMPLEMENT THIS BY FOLLOWING THE SAME MODEL AS THE DEVICES
I create a form that I populate dynamically with the values of the locations only. then I render the form.
In my JS script I put an event that is triggered whenever there is a change in the field of locations.
At each change I send the selected value (location
) to the device_choice route
and find all the devices associated with this location. I return the devices as a list and fill in the appropriate selectfield (devices
)
HTML's SIDE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dropdown</title>
</head>
<body>
{{ form.hidden_tag() }}
{{ form.locations(class_="form-control") }}
<select class="form-control devices" id="devices"></select>
<select class="form-control unit" id="unit"></select>
</body>
<script>
let location = document.getElementById('locations');
let devices = document.getElementById('devices');
location.onchange = function(){
value = location.value;
fetch('/device_choice/' + value).then(function(response){
response.json().then(function(data){
let optionHTML = '';
for(let opt of data.Devices){
optionHTML += '<option value ="' + opt + '">' + opt + '</option>';
}
devices.innerHTML = optionHTML;
});
});
}
</script>
</html>
You just have to apply the same logic for the units too...
Upvotes: 5