Alice_inwonderland
Alice_inwonderland

Reputation: 348

Send all dropdown data from HTML/Jenja back to flask server

I posted a similar question here: Flask - Data inputting on the client side

However, I figured out another way to solve that problem and now encounter a new one below.

In short, I'm building a portal for our client where they can log in and upload their financial documents. There is a predefined schema in flask that maps financial items in the uploaded document. For example, all accounts related to 'Cash' will simply be mapped into 'Cash'.

The html code below basically renders a table that is similar to the uploaded file with an additional column 'Mapping' that maps each row of account. If there are new accounts added in the financial document, there will be a drop-down section for the client to pick the mapping schema. A screenshot is included here for your visuals.

https://drive.google.com/file/d/1RuYq3rdaG5XSxLTPYO46PlqBujuy_I8A/view?usp=sharing

My question is how do I set up the event for the button "Confirm mapping" to send all selected dropdown inputs back to the flask server in the form of JSON object (preferably). In this case, I want the JSON to be:

{
"Cash" : "Lucky money",
"Debt" : "Bad debt"
}

I include some html code below. I know it's not very reproducible but my company codebase is too big to share. I'm just interested in some general method to accomplish the task.

<!-- results.html -->

<body>
  <div>
     <table id="Mapped table">
       <h2 align='center'>Mapped data</h2>
          <tr>
              {% for col in column_names %}
              <th>{{col}}</th>
              {% endfor %}
          </tr>
          {% for row in row_new %}
          <tr>
              {% for col, row_ in zip(column_names, row) %}
              {% if col == link_column %}
              <td>

                <select id="dropbtn">
                  <option value="1">Cash</option>
                  <option value="2">Debt</option>
                  <option value="3">Retained Earnings</option>
                </select>

                <div id="selection"></div>

                <script>
                  var e = document.getElementById("dropbtn");
                  var strUser = e.options[e.selectedIndex].text;
                </script>

              </td>
              {% else %}
              <td>{{row_}}</td>
              {% endif %}
              {% endfor %}
          </tr>
          {% endfor %}
     </table>
  </div>

  <div class="wrapper">
    <button class="button" id="myBtn">Confirm mapping</button>
</body>

Upvotes: 0

Views: 161

Answers (1)

gaetanoM
gaetanoM

Reputation: 42054

You have some issues:

  • ID must be unique. Hence, you can consider to change from select id="dropbtn" to **select class="dropbtn"
  • A table should contain a body, header and footer. Instead you have a series of rows (i.e.: tr)
  • The table ID contains a space. This is a problem when selecting by ID. For this take a look to escapeSelector

A possible solution to your issue can be:

$('#myBtn').on('click', function(e) {
    var drpdbJson = {};
    // for each row containing a select....
    $('#Mapped\\ table tr:gt(0):has(select)').each(function(idx, ele) {
        // get the selected value
        var drpdwnKey = $(ele).find('.dropbtn option:selected').text();
        // get the second column text
        var drpdwnValue = $(ele).find('td:eq(1)').text();
        // add to the json result
        if (drpdbJson[drpdwnKey] == undefined) {
            drpdbJson[drpdwnKey] = drpdwnValue;
        } else {
            drpdbJson[drpdwnKey] = (typeof drpdbJson[drpdwnKey] === 'string') ? 
                    [drpdbJson[drpdwnKey], drpdwnValue] : [...drpdbJson[drpdwnKey], drpdwnValue];
        }
    })
    // print the json obj
    // pay attention: a json cannot contain duplicated keys:
    // if you select the same value for both select in the example....
    console.log(JSON.stringify(drpdbJson))
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
    <h2 align='center'>Mapped data</h2>
    <table id="Mapped table">
        <tr>
            <th>Account Number</th>
            <th>Account Description</th>
            <th>Amount</th>
            <th>Mapping</th>
        </tr>
        <tr>
            <td>2010</td>
            <td>Lucky money</td>
            <td>1111.0</td>
            <td>
                <select class="dropbtn">
                    <option value="1" selected>Cash</option>
                    <option value="2">Debt</option>
                    <option value="3">Retained Earnings</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>1234</td>
            <td>Bad debt</td>
            <td>222222.0</td>
            <td>
                <select class="dropbtn">
                    <option value="1">Cash</option>
                    <option value="2" selected>Debt</option>
                    <option value="3">Retained Earnings</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>1234</td>
            <td>USD</td>
            <td>222222.0</td>
            <td>
                <select class="dropbtn">
                    <option value="1" selected>Cash</option>
                    <option value="2">Debt</option>
                    <option value="3">Retained Earnings</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>1234</td>
            <td>Petty cash</td>
            <td>222222.0</td>
            <td>
                <select class="dropbtn">
                    <option value="1" selected>Cash</option>
                    <option value="2">Debt</option>
                    <option value="3">Retained Earnings</option>
                </select>
            </td>
        </tr>
    </table>
</div>

<div class="wrapper">
    <button class="button" id="myBtn">Confirm mapping</button>
</div>

Upvotes: 1

Related Questions