skip to Main Content

I’m trying to have a multi-select box for users to choose from multiple groups and be able to pass the selected records/query to my Flask API where I can search in my MongoDB and return the JSON data to a table on the same page.

Issue I have now is that under different optgroups, there may be records with the same name, but I hope to differentiate them since user may only want to see one of them sometimes

HTML Example:

<em>Choose the records:</em>
    <select id="recordList" name="records" data-placeholder="Your records" class="chosen-select" multiple>
        <option value=""></option>
        <optgroup label="Location1">
            <option value="report31101">report31101</option>     <!-- report with same name -->
        </optgroup>
        <optgroup label="Location2">
            <option value="report143242">report143242</option>
            <option value="report34345">report34345</option>
        </optgroup>
        <optgroup label="Location3">
            <option value="report31101">report31101</option>     <!-- report with same name -->
            <option value="report13904">report13904</option>
            <option value="report13921">report13921</option>
          </optgroup>
    </select>

When selecting report31101 under Location 1, I want to be able to search the following from my Flask route with pymongo
collection.find({$and:[{'location':"Location1"},{'report':report31101}]})
then return the report’s data in JSON format to the same HTML page in a table.

Then if select report31101 under Location3 again, it should search the following:
collection.find({$or:[{$and:[{'location':"Location3"},{'report':report31101}]},{$and:[{'location':"Location1"},{'report':report31101}]}})

After looking up on Google, I found that a MultiDict structure mentioned here might be the best option to process the incoming data for me to feed in my pymongo query.
I imagine process should be something like this:

Step 1: User selects report31101 in Location1, report31101 and report13904 in Location 3 from dropdown

Step 2: Sends MultiDict([('Location1','report31101'),('Location3','report31101'),('Location3','report13904')]) from JavaScript/Ajax back to my Flask API route

Step 3: In Flask route, I imagine it to be something like this:

@api.route("/data/records",method=['POST'])
def get_reports():
    collection = mongo.db.records
    output = []
    reports = request.args.getlist('data')  #trying to get this to be in MultiDict structure from Ajax sent from front end
    location_1 = reports.getlist('Location1')
    location_2 = reports.getlist('Location2')
    location_3 = reports.getlist('Location3')
    filter1 = "{"$and":[{'location':"Location1"},{"$or":["
    filter2 = "{"$and":[{'location':"Location2"},{"$or":["
    filter3 = "{"$and":[{'location':"Location3"},{"$or":["
    i = 0
    while i < len(location_1):
        filter1 += "{'location':'"+location_1[i] +"'}"
        i+=1
        if i < len(location_1):
            filter1 += ","
    filter1+="]}]}";        

    i = 0
    while i < len(location_2):
        filter2 += "{'location':'"+location_2[i] +"'}"
        i+=1
        if i < len(location_2):
            filter2 += ","
    filter2+="]}]}"; 

    i = 0
    while i < len(location_3):
        filter3 += "{'location':'"+location_3[i] +"'}"
        i+=1
        if i < len(location_3):
            filter3 += ","
    filter3+="]}]}"; 

    q1 = collection.find(filter1)
    q2 = collection.find(filter2)
    q3 = collection.find(filter3)
    for report in q1:
        output.append({
            'location':report['location'],
            # list goes on...
    return jsonify({'data': output})  # return JSON to the same page again using Ajax to display data in a table<br>

Right now I’m having trouble with Step 2
I’m able to print out the list of selected report names and another list of Location labels on the console, but just cannot figure out how to feed these two lists back to Flask route in Ajax with MultiDict structure for python to understand.
Could someone please help me?

My attempt for Step 2 so far which doesn’t work:

$('#recordList').on('change',function(){
        var location_list = []
        $(this).find("option:selected").each(function(){
            location_grp = $(this).parent().attr("label");
            location_list.push(location_grp);
        }) 
        var records = $('#recordList').val();
        console.log('location',location_list);
        console.log('records:',records);

        var record_List = [];
        var i=0;
        while ( i < location_list.length)
        {
            // currently have array of arrays because I don't know how to create MultiDict in JavaScript to post to my Flask route
            record_list = [location_list[i],records[i]];    
            i++;
        }
        console.log(record_list);

    $.ajax({
        type: 'POST',
        url: '/data/records',
        data:{ records: record_list },
        success: function( result ){
            console.log('result:',result);
        }
    })
    })

2

Answers


  1. Chosen as BEST ANSWER

    I'm quite new to JavaScript and web development so was a little lost when asking the question.

    After many tries, I figured out if I send a JSON object with arrays from AJAX, then it will work the way I want:

    $('#recordList').on('change',function(){
            var location_list = []
            $(this).find("option:selected").each(function(){
                location_grp = $(this).parent().attr("label");
                location_list.push(location_grp);
            })
            var records = $('#recordList').val();
    
            recordsJSON = {};
            location_list.forEach(function(k,i){
                if(!(k in recordsJSON))
                {
                    recordsJSON[k] = [];
                    recordsJSON[k].push(records[i]);
                }
                else{
                    recordsJSON[k].push(records[i]);
                }
            })
            console.log(recordsJSON);
            
            $.ajax({
            type: 'POST',
            url: '/data/records',
            contentType: 'application/json',
            data: JSON.stringify(recordsJSON),
            success: function( result ){
                console.log('result:',result);
            }
        })
        });
    

    So the recordJSON will be {"Location1":["report31101"],"Location3":["report31101","report13904"]} for my Step 2.


  2. I don’t think there is any native data-structure in Javascript for emulating MultiDict data-structure from Python.

    My best guess to achieve this would be –

    1. Send JSON data to Flask backend using AJAX.
    2. Consume the incoming JSON in Flask and create a MultiDict here.
    3. Post this MutliDict query to MongoDB using the MongoDB driver.
    4. Return the data back to the frontend using the Flask route.

    See – How do read multiDicts in python (flask)

    Note – I wanted to add this as a comment, but I lack the reputation points for the same.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search