skip to Main Content

New to Bootstrap and FE development in general. I have the following page that presents the user with a table, and each row in the table has a "Change" button like so:

enter image description here

When the user clicks the change button they see a modal like so:

enter image description here

They can then change the value for the configuration and click the Update button, where I want an AJAX post to submit some JSON to a certain url.

Here is my best attempt at that:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>

    <meta name="description" content="">
    <meta name="author" content="">

    <title>My App</title>

    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">


</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
    <div class="container">
        <a class="navbar-brand" href="/">My App</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive"
                aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarResponsive">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <a class="nav-link" href="/fizzes">Fizzes</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/buzzes">Buzzes</a>
                </li>
            </ul>
        </div>
    </div>
</nav>

<div class="container">

    <div class="row">
        <div class="col-md-4 mt-5">
            <h3><span>Configurations</span></h3>
            <table class="table">
                <thead>
                <tr>
                    <th scope="col">Config</th>
                    <th scope="col">Value</th>
                    <th scope="col">Actions</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td >type</td>
                    <td >EXCEL</td>
                    <td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#changeModal" data-currval="EXCEL" data-config="type">Change</button></td>
                </tr>
                <tr>
                    <td >fizz</td>
                    <td >1</td>
                    <td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#changeModal" data-currval="1" data-config="fizz">Change</button></td>
                </tr>
                </tbody>
            </table>
            <button>Config History</button>
        </div>
    </div>

</div>

<div class="modal fade" id="changeModal" tabindex="-1" role="dialog" aria-labelledby="changeModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="changeModalLabel">Change config value</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="form-group">
                        <label for="current-value" class="col-form-label">Current value:</label>
                        <input type="text" class="form-control" id="current-value"/>
                    </div>
                    <div class="form-group">
                        <label for="new-value" class="col-form-label">New value:</label>
                        <textarea class="form-control" id="new-value"></textarea>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" id="btnUpdate" class="btn btn-primary">Update</button>
            </div>
        </div>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script type="text/javascript">
    $('#changeModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget);
        var configName = button.data('config');
        var currVal = button.data('currval');
        var modal = $(this);
        modal.find('.modal-title').text('Change value for ' + configName);
        modal.find('.modal-body input').val(currVal);
    });

    $('#btnUpdate').click(function (event) {
        var button = $(event.relatedTarget);
        var modal = $(this);
        var url = '/fizzes/abc123/buzzes/abc235';
        var configName = button.data('config');
        var newVal = modal.find('#new-value').text;

        $.post(
            url,
            { [configName]: newVal },
            alert("update made")
        )
    });
</script>

</body>
</html>

When I run this in a browser, click "Change", update a value and click "Update", I get the alert("update made") popup firing, but in my Developer Tools Network tab I don’t actually see an AJAX POST firing off, and instead I see the following error:

Uncaught TypeError: Cannot read property 'length' of undefined
    at $ (jquery.min.js:2)
    at text (jquery.min.js:2)
    at i (jquery.min.js:2)
    at Dt (jquery.min.js:2)
    at Function.S.param (jquery.min.js:2)
    at Function.ajax (jquery.min.js:2)
    at Function.S.<computed> [as post] (jquery.min.js:2)
    at HTMLButtonElement.<anonymous> (abc235:121)
    at HTMLButtonElement.dispatch (jquery.min.js:2)
    at HTMLButtonElement.v.handle (jquery.min.js:2)

On the server-side I also don’t see any requests being received. I noticed that, in my IDE, when I hover over the [configName] JSON section of the AJAX post, I see the following error:

"Computed property names are not supported by current JavaScript version"

So I tried changing that to:

$.post(
    url,
    { configName: newVal },
    alert("update made")
)

But the issue persists. Can anyone spot where I’m going awry?

3

Answers


  1. Sorry I could not do it in jQuery but here is an AJAX request that should replace your entire POST request at the bottom:

    function sendData(url, object) {
      const formdata = new FormData();
      for ( let key in object ) {
        formdata.append(key, object[key]);
      }
      
      const http = new XMLHttpRequest();
      return new Promise(resolve => {
        http.onreadystatechange = function () {
          if (this.readyState === 4 && this.status === 200) {
            resolve(this.responseText);
          }
        };
        http.open("POST", url, true);
        http.send(formdata);
      });
    }
    
    //object is post information
    
    sendData(url, {
      [configName]: newVal
    }).then(response => alert("Update made"));
    
    //configName should be a string
    
    Login or Signup to reply.
  2. I guess there the modal.find is not serving the purpose here. I could not find modal’s function to read the value, so I used jquery .val() function.

    var newVal = $('#new-value').val();
    

    Hope this works for you

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
    
        <meta name="description" content="">
        <meta name="author" content="">
    
        <title>My App</title>
    
        <!-- Bootstrap core CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    
    
    </head>
    <body>
    <!-- Navigation -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
        <div class="container">
            <a class="navbar-brand" href="/">My App</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarResponsive">
                <ul class="navbar-nav ml-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="/fizzes">Fizzes</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/buzzes">Buzzes</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    
    <div class="container">
    
        <div class="row">
            <div class="col-md-4 mt-5">
                <h3><span>Configurations</span></h3>
                <table class="table">
                    <thead>
                    <tr>
                        <th scope="col">Config</th>
                        <th scope="col">Value</th>
                        <th scope="col">Actions</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr>
                        <td >type</td>
                        <td >EXCEL</td>
                        <td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#changeModal" data-currval="EXCEL" data-config="type">Change</button></td>
                    </tr>
                    <tr>
                        <td >fizz</td>
                        <td >1</td>
                        <td><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#changeModal" data-currval="1" data-config="fizz">Change</button></td>
                    </tr>
                    </tbody>
                </table>
                <button>Config History</button>
            </div>
        </div>
    
    </div>
    
    <div class="modal fade" id="changeModal" tabindex="-1" role="dialog" aria-labelledby="changeModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="changeModalLabel">Change config value</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form>
                        <div class="form-group">
                            <label for="current-value" class="col-form-label">Current value:</label>
                            <input type="text" class="form-control" id="current-value"/>
                        </div>
                        <div class="form-group">
                            <label for="new-value" class="col-form-label">New value:</label>
                            <textarea class="form-control" id="new-value"></textarea>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="button" id="btnUpdate" class="btn btn-primary">Update</button>
                </div>
            </div>
        </div>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <script type="text/javascript">
        $('#changeModal').on('show.bs.modal', function (event) {
            var button = $(event.relatedTarget);
            var configName = button.data('config');
            var currVal = button.data('currval');
            var modal = $(this);
            modal.find('.modal-title').text('Change value for ' + configName);
            modal.find('.modal-body input').val(currVal);
        });
    
        $('#btnUpdate').click(function (event) {
            var button = $(event.relatedTarget);
            var modal = $(this);
            var url = '/fizzes/abc123/buzzes/abc235';
            var configName = button.data('config');
            var newVal = $('#new-value').val();
            console.log(newVal)
    
            $.post(
                url,
                { [configName]: newVal },
                alert("update made")
            )
        });
    </script>
    
    </body>
    </html>
    Login or Signup to reply.
  3. All that really needed fixing was your selectors upon submit changing

    var button = $(event.relatedTarget);
    

    to

    var element = $('input#current-value');
    

    and changing

    var configName = button.data('config');
    var newVal = modal.find('#new-value').text;
    

    to

    var configName = element.val();
    var newVal = $('textarea#new-value').val();
    

    So in the end this is what your code should look like and it should be fixed

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    
        <meta name="description" content="" />
        <meta name="author" content="" />
    
        <title>My App</title>
    
        <!-- Bootstrap core CSS -->
        <link
          rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossorigin="anonymous"
        />
      </head>
      <body>
        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
          <div class="container">
            <a class="navbar-brand" href="/">My App</a>
            <button
              class="navbar-toggler"
              type="button"
              data-toggle="collapse"
              data-target="#navbarResponsive"
              aria-controls="navbarResponsive"
              aria-expanded="false"
              aria-label="Toggle navigation"
            >
              <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarResponsive">
              <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                  <a class="nav-link" href="/fizzes">Fizzes</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link" href="/buzzes">Buzzes</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>
    
        <div class="container">
          <div class="row">
            <div class="col-md-4 mt-5">
              <h3><span>Configurations</span></h3>
              <table class="table">
                <thead>
                  <tr>
                    <th scope="col">Config</th>
                    <th scope="col">Value</th>
                    <th scope="col">Actions</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td>type</td>
                    <td>EXCEL</td>
                    <td>
                      <button
                        type="button"
                        class="btn btn-primary"
                        data-toggle="modal"
                        data-target="#changeModal"
                        data-currval="EXCEL"
                        data-config="type"
                      >
                        Change
                      </button>
                    </td>
                  </tr>
                  <tr>
                    <td>fizz</td>
                    <td>1</td>
                    <td>
                      <button
                        type="button"
                        class="btn btn-primary"
                        data-toggle="modal"
                        data-target="#changeModal"
                        data-currval="1"
                        data-config="fizz"
                      >
                        Change
                      </button>
                    </td>
                  </tr>
                </tbody>
              </table>
              <button>Config History</button>
            </div>
          </div>
        </div>
    
        <div
          class="modal fade"
          id="changeModal"
          tabindex="-1"
          role="dialog"
          aria-labelledby="changeModalLabel"
          aria-hidden="true"
        >
          <div class="modal-dialog" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="changeModalLabel">
                  Change config value
                </h5>
                <button
                  type="button"
                  class="close"
                  data-dismiss="modal"
                  aria-label="Close"
                >
                  <span aria-hidden="true">&times;</span>
                </button>
              </div>
              <div class="modal-body">
                <form>
                  <div class="form-group">
                    <label for="current-value" class="col-form-label"
                      >Current value:</label
                    >
                    <input type="text" class="form-control" id="current-value" />
                  </div>
                  <div class="form-group">
                    <label for="new-value" class="col-form-label">New value:</label>
                    <textarea class="form-control" id="new-value"></textarea>
                  </div>
                </form>
              </div>
              <div class="modal-footer">
                <button
                  type="button"
                  class="btn btn-secondary"
                  data-dismiss="modal"
                >
                  Close
                </button>
                <button type="button" id="btnUpdate" class="btn btn-primary">
                  Update
                </button>
              </div>
            </div>
          </div>
        </div>
    
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
          integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
          crossorigin="anonymous"
        ></script>
        <script
          src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
          integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
          crossorigin="anonymous"
        ></script>
        <script type="text/javascript">
          $('#changeModal').on('show.bs.modal', function (event) {
            var button = $(event.relatedTarget);
            var configName = button.data('config');
            var currVal = button.data('currval');
            var modal = $(this);
            modal.find('.modal-title').text('Change value for ' + configName);
            modal.find('.modal-body input').val(currVal);
          });
    
          $('#btnUpdate').click(function (event) {
            var element = $('input#current-value');
            var modal = $(this);
            var url = '/fizzes/abc123/buzzes/abc235';
            var configName = element.val();
            var newVal = $('textarea#new-value').val();
            console.log(newVal);
    
            $.ajax({
              url: url,
              method: 'POST',
              data: { [configName]: newVal },
              success: (data) => {
                console.info(data);
              },
              error: (err) => {
                console.error(err);
              },
            });
          });
        </script>
      </body>
    </html>

    As an aside you can definitely ignore the fact that i’m using the $.ajax rather than the post that you used, that was just a sanity check for me.

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