fnPageChange not working without delay? JS sequence error? - javascript

I'm running into a strange issue, and it's happening across a few sites I maintain that use datatables.
Whenever I utilize fnPageChange, it does not work unless there is a setTimeout around it like this;
setTimeout(function() { oTable.fnPageChange(whatPage); }, 100);
or with an alert before it
alert('starting'); oTable.fnPageChange('last');
I understand this may be a sequence error of some sort, but I'm just unsure why the same issue would arise across multiple projects.
Here is the delete function I'm working with now:
function fnDelete(elem){
if (selected.length>0) {
var c;
c = confirm('Are you sure you want to delete the selected ${displayTableName}?');
if (c) {
// Create delete url from editor url...
var deleteURL = (urlstr.substring(0, urlstr.lastIndexOf('/') + 1)) + "delete.do";
deleteRecord(deleteURL,selected[0]);
if ( $('tableViewer tr').length === 0) {
// Reload the Table
oTable.fnPageChange('last');
//Send them back to the last page
}
}
}
}
Does anyone know what kind of issue this might be?
Here is deleteRecord:
function deleteRecord(deleteURL, iid){
var didDelete = false;
jQuery.ajax({
type: "POST",
url: deleteURL,
dataType:"html",
data:"recordID="+iid,
success:function(response){
didDelete = true;
oTable.fnDraw(true);
selected = [];
selectedRecord = [];
enableButtons(selected);
},
error:function (xhr, ajaxOptions, thrownError){
if ((xhr.status >=400) && (xhr.status < 500))
alert(xhr.responseText);
else
alert('error');
}
});
return didDelete;
}

You can try as below to
oTable.page(CurrentPageNo).draw(false);
Here, oTable is object of Datatable.

Related

AJAX sending multiple requests after button click

I just want one click to equal one submit in my jQuery code.
I've read quite a few posts on this same topic but I think mine is different. I do have a mouseleave and focusout event that I'm using to find errors in user input. Those functions feed down into the function that is submitting multiple times. The more times I hit mouseleave and focusout the more times my Ajax request is submitted. But I need mouseleave and focusout to continue to work and check the users input, that's why I'm not using one. Please see my code below, the function that I think is submitting multiple times is handleButtonClicksAfterError
function getCreditAmountToSend(modal){
console.log("getCreditAmountToSend");
var checkBox = $(modal).contents().find("#fresh-credit-checkbox");
checkBox.change(function(){
if($(checkBox).is(":checked")) {
var creditAmount = +(sessionStorage.getItem("creditAmount"));
sessionStorage.setItem('amountToSend', creditAmount);
}
});
var pendingCreditAmount = $(modal).contents().find("#pending_credit_amount");
pendingCreditAmount.on({
mouseleave: function(){
if(pendingCreditAmount.val() != ""){
adminForGetPendingCredit(modal);
}
},
focusout: function(){
if(pendingCreditAmount.val() != ""){
adminForGetPendingCredit(modal);
}
}
});
}
function adminForGetPendingCredit(modal){
console.log("adminForGetPendingCredit");
var checkBox = $(modal).contents().find("#fresh-credit-checkbox");
if(!$(checkBox).is(":checked")) {
var enteredAmount = +($(modal).contents().find("#pending_credit_amount").val());
var creditAmount = +(sessionStorage.getItem("creditAmount"));
sessionStorage.setItem('enteredAmount', enteredAmount);
doWeDisplayError(modal,creditAmount, enteredAmount);
}
}
function doWeDisplayError(modal,creditAmount, enteredAmount){
console.log("doWeDisplayError");
$(modal).contents().find("#fresh-credit-continue-shopping").prop("disabled", false);
$(modal).contents().find("#fresh-credit-checkout").prop("disabled", false);
if(creditAmount < enteredAmount){
$(modal).contents().find("#pending_credit_amount").val("");
$(modal).contents().find("#fresh-credit-continue-shopping").prop("disabled", true);
$(modal).contents().find("#fresh-credit-checkout").prop("disabled", true);
displayError();
}
else{
handleButtonClicksAfterError(modal, enteredAmount);
}
}
function handleButtonClicksAfterError(modal, enteredAmount){
// this is the problem!!!!!!!!!!!!!
console.log("handleButtonClicksAfterError");
sessionStorage.setItem('amountToSend', enteredAmount);
var continueButton = $(modal).contents().find("#fresh-credit-continue-shopping");
continueButton.click(function() {
modal.hide();
});
var checkoutButton = $(modal).contents().find("#fresh-credit-checkout");
checkoutButton.click(function() {
console.log("handleButtonClicksAfterError");
sendData();
});
}
function displayError(){
console.log("displayError");
$(function(){
$("#fresh-credit-iframe").contents().find("#pending_credit_amount").attr("placeholder", "Whoops, that was too much");
$("#fresh-credit-iframe").contents().find("#pending_credit_amount").attr({
class: "form-control form-control-red"
});
sessionStorage.removeItem('enteredAmount');
});
}
This is the function that actually POSTs the data
function sendData(){
var amountToSend = sessionStorage.getItem("amountToSend");
var products = $.parseJSON(sessionStorage.getItem("products"));
console.log("sendData");
console.log("This is the amount to send " + amountToSend);
$.ajax({
url: "/apps/proxy/return_draft_order",
data: {amountToSend, products},
type: "POST",
dataType: "json",
complete: function(data) {
window.location.href = data.responseText;
console.log("This is the URL from poll " + data.responseText );
return false;
},
});
}
It ended up being super simple.. I just needed the jQuery off method.. I attached it to the button before click and everything is peachy.. Looks like this:
checkoutButton.off().click(function(){});
off clears all the previous event handlers and then just proceeds with Click
Pretty cool, to read more check it out here
use async:false to prevent multiple request
$(document).off('click').on('click', function(){
$.ajax({
type:'POST',
url: ,
async:false,
cache: false,
data:{}
,
success: function(data){
},
error:function(data){
}
});
});

Issue with javascript and setting selected index of a select

I've got a piece of code that populates a dropdown based on the selection of another dropdown. This propogates through 4 dropdowns so:
selection -> selection based on 1 -> selection based on 1 & 2 -> selection based on 1, 2, & 3.
My issue is that sometimes the selection only comes up as 1 item, making it such that the user cannot "fire" the onchanged event. As such, upon population, I want to set the selected index to 0. Easy peasy, right?
So here's my code (edited to include full javascript function):
function FillProject() {
var BusinessAreaDropDown = document.getElementById("BusinessAreaDropDown");
var BusinessAreaSelection = BusinessAreaDropDown.options[BusinessAreaDropDown.selectedIndex].text
var GenericProjectDropDown = document.getElementById("GenericProjectDropDown");
if (GenericProjectDropDown.selectedIndex == -1) {
GenericProjectDropDown.selectedIndex = 0;
}
var GenericProjectSelection = GenericProjectDropDown.options[GenericProjectDropDown.selectedIndex].text
#* Get list from C# for GenericProjects matching *#
$.ajax({
url: '/Home/FillProject',
type: "GET",
dataType: "JSON",
data: { BusinessArea: BusinessAreaSelection, GenericProject: GenericProjectSelection },
error: function (error) {
alert(error);
},
success: function (Projects) {
$("#ProjectDropDown").html("");
$.each(Projects, function (i, project) {
$("#ProjectDropDown").append(
$('<option></option>').val(project).html(project));
});
}
})
}
This generates an error. If I place an alert after the if statement, it says that the selected index is still -1. Here's where stuff gets weird. If I place an alert INSIDE the if statement it pops up saying that the selected index is -1 before changing, 0 after changing, and actually changes the selectedIndex to 0, causing the code to work. If I remove the alert statement, it goes back to failing. What's happening here?
Examples:
Works->
if (GenericProjectDropDown.selectedIndex == -1) {
alert(GenericProjectDropDown.selectedIndex);
GenericProjectDropDown.selectedIndex = 0;
}
Works->
if (GenericProjectDropDown.selectedIndex == -1) {
GenericProjectDropDown.selectedIndex = 0;
alert(GenericProjectDropDown.selectedIndex);
}
Fails ->
if (GenericProjectDropDown.selectedIndex == -1) {
GenericProjectDropDown.selectedIndex = 0;
}
Solution! Thanks to #charlietfl
I had some ajax that was running in a previous code chunk populating the dropdown and it wasn't finixshed before running the second script because it was asynchronous. By adding:
$.ajax({
url: '/Home/FillProject',
type: "GET",
dataType: "JSON",
async: false, //this line
data: { BusinessArea: BusinessAreaSelection, GenericProject: GenericProjectSelection },
error: function (error) {
alert(error);
},
success: function (Projects) {
$("#ProjectDropDown").html("");
$.each(Projects, function (i, project) {
$("#ProjectDropDown").append(
$('<option></option>').val(project).html(project));
});
The issue was resolved!

autofocus(autotab) on next element is not working for dynamically created fields

$("#destination1" + countVar).autocomplete({
minLength : 3,
source : function(request, response) {
var url = configOptions.icaocodeUrl;
var term = request.term;
url=url+term;
console.log(url);
$.ajax({
url : url,
type : "GET",
data : request,
dataType : "json",
success : function(data) {
response(data.slice(0, 10));
//alert(data);
},error: function(xhr, textStatus) {
alert('error');
}
});
},
change:function(event,ui){
console.log("fired in dest2");
},close:function(event,ui){
console.log("close in dest2"+'#dof1'+countVar);
console.log(countVar);
$(this).parents('form').find('#dof1'+countVar)
.filter(function () { return $(this).val() === ''; })
.first().focus();
}
});
above is my code for autocomplete and autotab(autofocus) to next field for dynamically created elements.autotab(autofocus ) is working fine for normal html but it is not working for dynamically created elements only.
Are you trying to focus() on a tab that is being dynamically added? If so, you might be triggering focus() to soon and the DOM element might not be there.
Try wrapping the focus function into a setTimeout() function to test it out.
setTimeout(function () {
$(this).parents('form').find('#dof1'+countVar)
.filter(function () { return $(this).val() === ''; })
.first().focus();
}, 2000); // 2 seconds

Running a form handled by ajax in a loaded ajax page?

Using tutorials found i'm currently loading new pages with this:
$("a.nav-link").click(function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#userright');
$wrap
// removing old data
.html('')
// slide it up
.hide()
// load the remote page
.load(href + ' #userright', function () {
// now slide it down
$wrap.fadeIn();
});
});
This loads the selected pages perfectly, however the pages have forms that themselves use ajax to send the following:
var frm = $('#profileform');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
alert(data)
}
});
However this is not sending the form as it did before the page itself was called to the parent page via ajax. Am I missing something? Can you not use an ajax call in a page already called by ajax?
I also have other issues, for example I disable the submit button unless there are any changes to the form, using:
var button = $('#profile-submit');
var orig = [];
$.fn.getType = function () {
return this[0].tagName == "INPUT" ? $(this[0]).attr("type").toLowerCase() : this[0].tagName.toLowerCase();
}
$("#profileform :input").each(function () {
var type = $(this).getType();
var tmp = {
'type': type,
'value': $(this).val()
};
if (type == 'radio') {
tmp.checked = $(this).is(':checked');
}
orig[$(this).attr('id')] = tmp;
});
$('#profileform').bind('change keyup', function () {
var disable = true;
$("#profileform :input").each(function () {
var type = $(this).getType();
var id = $(this).attr('id');
if (type == 'text' || type == 'select') {
disable = (orig[id].value == $(this).val());
} else if (type == 'radio') {
disable = (orig[id].checked == $(this).is(':checked'));
}
if (!disable) {
return false; // break out of loop
}
});
button.prop('disabled', disable);});
However this also doesn't work when pulled to the parent page. Any help much appreciated! I'm really new to ajax so please point out any obvious mistakes! Many thanks in advance.
UPDATE
Just an update to what i've found. I've got one form working by using:
$(document).on('mouseenter', '#profile', function() {
However the following:
$(document).on('mouseenter', '#cancelimage', function() {
$('#cancelimage').onclick=function() {
function closePreview() {
ias.cancelSelection();
ias.update();
popup('popUpDiv');
$('#imgForm')[0].reset();
} }; });
Is not working. I understand now that I need to make it realise code was there, so I wrapped all of my code in a mouseover for the new div, but certain parts still don't work, so I gave a mouseover to the cancel button on my image form, but when clicked it doesn't do any of the things it's supposed to.
For anyone else who comes across it, if you've got a function name assigned to it, it should pass fine regardless. I was trying to update it, and there was no need. Doh!
function closePreview() {
ias.cancelSelection();
ias.update();
popup('popUpDiv');
$('#imgForm')[0].reset();
};
Works just fine.

submit during beforeunload, maybe who knows radically another method solution

Reviewed many similar questions on stackoverflow.com (also on other resources), but found no answers. So I simplified and generalized questions. It seems like the obvious solution:
$(document).ready(function() {
var a = 3;
var b = 5;
// no message when pressed submit button
$('form').submit(function() {
$(window).off('beforeunload');
});
// confirm of the need to save
$(window).on('beforeunload', function(e) {
if (a != b)
if (confirm('You changed data. Save?')) {
$('form').submit();
// alert('Your data is saved. (With alert submit() work only in FireFox!?)');
}
});
});
But not submit work. If you use the alert(), it works only in FireFox. I would like to correct (possibly without delay) cross-browser solution. Maybe who knows radically another method solution.
P.S. On some originality beforeunload described here in the first part: https://stackoverflow.com/a/6065085/1356425, but this is not the solution obvious functional.
Chrome and Firefox blocking submits after the onbeforeunload-event. You have to use
$(window).on('beforeunload', function(e) {
if (a != b)
return 'You\'ve changed the data. Leave page anyway?';
}
});
I used synchronous AJAX (JAX) request and run handler for events onUnload or onBeforeUnload once for the respective browser. This solution has a single and almost cross-browser behavior.
Example (on jsfiddle):
$(document).ready(function() {
var form = $('form');
var textareas = $('textarea');
function array_compare(a_0, a_1) {
if(a_0.length != a_1.length)
return false;
for(i = 0; i < a_0.length; i++)
if(a_0[i] != a_1[i])
return false;
return true;
}
var flag = false; // flag to control the execution of the unloadHandler() once
var a_open = []; // array with data before unload
$('textarea').each(function(index) {
a_open.push($(this).val());
});
function unloadHandler() {
if (flag)
return;
var a_close = []; // array with data during unload
$('textarea').each(function(index) {
a_close.push($(this).val());
});
if (!array_compare(a_open, a_close)) {
if (confirm('You changed the data, but not saved them. Save?')) {
$.ajax({
type: 'POST',
url: '/echo/json/',
async: false,
data: form.serialize()/* {
json: JSON.stringify({
text: 'My test text.'
}),
delay: 3
} */,
success: function(data) {
if (data) {
console.log(data);
alert('All data is saved!');
}
}
});
}
}
flag = true;
}
// For FireFox, Chrome
$(window).on('beforeunload', function () {
unloadHandler();
});
// For Opera, Konqueror
$(window).unload(function() {
unloadHandler();
});
// Without message when pressed submit button
$('form').submit(function() {
$(window).off('beforeunload');
$(window).off('unload');
});
});
Best way to submit data on unload is to store it in localstorage and send it next time when any other page under same origin is requested.
function sendBeacon(data) {
data?dataArr.push(data):'';
for (var i = 0, len = dataArr.length; i < len; i++) {
$.getScript(dataArr[i], (function (index) {
dataArr.splice(index, 1) //Updata dataArray on data submission
}(i)))
}
}
$(window).on('beforeunload', function () {
localStorage.setItem('dataArr', JSON.stringify(dataArr));
})
var dataArr = JSON.parse(localStorage.getItem('dataArr'));
if (!dataArr) {
dataArr = []; // Create Empty Array
} else {
sendBeacon(dataArr); //Submit stored data
}

Categories

Resources