I want to create this function:
If ID is 10 digits it should make ajax call to file number 1
If ID is 18 digits it should make ajax call to another file
Here is the code:
function get_invoice_info(expressid,expressno,div_id)
{
document.getElementById("retData")
.innerHTML="<center>Please wait fetching tracking details for you...</center>";
var expressno = '{$order.invoice_no}';
var matches = expressno.match(/^\d{12}$/);
Ajax.call('plugins/track/tracking.php?CN='+ expressno,
'showtest=showtest',
function(data){
document.getElementById("retData").innerHTML=data;
},
'GET',
'TEXT'
);
} else {
Ajax.call('plugins/track/tracking.php?CN='+ expressno,
'showtest=showtest',
function(data) {
document.getElementById("retData").innerHTML=data;
},
'GET',
'TEXT'
);
}
This code is working exactly as i wanted it to be
function get_invoice_info(expressid,expressno,div_id)
{
var waitMsg = "Please wait fetching tracking details for you...";
document.getElementById("retData").innerHTML= waitMsg;
var expressno = '{$order.invoice_no}';
if(expressno.length === 12) {
filePath='tracking';
} else if(expressno.length === 18) {
filePath='track';
} else {
//Not in range, so exit
return;
}
Ajax.call('plugins/track/'+filePath+'.php?CN='+ expressno, 'showtest=showtest', function(data){document.getElementById("retData").innerHTML=data;}, 'GET', 'TEXT');
}
Am I missing something, seems like you can just check length (or does it need to only be numeric, in which case you can add another if statement to the beginning that checks for non numeric characters).
function get_invoice_info(expressid,expressno,div_id) {
var waitMsg = "Please wait fetching tracking details for you...";
var expressno = '{$order.invoice_no}';
var filePath = null;
document.getElementById("retData").innerHTML= waitMsg;
if(expressno.length === 10) {
filePath='file1';
} else if(expressno.length === 16) {
filePath='file2';
} else {
//Not in range, so exit
return;
}
var onSuccess = function(data){
document.getElementById("retData").innerHTML=data;
};
Ajax.call('plugins/track/'+filePath+'.php?CN='+ expressno,
'showtest=showtest',
onSuccess,
'GET',
'TEXT'
);
Related
I want my serach function when user stop typing, because when typing the search is being performed for each charecter. For that issue search is taking so much time. So I want when user stop typing then search function will start. My current search code:
function search(){
var searchKey = $('#search').val();
if(searchKey.length > 3){
$('body').addClass("typed-search-box-shown");
$('.typed-search-box').removeClass('d-none');
$('.search-preloader').removeClass('d-none');
$.post('{{ route('search.ajax') }}', { _token: AIZ.data.csrf, search:searchKey}, function(data){
if(data == '0'){
// $('.typed-search-box').addClass('d-none');
$('#search-content').html(null);
$('.typed-search-box .search-nothing').removeClass('d-none').html('Sorry, nothing found for <strong>"'+searchKey+'"</strong>');
$('.search-preloader').addClass('d-none');
}
else{
$('.typed-search-box .search-nothing').addClass('d-none').html(null);
$('#search-content').html(data);
$('.search-preloader').addClass('d-none');
}
});
}
else {
$('.typed-search-box').addClass('d-none');
$('body').removeClass("typed-search-box-shown");
}
}
Here's a debounced (and rewritten, with jQuery objects cached, async/await instead of a callback function, etc.) version of your search function.
Basically on keyUp you call searchDebounced(), which will then call the actual search() 500ms later, unless a new key is pressed, which resets the timeout and waits an additional 500ms :
const $search = $('#search'),
$searchContent = $('#search-content'),
$body = $("body"),
$typedSearchBox = $('.typed-search-box'),
$searchPreloader = $('.search-preloader'),
$searchNothing = $('.typed-search-box .search-nothing');
let debounceTimeout = null
function searchDebounced() {
const searchKey = $search.val().trim();
if (searchKey.length < 4) {
$typedSearchBox.addClass('d-none');
$body.removeClass("typed-search-box-shown");
return;
}
// These two lines do the debouncing work
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout( search, 500 );
}
async function search() {
$body.addClass("typed-search-box-shown");
$typedSearchBox.removeClass('d-none');
$searchPreloader.removeClass('d-none');
const data = await $.post('{{ route(' + search.ajax + ') }}', { // No idea what this route is, I'm assuming it makes sense somehow
_token: AIZ.data.csrf,
search: searchKey
})
if (data == '0') {
$searchContent.html(null);
$searchNothing.removeClass('d-none').html('Sorry, nothing found for <strong>"' + searchKey + '"</strong>');
} else {
$searchContent.html(data);
$searchNothing.addClass('d-none').html(null);
}
$searchPreloader.addClass('d-none');
}
So I have a PHP form which is being submitted with isset($_POST[]). I wrote a js function which runs some code with if-else which should return true/false but it's not and the form is getting submitted regardless.
I've tried using e.preventDefault() but that hasn't worked for me either. I also tried putting the true/false in a var as so out = true/false (Of course I put them in different var as for if and else), and then tried returning them as return out.
Code for true/false in var -
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
out = false;
}
else {
out = true;
}
window.location = "add_working_details.php";
return out;
}
Original Code -
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
// event.preventDefault();
//out = false;
return false;
window.location = "add_working_details.php";
}
else {
// out = true;
return true;
}
//return out;
// window.location = "add_working_details.php";
}
The AJAX function-
$("#submit").click(function(){//comparing the total quoted hours with duration of time selected
ticket_id = $('#ticket_no').val();
total_hours = $('#total_hours').val();
var user_dur, ud, th;
$.ajax({
url: 'comp_time.php',
type: 'GET',
data: {ticket_id: ticket_id, total_hours: total_hours} ,
success: function (response) {
// console.log("response", response);
var resp = response;
user_dur = $('#time_duration').text();
ud = compare_time(user_dur); //user duration
th = Number(resp); //total quoted hours
submitFunc(ud, th);
}
});
});
So I believe that returning false should stop the form from submitting and then with the window.location it should redirect to the page I want but it's not doing so.
Please correct me if my logic is wrong. Thanks for your time.
First your function should prevent the submit regardless of the event outcome
$("#submit").click(function(e){
e.preventDefault();
second you need to remove the returns from your function, they don't affect you click event
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
} else {
window.location = "add_working_details.php";
}
}
$('#form').submit(function(e) {
if (submitFunc(1, 2)) {
$.ajax({});
} else {
e.preventDefault();
}
})
I've got some IDS that I want to use to fill / generate some jQuery Objects. I use these IDS in ajax requests.
After the jQuery Objects have been filled, I want to sort them.
Has to work in IE11.
What my problem is:
At the moment I've no idea how the best practice would look like, to wait for all ajax requests and as well all jQuery objects to be filled.
I have to wait until all ajax requests have been completed (so
always, indepedent from response code (so on .done and .fail))
I have to wait until all
jQuery Objects are filled with the results from the ajax Requests
Problem conclusion: sort function is called before the items are filled.
I've tried to break down my whole code to a simple example, maybe someone can help here:
function sortEntries(a, b) {
var aa = ($(a).data('name') || '').toLowerCase(),
bb = ($(b).data('name') || '').toLowerCase();
return aa < bb ? -1 : aa > bb ? 1 : 0;
}
function getEntryInfo(infoObj, callback) {
function getLabelByResult(result) {
var name = '';
switch (result) { // For this demo, we don't use the response data.
case 'page-header':
name = 'Hello World 1';
break;
case 'thumbnails':
name = 'It works!';
break;
case 'nav':
name = 'Great!';
break;
case 'btn-groups':
name = 'BTN GROUP';
break;
default:
name = 'NOT SET!'
}
return name;
}
return $.ajax({
method: 'GET',
url: infoObj.URI,
cache: false
}).done(function(data) {
if ($.isFunction(callback)) {
callback(true, {
name: getLabelByResult(infoObj.element)
});
}
}).fail(function() {
if ($.isFunction(callback)) {
callback(false, {
name: getLabelByResult(infoObj.element)
});
}
});
}
function setInfoForEntry(item$, config) {
return getEntryInfo(config, function(isOk, responseObjInfo) {
item$.attr('data-name', responseObjInfo.name || '').text(responseObjInfo.name || '');
});
}
function generateItems() {
var parentItem$ = $('body').append($('<ul/>').addClass('allItems').hide()),
ids = ['page-header', 'thumbnails', 'nav', 'btn-groups'], // for testing purposes of course
requests = [],
extractedItems$;
$.each(ids, function(ignorel, el) {
var newItem$ = $('<li/>').addClass('idItem').on('click', function(e) {
alert($(e.currentTarget).data('name'));
});
parentItem$.append(newItem$);
requests.push(setInfoForEntry(newItem$, {
URI: 'https://getbootstrap.com/docs/3.3/components/#/' + el,
element: el
}));
});
// HERE I HAVE TO ENSURE THAT:
// -ALL AJAX REQUESTS ARE DONE
// -ALL jQuery Elements are filled
extractedItems$ = parentItem$.find('.idItem');
extractedItems$.sort(sortEntries);
extractedItems$.detach().appendTo(parentItem$);
parentItem$.show();
}
$(document).ready(function() {
generateItems();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body></body>
To wait for multiple promises, jQuery has the $.when() utility function. Also see this thread and this thread (there are quite a few posts that discuss this, look around).
I've also streamlined your code a bit, I think it's much easier to read this way:
function by(func) {
return function (a, b) {
var aa = func(a), bb = func(b);
return aa < bb ? -1 : aa > bb ? 1 : 0;
};
}
$(function () {
var things = {
'page-header': 'Hello World 1',
'thumbnails': 'It works!',
'nav': 'Great!',
'btn-groups': 'BTN GROUP'
}, requests;
requests = $.map(Object.keys(things), function (key) {
return $.get('https://getbootstrap.com/docs/3.3/components/#/' + key)
.then(function (data) {
return $('<li class="idItem">', {text: things[key] || 'NOT SET!'})[0];
});
});
$.when.apply($, requests).done(function () {
// each argument here is a single <li> element
var items = $(arguments).sort(by(function (el) {
return ($(el).text() || '').toLowerCase();
}));
$('<ul class="allItems">').appendTo('body').append(items);
}).fail(function (jqXhr, status, error) {
// show error
});
});
I have a javascript function that has about 4 ajax requests in it. It typically takes less than a second to run. However, I'm working on the error handling now and was wondering. How long, in seconds, should I allow my javascript function to try to keep working until I manually cancel it and allow the user to try again?
Here's what the function in question looks like. (not everything is there, but it could potentially have (1000*5000*3)+(70)+(1000)+(6)+(2500) bytes being sent)
function saveChanges(bypassDeckSave){
// bypassDeckSave = undefined - does not bypass
showSavedNotification_check = 1;
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
console.log("db deck location not saved, asked for it");
//values to set to
var setFolderID = $('.libDeckLocationModifierDiv .folders li.on').val(),
setSubjectID = $('.libDeckLocationModifierDiv .subjects li.on').val();
if(isNaN(setFolderID) || isNaN(setSubjectID) ||
setFolderID == 0 || setSubjectID == 0)
{
openDeckLocationDiv();
showSavedNotification_check = 0;
return;
}
}
}
var deck_id = $('.deck_id').val();
if(deck_id == 0){
// create a new deck
createDeckThenSave();
return;
}
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
//values to set to
saveDeckLocation();
}
}
// removes empty rows
$('.editMain li').each(function(){
var one = $(this).find('.text1').val(),
two = $(this).find('.text2').val();
if(one == "" && two == ""){
//remove this row and remove value from updateSaveArray + add to delete array
var currentval = $(this).val();
var rowid = ".row_"+currentval;
updateSaveArray = jQuery.grep(updateSaveArray, function(value) {
return value != currentval;
});
$(rowid).remove();
updateDeleteArray[updateDeleteArray.length] = currentval;
}
});
if(bypassDeckSave == undefined){
// save deck info to db
var deckname = $('.editDeckNameInput').val(),
cardCount = $('.editMain li.mainLi:visible').length,
deckTermLanguage = $('.selector.one select').val(),
deckDefinitionLanguage = $('.selector.two select').val(),
deckThirdBoxLanguage = $('.selector.three select').val(),
deckDescription = $('.editMoreDeckOptionsDiv textarea').val();
if($('.editMoreDeckOptionsSelector .onlyme').hasClass("on")){
var viewPreferences = 1;
}else{
var viewPreferences = 0;
}
if($('.editUseThirdboxDiv').hasClass('on')){ var thirdbox = 1;
}else{ var thirdbox = 2; }
// console.log("deckInfoSave called");
$.ajax({
type: "POST",
url: "/edit/deckInfoSave.php",
data: { pDeckid: deck_id, pDeckname: deckname, pCardCount: cardCount,
pDeckTermLanguage: deckTermLanguage, pDeckDefinitionLanguage: deckDefinitionLanguage,
pDeckThirdBoxLanguage: deckThirdBoxLanguage, pThirdbox: thirdbox,
pDeckDescription: deckDescription, pViewPreferences: viewPreferences
}
})
.done(function(data){
// console.log(data);
// decksaved = 1;
saveDeckInfoHasFinished = 1;
});
}else{
saveDeckInfoHasFinished = 1;
}
// prepares edited card array
// gets all needed values and stores in holdSaveCardArray
var holdSaveCardArray = [];
for (i = 0; i < updateSaveArray.length; ++i) {
var currentCard_id = updateSaveArray[i],
rowidClass = ".row_"+currentCard_id,
text1val = $(rowidClass+" .text1").val(),
text2val = $(rowidClass+" .text2").val(),
text3val = $(rowidClass+" .text3").val();
cardOrder = $(".editMain li.mainLi:visible").index($(rowidClass)) + 1;
holdSaveCardArray[holdSaveCardArray.length] = {
"card_id": currentCard_id,
"text1val": text1val,
"text2val": text2val,
"text3val": text3val,
"cardOrder": cardOrder
};
}
// console.log(print_r(holdSaveCardArray));
// delete cards start
// deletes any card with an id in updateDeleteArray
$.ajax({
type: "POST",
url: "/edit/deleteCards.php",
data: { pDeck_id: deck_id, pDeleteArray: updateDeleteArray }
})
.done(function( msg ) {
// $('.temp').append(msg);
updateDeleteArray = [];
deleteCardsHasFinished = 1;
});
// save cards to database
// loops through each card that had changes made to it
$.ajax({
type: "POST",
url: "/edit/saveCardsArray.php",
dataType: "JSON",
data: { pDeck_id: deck_id, pCardArray: holdSaveCardArray}
}).done(function(data){
for (var i = 0; i < data.length; i++) {
var temp_id = data[i]["temp_id"], // new id
card_key = data[i]["card_key"], // old id
currentClassName = 'row_'+temp_id,
currentClass = '.row_'+temp_id,
nextClassName = 'row_'+card_key;
$(currentClass).val(card_key);
$(currentClass).removeClass(currentClassName).addClass(nextClassName);
}
saveCardsHasFinished = 1;
});
updateSaveArray = [];
// update order start // uses li value
updateOrderArray = [];
$('.editMain').find(".mainLi").each(function(){
var temp = $(this).val();
updateOrderArray[updateOrderArray.length] = temp;
});
$.ajax({
type: "POST",
url: "/edit/orderCards.php",
data: { pUpdateOrderArray: updateOrderArray }
})
.done(function( msg ) {
updateOrder = 0;
updateOrdersHasFinished = 1;
});
closeLibDLM(); console.log("closeLibDLM1");
changeSaveStudyButton(1);
} //saveChanges function end
So you could totally set an arbitrary timeout, or even a timeout that should encompass everything finishing on time? But, what happens when it doesn't? What happens when it takes longer to finish?
At that point, you're going to be in quite a pickle. I did not thoroughly read your code, but I would highly advise trying to use a callback() or Promise to end your function. And, not set a timeout. - This is a cleaner solution in that things happen when you want them, and after some defined has happened. Time is a relative, and finicky attribute of our world (Einstein proved this =P) that would be best be used as your friend, and not your enemy.
The counter argument would be, well sometimes things just hang. And, that is totally valid. For that case, you could set a timeout for a long period of time. But, again, that is still a 'hacky' way to handle things. In this case, I would try to create some handling to detect errors, or timeouts. i.e you could periodically check the page for a status. You could check to see which events are in existence that you could hook into.
If you could share in what instances our program hangs, I could better suggest a solution. Otherwise this question may end up being opinionated based on coding styles.
Hope this helps in some regard :)
I've worked in the Aerospace Aviation Industry and have asked a similar question when working with Microcontrollers. It seems you are looking for an appropriate timeout value based on calculation, but this may not be necessary in your case. Often times timeout values are more or less arbitrary. If your function executes in an average of roughly 1 second, maybe your timeout value should be set to 3 seconds. You should come to a conclusion based on testing.
I have an error checking function that is just running me in circles.
function emailValUReq(v, noRet) {
var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
if (!v.val()) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Required Field');
}
return 1;
} else if (!textReg.test(v.val())) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Invalid Entry');
}
return 1;
} else {
$data = new Object;
$data['email'] = v.val();
$data['id'] = v.data('cur');
$.ajax({
type: "POST",
url: "/modules/data/dup_check.php",
data: $data,
success: function (r) {
if (r == 'ok') {
v.nextAll('.errText').empty();
return 0;
} else {
if (noRet == null) {
v.nextAll('.errText').html('<br>! An account already exists for this email');
}
return 1;
}
}
});
}
}
This function works perfectly overall. It returns 1 on an error, 0 when a value is correctly formatted and unique. The problem comes in when I try to 'add up' the errors from multiple functions.
(area and noRet are passed in)
var vErr=0;
area.find('.emailvalureq:visible').each(function () {
vErr += emailValUReq($(this), noRet);
});
When the input field is empty, or when it is incorrectly formatted, this works properly. As soon as the $.ajax call is fired within the validation script, it seems that the delay messes everything up and vErr ends up being a NaN value.
I have tried doing this as follows, with the same result:
var vErr=0;
area.find('.emailvalureq:visible').each(function () {
var ve1 = emailValUReq($(this), noRet);setTimeout(function(){vErr+=ve1;},1000);
});
I'm going to be at a family wedding for a couple hours, so I won't be able to respond to any questions / suggestions until later tonight - but any help is appreciated!
I tried using a when / done statement as follows:
$.when(emailValUReq($(this),noRet)).done(function(r){vErr+=r;});
but the problem with this was that 'r' was undefined (I was hoping it would pull the returned value from the emailValUReq function).
For me, the solution was to rework the emailValUReq function to simply update the error variable directly, as follows:
function emailValUReq(v, noRet) {
var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
if (!v.val()) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Required Field');
}
$err++;
} else if (!textReg.test(v.val())) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Invalid Entry');
}
$err++;
} else {
$data = new Object;
$data['email'] = v.val();
$data['id'] = v.data('cur');
$.ajax({
type: "POST",
url: "/modules/data/dup_check.php",
data: $data,
success: function (r) {
if (r == 'ok') {
v.nextAll('.errText').empty();
} else {
if (noRet == null) {
v.nextAll('.errText').html('<br>! An account already exists for this email');
}
$err++;
}
}
});
}
}
$err=0;
area.find('.emailvalureq:visible').each(function () {
emailValUReq($(this), noRet);
});
All that I need to then do is delay checking the value of $err for roughly 1 second, which gives the ajax call enough time to run and return the response.
setTimeout(function(){return $err;},1128);
I'm not sure if this was the best response, or the most elegant, but it worked!