Reputation: 625
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?
Upvotes: 4
Views: 207
Reputation: 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">×</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.
Upvotes: 0
Reputation: 1674
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
Upvotes: 2
Reputation: 497
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">×</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>
Upvotes: 0