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:
When the user clicks the change button they see a modal like so:
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">×</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
Sorry I could not do it in jQuery but here is an AJAX request that should replace your entire POST request at the bottom:
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.
Hope this works for you
All that really needed fixing was your selectors upon submit changing
to
and changing
to
So in the end this is what your code should look like and it should be fixed
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.