0

My web application is designed to allow users to upload their Excel files, which will then be read and convert into a DataFrame within my flask application. Subsequently, my application is supposed to filter the DataFrame to remove unnecessary records from the DataFrame. To do that, I am planning to set up 2 dynamic select fields:

1st Select field - contains a list of the column names from the dataframe 2nd Select field - corresponding unique values of the selected value in the 1st Select field.

So how should I go about doing this??

I have watched a video that taught me how to use FlaskForm to do these dynamic fields. But I can't seemed to customize his ways to fit my https://www.youtube.com/watch?v=I2dJuNwlIH0

Flask side code (app.py):

class Form(Form):
    column = SelectField('column', choices=list(upload_df.columns.values))
    unique_value = SelectField('unique_value', choices=[]) 

@app.route('/upload_file')
def upload_file():
    return render_template('upload.html')

@app.route('/testing_field', methods=['GET', 'POST'])
def testing():
    if request.method == 'POST':
        file = request.files['datafile']
        if file and allowed_file(file.filename):
            global upload_df
            upload_df = pd.read_excel(file)
            col = list(upload_df.columns.values)
            form = Form()
            global col_uni_val_dict
            for i in col:
                col_uni_val_dict[i] = upload_df[i].unique()
            form.unique_value.choices = (col_uni_val_dict[col[0]]).tolist()

    return render_template(
        'index2.html',
        form=form
    )

@app.route('/col/<col>')
def unique_val(col):
    unique_values = col_uni_val_dict[col].tolist()

    return jsonify({'unique_val' : unique_values})

HTML side code:

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form method="POST">
        {{ form.crsf_token }}
        {{ form.column }}
        {{ form.unique_value }}
        <input type="submit">
    </form>
    <script>
        let col_select = document.getElementById('column');
        let uv_select = document.getElementById('unique_value');

        col_select.onchange = function(){
            col = col_select.value;

            fetch('/col/' + col).then(function(response){

                response.json().then(function(data){
                    let optionHTML = "";

                    for (let uv of data.unique_val) {
                        optionHTML += '<option value="' + uv + '">' + uv + '</option>';
                    }

                    uv_select.innerHTML = optionHTML;

                });
            });
        }
    </script>
</body>
</html>

Expected: To have 2 dynamic select fields on webpage Actual: Keep getting different errors like --> TypeError: cannot unpack non-iterable int object

Soon Hang
  • 91
  • 2
  • 11
  • Can you show what youre current dataframe looks like and what your desired dataframe looks like? – Emil May 20 '19 at 09:31
  • Hi @Emil, i am modifying the structure of the DF, but rather just referencing its column values and each column's unique records. So if there are 2 columns, which are Company Name and Country Name, which will be the values for first select field. Based on that, the second select field will then be populated by the corresponding unique value. E.g., if the user select "Country Name", the second select field will be populated by a unique list of country name referencing from the records in the DF, so if the DF have "USA, USA, UK, CHN, CHN", the 2nd select field will only show USA, UK and CHN – Soon Hang May 21 '19 at 03:23

1 Answers1

1

So basically, your question is twofold:

1) You want to get all the column names of the dataframe. To do so, see: Get list from pandas DataFrame column headers

2) For each column you want to get the unique values. To do so, see: getting the unique values of every column in a pandas dataframe - to help me create smaller more manageable dataframes to perform metrics on

Emil
  • 1,531
  • 3
  • 22
  • 47