I have a bizarre error where ajax call in a on('click') listener executed from an external trigger('click') call will fail, but execute correctly if the on('click') listener is called via a regular user mouse-click.
HTML:
....
<div class="navbar-collapse collapse">
<ul class="navbar-nav mr-auto navbar-right">
<li class="nav-item dropdown active">
<a class="nav-link dropdown-toggle" id="nbd" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Graphs<span class="sr-only">(current)</span></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item ycai" id="d1" href="#" data-type="1">Graph 1</a>
<a class="dropdown-item ycai" id="d2" href="#" data-type="2">Graph 2</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-lg-0 navbar-right">
<div id="nbsa"></div>
<input class="form-control mr-sm-2" id="nbpc" placeholder="Postal Code" style="width:140px" aria-label="Postal Code" type="search">
<select class="form-control mr-sm-2" id="nbs">
<option value="1" selected="true">Average-case</option>
<option value="2">High-case</option>
</select>
</form>
</div>
JS:
<script>
var dataV = {
gtype:2,
nbpc: null,
nbs: null
};
$('#nbpc').keyup(function(e) {
if (e.keyCode === 13) {
e.preventDefault();
dataV.nbpc = $(this).val();
switch(dataV.gtype) {
case 1:
$('#d1').trigger('click');
break;
case 2:
$('#d2').trigger('click');
break;
}
}
});
$('#nbtop').on('click', '.ycai', function(e) {
console.log('In Click...',$(this).attr('data-type'));
e.preventDefault();
var i=0, rval;
if (!$(this).hasClass("dislink")) {
$(this).addClass("dislink");
dataV.nbpc = $('#nbpc').val();
dataV.nbs = $('#nbs').val();
dataV.gtype = +$(this).attr('data-type');
console.log(dataV);
if (dataV.gtype<8 && dataV.nbpc == "") {
alert('Postal Code Cannot Be Blank...');
$('.dislink').removeClass('dislink');
$('#nbpc').focus();
return;
}
$.ajax({
type: 'POST',
url: '/climG',
dataType: 'json',
data: dataV
}).fail(function(jqXHR, textStatus, error) {
console.log(textStatus);
console.log(error);
alert('Error on Graph');
}).done(function(res) {
...
});
Scenario #1: If I add the postal-code in (#nbpc) first (without hitting Enter) and then select a graph (say Graph 2), the ajax call goes thru and executes perfectly.
Scenario #2: If I add the postal-code in (#nbpc) and then hit Enter, which defaults to Graph 2 and then executes the $('#d2').trigger('click'); via the $('#nbpc') keyup listener, then the ajax call will fail with no error message.
What is interesting are the node.js console lines.
In Scenario #1, the console log lines are perfect:
Console Log Line 1
...
Console Log Line N
POST /climG 200 378.344ms - 1872
In Scenario #2 (error), the console log lines are very strange:
GET /? 304 192.332 ms - -
POST /climG - - ms - -
Console Log Line 1
...
Console Log Line N
So in Scenario #2, an extra GET /? is generated for some unknown-to-me reason, and the /climG call quickly returns a failure, yet the actual /climG server-side function continues to execute (evidenced by the console log lines after the POST message). I have no clue what's happening. Thx.
the form
element will default to GET
as its action - if you are not using the form to submit your data, you can safely remove this tag.
It's likely being triggered by pressing the enter key - before you even get a chance to execute the JS.
In other words, change
<form class="form-inline my-2 my-lg-0 navbar-right">
<div id="nbsa"></div>
<input class="form-control mr-sm-2" id="nbpc" placeholder="Postal Code" style="width:140px" aria-label="Postal Code" type="search">
<select class="form-control mr-sm-2" id="nbs">
<option value="1" selected="true">Average-case</option>
<option value="2">High-case</option>
</select>
</form>
to
<div class="form-inline my-2 my-lg-0 navbar-right">
<div id="nbsa"></div>
<input class="form-control mr-sm-2" id="nbpc" placeholder="Postal Code" style="width:140px" aria-label="Postal Code" type="search">
<select class="form-control mr-sm-2" id="nbs">
<option value="1" selected="true">Average-case</option>
<option value="2">High-case</option>
</select>
</div>