Brandon Brandon - 10 days ago 5
jQuery Question

Ajax - Issue passing POST through

My code was working great, but I didnt like the input event I was using since it happens every time a key is pushed. This Ajax is to update the database so I was searching for a way to delay a few seconds before submitting which another awesome member here showed me. The issue I am now having though is that POST variables are no longer making it through Ajax for some reason and I cant figure out why.

My Question Is: Why is this happening and how can I tweak this to fix it.

Below is first the code that was working great but using the input event, second is the code I want to use now, but Ajax isnt passing variables through.

Old Code:

$('td').on('input',function() {
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: $(this).text(),
date: $(this).siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + ($(this).index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
});

toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}

toastr.info(old,'Your Previous Amount Was:');

});


New Code not working correctly:

var saveTimeout = false;

$('td').on('input', function() {

if(saveTimeout) clearTimeout(saveTimeout);

saveTimeout = setTimeout(function() {
console.log($(this));
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: $(this).text(),
date: $(this).siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + ($(this).index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
});

toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}

toastr.info(old,'Your Previous Amount Was:');

}, 2500);
});


Snippet:



var old;

$('td').click(function(){

old=$(this).text();

editclick="yes;"

$(this).prop('contenteditable', true);

// var days = 7;
// var result = $(this).siblings().first().text();
// result.setDate(result.getDate() + days);
// alert( result );

});

var saveTimeout = false;

$('td').on('input', function() {

if(saveTimeout) clearTimeout(saveTimeout);
saveTimeout = setTimeout(function() {
console.log($(this))
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: $(this).text(),
date: $(this).siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + ($(this).index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
});

toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}

toastr.info(old,'Your Previous Amount Was:');

}, 2500);
});


$("td").hover(function(){



$(this).addClass('highlight').siblings().first().addClass('highlight');

$('tr:eq(1) th:eq('+$(this).index()+')').addClass('highlight');


},function(){



$(this).removeClass("highlight").siblings().first().removeClass('highlight');

$('tr:eq(1) th:eq('+$(this).index()+')').removeClass('highlight');


});

table,th, td {

border: 1px solid black;
border-collapse: collapse;

}

.highlight {

background-color:#E0E0E0;
color: blue;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/1.3.1/css/toastr.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/1.3.1/js/toastr.js"></script>
<table>
<tr>
<th>Item #</th>
<th>1234567</th>
<th>7654321</th>
<th>5678945</th>
</tr>
<tr>
<th>Product</th>
<th><u>22 ounce Dark</u></th>
<th><u>12count 4oz Dark</u></th>
<th><u>24count 6oz TJ</u></th>
</tr>
<tr>
<th>2016-01-03</th>
<td>13587</td>
<td>2203</td>
<td>4111</td>
</tr>
<tr>
<th>2016-01-04</th>
<td>14111</td>
<td>3247</td>
<td>4332</td>
</tr>
<tr>
<th>2016-01-05</th>
<td>13212</td>
<td>3101</td>
<td>3911</td>
</tr>
<tr>
<th>2016-01-06</th>
<td>16335</td>
<td>3299</td>
<td>4001</td>
</tr>
<tr>
<th>2016-01-07</th>
<td>15421</td>
<td>3100</td>
<td>4078</td>
</tr>
</table>




Answer

So, that $(this) does not refer to the input field but to the window object is the problem here. This happens because you wrapped the function inside the event handler in setTimeout, which changes the execution context of the function.

But this should be fixable, if you just store the reference to the input field into a local variable first, and then use that inside the timeout-ed (that a word?) function, like this:

$('td').on('input', function() {

    var _this = $(this); // preserve reference to the input field here

    if(saveTimeout) clearTimeout(saveTimeout);

    // replace $(this) with _this everywhere inside this function
    saveTimeout = setTimeout(function() {
            $.ajax({
            method: "POST",
            url: "updatedatabase.php",
            data: { 
                content: _this.text(), 
                date: _this.siblings().first().text(),
                prod: $('tr:first-child th:nth-child(' + (_this.index() + 1) + ')').text(),
                old: old
            }
        })
Comments