I am trying to get a better understanding on javacsript. And I am not sure why this code is not working. I am trying to create functions that will call another function. And return the results of the called function.
When I call the below, I get fully logged in and presented with the screen I desire. But jsDidLogin Always returns undefined. Is there a better way to implement my methods?
var jsDidLogin = beginLogin()
console.log(jsDidLogin)
function waitUntilElementFound(element, time, callFunction) //Wait for the element to be found on the page
{
if (document.querySelector(element) != null) {
return callFunction();
}
else {
if (!checkForFailedLogin()) {
setTimeout(function () {
waitUntilElementFound(element, time, callFunction);
}, time);
}
else {
return false;
}
}
}
function checkForFailedLogin() {
if (document.querySelector("div[class='modal-body ng-scope'] h1") != null) {
if(document.querySelector("div[class='modal-body ng-scope'] h1").innerHTML == "Login Error")
{
return true;
}
}
else {
return false;
}
}
function initialTabSelect() //Load the bank page once login is completed
{
document.querySelectorAll("li[class='Tab'] a")[0].click();
return "Fully Logged In";
}
function initialDoNotAsk() {
document.querySelectorAll("a[ng-click='modalCancel()']")[0].click();
return waitUntilElementFound("li[class='Tab'] a", 1000, initialTabSelect);
}
function initialLogin() {
var accountName = document.getElementById("username");
var accountPassword = document.getElementById("password");
var evt = document.createEvent("Events");
evt.initEvent("change", true, true);
accountName.value = "USERNAME";
accountPassword.value = "PASSWORD";
accountName.dispatchEvent(evt);
accountPassword.dispatchEvent(evt);
document.querySelectorAll("form[name='loginForm'] button.icon-login")[0].click();
return waitUntilElementFound("a[ng-click='modalCancel()']", 2000, initialDoNotAsk);
}
function beginLogin() {
return waitUntilElementFound("form[name='loginForm'] button.icon-login", 1000, initialLogin);
}
Changing to this alerts me when Fully Logged in, but if I change it to return status. I still get no returns.
My head is starting to hurt :(
function waitUntilElementFound(element, time, callFunction, callBack) //Wait for the element to be found on the page
{
if (document.querySelector(element) != null) {
callBack(callFunction());
}
else {
if (!checkForFailedLogin()) {
setTimeout(function () {
callBack(waitUntilElementFound(element, time, callFunction, function(status){alert(status);}));
}, time);
}
else {
return false;
}
}
}
function checkForFailedLogin() {
if (document.querySelector("div[class='modal-body ng-scope'] h1") != null) {
if(document.querySelector("div[class='modal-body ng-scope'] h1").innerHTML == "Login Error")
{
return true;
}
}
else {
return false;
}
}
function initialTabSelect() //Load the bank page once login is completed
{
document.querySelectorAll("li[class='Tab'] a")[0].click();
return "Fully Logged In";
}
function initialDoNotAsk() {
document.querySelectorAll("a[ng-click='modalCancel()']")[0].click();
return waitUntilElementFound("li[class='Tab'] a", 1000, initialTabSelect, function(status){alert(status)};);
}
function initialLogin() {
var accountName = document.getElementById("username");
var accountPassword = document.getElementById("password");
var evt = document.createEvent("Events");
evt.initEvent("change", true, true);
accountName.value = "USERNAME";
accountPassword.value = "PASSWORD";
accountName.dispatchEvent(evt);
accountPassword.dispatchEvent(evt);
document.querySelectorAll("form[name='loginForm'] button.icon-login")[0].click();
return waitUntilElementFound("a[ng-click='modalCancel()']", 2000, initialDoNotAsk, function(status){alert(status)};);
}
function beginLogin() {
return waitUntilElementFound("form[name='loginForm'] button.icon-login", 1000, initialLogin, function(status){alert(status)};);
}
Related
I have a JavaScript function that updates my data.
The user may Click several times and I want to Wait for the Second click while the first click is not finished and so on
$scope.isLastUpdateFinished = true;
$scope.onSave = function (isFitToPage) {
if (!$scope.isLastUpdateFinished)
while (!$scope.isLastUpdateFinished) {
}
$scope.isLastUpdateFinished = false;
dataService.save($scope.draft, "api/Draft/UpdateDraft/").then(function (data) {
if (data.Succeeded && data.Message != null)
toaster.pop("warning", _("Dataservice_TTL_Save"), data.Message);
if (!data.Succeeded) {
modalOptions.headerText = _("Error_InRefreshList");
modalOptions.bodyText = data.Message;
modalService.showModal(errorDefaults, modalOptions);
}
if (isFitToPage) {
$scope.imageviewer.viewerconfig.controls.imageReload(true, true);
}
if ($scope.myOtherAside.$scope.$isShown && isFitToPage) {
$scope.viewerconfig.controls.imageReload(true, true);
}
$scope.isLastUpdateFinished = true;
});
};
How about just notifying the user that the app is still working?
$scope.isLastUpdateFinished = true;
$scope.onSave = function (isFitToPage) {
if (!$scope.isLastUpdateFinished)
{
toaster.pop("info", "Please wait...", "Request already in progress... ");
return false;
}
$scope.isLastUpdateFinished = false;
dataService.save($scope.draft, "api/Draft/UpdateDraft/").then(function (data) {
if (data.Succeeded && data.Message != null)
toaster.pop("warning", _("Dataservice_TTL_Save"), data.Message);
if (!data.Succeeded) {
modalOptions.headerText = _("Error_InRefreshList");
modalOptions.bodyText = data.Message;
modalService.showModal(errorDefaults, modalOptions);
}
if (isFitToPage) {
$scope.imageviewer.viewerconfig.controls.imageReload(true, true);
}
if ($scope.myOtherAside.$scope.$isShown && isFitToPage) {
$scope.viewerconfig.controls.imageReload(true, true);
}
$scope.isLastUpdateFinished = true;
});
};
I am using the excellent onlinejs (https://github.com/PixelsCommander/OnlineJS) library for checking that my app has a live internet connection. However, I don't need it to fire regularly, but rather upon the manual calling of the main function.
I would like to modify this code so that it is not firing on a timer, and know the name of the function to call for manual firing, which assume is just getterSetter.
My previous attempts to modify the code below have broken the script as I'm no expert at JavaScript. I appreciate any help in adapting this very useful code.
function getterSetter(variableParent, variableName, getterFunction, setterFunction) {
if (Object.defineProperty) {
Object.defineProperty(variableParent, variableName, {
get: getterFunction,
set: setterFunction
});
}
else if (document.__defineGetter__) {
variableParent.__defineGetter__(variableName, getterFunction);
variableParent.__defineSetter__(variableName, setterFunction);
}
}
(function (w) {
w.onlinejs = w.onlinejs || {};
//Checks interval can be changed in runtime
w.onLineCheckTimeout = 5000;
//Use window.onLineURL incapsulated variable
w.onlinejs._onLineURL = "http://lascelles.us/wavestream/online.php";
w.onlinejs.setOnLineURL = function (newURL) {
w.onlinejs._onLineURL = newURL;
w.onlinejs.getStatusFromNavigatorOnLine();
}
w.onlinejs.getOnLineURL = function () {
return w.onlinejs._onLineURL;
}
getterSetter(w, 'onLineURL', w.onlinejs.getOnLineURL, w.onlinejs.setOnLineURL);
//Verification logic
w.onlinejs.setStatus = function (newStatus) {
w.onlinejs.fireHandlerDependOnStatus(newStatus);
w.onLine = newStatus;
}
w.onlinejs.fireHandlerDependOnStatus = function (newStatus) {
if (newStatus === true && w.onLineHandler !== undefined && (w.onLine !== true || w.onlinejs.handlerFired === false)) {
w.onLineHandler();
}
if (newStatus === false && w.offLineHandler !== undefined && (w.onLine !== false || w.onlinejs.handlerFired === false)) {
w.offLineHandler();
}
w.onlinejs.handlerFired = true;
};
w.onlinejs.startCheck = function () {
setInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
w.checkOnLine = function () {
w.onlinejs.logic.checkConnectionWithRequest(false);
}
w.onlinejs.getOnLineCheckURL = function () {
return w.onlinejs._onLineURL + '?' + Date.now();
}
w.onlinejs.getStatusFromNavigatorOnLine = function () {
if (w.navigator.onLine !== undefined) {
w.onlinejs.setStatus(w.navigator.onLine);
} else {
w.onlinejs.setStatus(true);
}
}
//Network transport layer
var xmlhttp = new XMLHttpRequest();
w.onlinejs.isXMLHttp = function () {
return "withCredentials" in xmlhttp;
}
w.onlinejs.isXDomain = function () {
return typeof XDomainRequest != "undefined";
}
//For IE we use XDomainRequest and sometimes it uses a bit different logic, so adding decorator for this
w.onlinejs.XDomainLogic = {
init: function () {
xmlhttp = new XDomainRequest();
xmlhttp.onerror = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
xmlhttp.ontimeout = function () {
xmlhttp.status = 404;
w.onlinejs.processXmlhttpStatus();
}
},
onInternetAsyncStatus: function () {
try {
xmlhttp.status = 200;
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
},
checkConnectionWithRequest: function (async) {
xmlhttp.onload = w.onlinejs.logic.onInternetAsyncStatus;
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("GET", url);
w.onlinejs.tryToSend(xmlhttp);
}
}
//Another case for decoration is XMLHttpRequest
w.onlinejs.XMLHttpLogic = {
init: function () {
},
onInternetAsyncStatus: function () {
if (xmlhttp.readyState === 4) {
try {
w.onlinejs.processXmlhttpStatus();
} catch (err) {
w.onlinejs.setStatus(false);
}
}
},
checkConnectionWithRequest: function (async) {
if (async) {
xmlhttp.onreadystatechange = w.onlinejs.logic.onInternetAsyncStatus;
} else {
xmlhttp.onreadystatechange = undefined;
}
var url = w.onlinejs.getOnLineCheckURL();
xmlhttp.open("HEAD", url, async);
w.onlinejs.tryToSend(xmlhttp);
if (async === false) {
w.onlinejs.processXmlhttpStatus();
return w.onLine;
}
}
}
if (w.onlinejs.isXDomain()) {
w.onlinejs.logic = w.onlinejs.XDomainLogic;
} else {
w.onlinejs.logic = w.onlinejs.XMLHttpLogic;
}
w.onlinejs.processXmlhttpStatus = function () {
var tempOnLine = w.onlinejs.verifyStatus(xmlhttp.status);
w.onlinejs.setStatus(tempOnLine);
}
w.onlinejs.verifyStatus = function (status) {
return status === 200;
}
w.onlinejs.tryToSend = function (xmlhttprequest) {
try {
xmlhttprequest.send();
} catch(e) {
w.onlinejs.setStatus(false);
}
}
//Events handling
w.onlinejs.addEvent = function (obj, type, callback) {
if (window.attachEvent) {
obj.attachEvent('on' + type, callback);
} else {
obj.addEventListener(type, callback);
}
}
w.onlinejs.addEvent(w, 'load', function () {
w.onlinejs.fireHandlerDependOnStatus(w.onLine);
});
w.onlinejs.addEvent(w, 'online', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.addEvent(w, 'offline', function () {
window.onlinejs.logic.checkConnectionWithRequest(true);
})
w.onlinejs.getStatusFromNavigatorOnLine();
w.onlinejs.logic.init();
w.checkOnLine();
w.onlinejs.startCheck();
w.onlinejs.handlerFired = false;
})(window);
Looking at the source, I believe you can simply call onlinejs.logic.checkConnectionWithRequest(false) to get the status synchronously. This function will return either true or false.
PS: I am sure there are better libraries for this task out there, I really do not like the way it's written and clearly, the author doesn't know JS very well. E.g., the following code taken from the library makes no sense at all.
w.onlinejs.stopCheck = function () {
clearInterval("window.onlinejs.logic.checkConnectionWithRequest(true)", w.onLineCheckTimeout);
}
I've read a lot of how to try and make two xmlhttprequest in parallel, but it looks like something doesn't quite work.
I have 1 php file. which includes 2 .js files.
The first runs xmlhttprequest every 3 seconds.
I want the second to run on demand, but whenever i trigger it, it returns with status 4 but the responseText is always empty. (the PHP file prints with no question, i even tried to put on the PHP file just window.open('1') to see that the file is called and its not).
Here is the first JS :
var req1 = createXMLHttpRequest2();
var user_redirected = false;
function createXMLHttpRequest2() {
var ua2;
if(window.XMLHttpRequest) {
try {
ua2 = new XMLHttpRequest();
} catch(e) {
ua2 = false;
}
} else if(window.ActiveXObject) {
try {
ua2 = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
ua2 = false;
}
}
return ua2;
}
function set_user_redirected_false() {
user_redirected = false;
}
function get_user_redirected() {
return user_redirected;
}
function handleResponse(username, game_id, isInvitation) {
if(req1.readyState == 4 && req1.status==200) {
var response = req1.responseText;
if (response == "true") {
// Ask to set the game_accepted var to 1 (user is redirected and not leaving)
user_redirected = true;
if (isInvitation == "true") {
window.location.href = "game.php?game_id="+game_id+"&position=2";
} else {
window.location.href = "game.php?game_id="+game_id+"&position=1";
}
}
else {
setTimeout(function(){sendRequest();}, 3000);
}
}
}
function sendRequest() {
user_redirected = false;
var username = "";
var game_id = -1;
var isInvitation = "false";
username = document.getElementById("username").value;
game_id = document.getElementById("game_id").value;
isInvitation = document.getElementById("invitation").value;
if (isInvitation == "true") {
req1.open('GET', 'check_for_inviter.php?username='+username+'&game_id='+game_id ,true);
} else {
req1.open('GET', 'check_for_opponent.php?username='+username+'&game_id='+game_id,true);
}
req1.onreadystatechange = function(){handleResponse(username, game_id, isInvitation);};
req1.send(null);
}
This is the second JS file :
function createXMLHttpRequest() {
var ua;
if(window.XMLHttpRequest) {
try {
ua = new XMLHttpRequest();
} catch(e) {
ua = false;
}
} else if(window.ActiveXObject) {
try {
ua = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
ua = false;
}
}
return ua;
}
function delete_waiting_games(username) {
var req2 = createXMLHttpRequest();
req2.open('GET', 'delete_waiting_games_for_username.php');
req2.onreadystatechange = function(){
window.open(req2.readyState+'&'+req2.responseText);
};
req2.send(null);
}
As you can see i open a new window to see the response and the ready state (just for testing) and i always get status 4 and empty responseText.
Thanks.
Use setTimeout to separate the calls, and with to encapsulate the XMLHTTPRequest:
function xhr()
{
with(new XMLHttpRequest)
{
open("GET",{},true);
setRequestHeader("Foo", "Bar");
send("");
onreadystatechange = handler;
}
}
function handler(event)
{
!!event.target && !!event.target.readyState && event.target.readyState === 4 && ( console.log(event) );
}
setTimeout(xhr, 500);
setTimeout(xhr, 1000);
I'm trying to create a function that shows a modal dialog which when called blocks until the dialog is closed, this will allow for a result to be returned to the caller
The following function is an attempt which has two problems.
It returns the result while the dialog is still open.
The selector test does not find the dialog, inspecting with firebug reveals that the id element is lost once the dialog is created.
.
function getCountrySelection() {
var ctryCode;
var dlg = $("#JS-field-dlg-ctry-select");
if (dlg.size() === 0) {
dlg = $("<div id='JS-field-dlg-ctry-select' title='Select Country' class='dialog-fields'></div>");
dlg.append("Customer found in both Australia and New Zealand");
dlg.dialog({
autoOpen: false,
width: 400,
height: 160,
modal: true,
buttons: {
"Australia": function() {
ctryCode = "au";
$(this).dialog("close");
},
"New Zealand": function() {
ctryCode = "nz";
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
}
dlg.dialog('open');
return ctryCode;
}
EDIT: I thought I'd show how I'm calling this:
buttons: {
"Find": function() {
var custAu = JS.sales.getCustomer("au", inpCust.val());
var custNz = JS.sales.getCustomer("nz", inpCust.val());
var cust;
if (custAu === undefined && custNz === undefined) {
alert('No customer could be found with that number.');
return;
} else if (custAu !== undefined && custNz !== undefined) {
var ctry;
getCountrySelection(function(result) {
ct = result;
});
if (ctry === "au") {
cust = custAu;
} else if (ctry === "nz") {
cust = custNz;
} else {
return;
}
} else if (custNz === undefined) {
cust = custAu;
} else {
cust = custNz;
}
if (cust) {
$(this).dialog("close");
// Do something with cust.
} else {
alert('Customer could not be found.');
}
},
"Cancel": function() {
$(this).dialog("close");
}
}
There is no way to block execution until the dialog closes; JavaScript does not allow to "suspend" execution. Your best bet is to change the contract of your function; instead of returning the value straight away, it should accept a callback function that it will call with the result as soon as the dialog is dismissed. Then the code calling this will provide a suitable callback in which it can continue its execution.
Something like this:
function getCountrySelection(callback) {
(...)
buttons: {
"Australia": function() {
$(this).dialog("close");
callback("au");
},
"New Zealand": function() {
$(this).dialog("close");
callback("nz");
},
"Cancel": function() {
$(this).dialog("close");
callback();
}
}
});
}
dlg.dialog('open');
}
Then use:
getCountrySelection(function(result) {
if (result) {
...handle result...
} else {
...the user cancelled the dialog...
}
});
This is basically the same thing as with AJAX calls; you can't "suspend" your AJAX call to wait until the AJAX actually completes and returns the result, hence "asynchronous".
EDIT: In your specific example, you could use it like this:
buttons: {
"Find": function() {
var custAu = JS.sales.getCustomer("au", inpCust.val());
var custNz = JS.sales.getCustomer("nz", inpCust.val());
if (custAu === undefined && custNz === undefined) {
alert('No customer could be found with that number.');
return;
} else if (custAu !== undefined && custNz !== undefined) {
getCountrySelection(function(ctry) {
var cust;
if (ctry === "au") {
cust = custAu;
} else if (ctry === "nz") {
cust = custNz;
}
handleCustomer(cust);
});
} else if (custNz === undefined) {
handleCustomer(custAu);
} else {
handleCustomer(custNz);
}
function handleCustomer(cust) {
if (cust) {
$(this).dialog("close");
// Do something with cust.
} else {
alert('Customer could not be found.');
}
}
},
"Cancel": function() {
$(this).dialog("close");
}
}
Here is the js file. The function SubmitCheck is running but when there is a state, I want to do the address check and it doesn't appear to run. What am I doing wrong?
Thanks,
ck in San Diego
var prm = null;
Sys.Application.add_init(Init);
function Init(sender) {
prm = Sys.WebForms.PageRequestManager.getInstance();
WireEvents();
}
function WireEvents() {
var submit = $("#btnSubmit");
submit.click(SubmitCheck);
}
function SubmitCheck(){
var hasState = DoStateCheck();
if (!hasState) {
prm.abortPostBack();
return false;
} else {
var addressCheck = DoAddressCheck();
alert(addressCheck);
}
if (!addressCheck) {
prm.abortPostBack();
return false;
}
}
function DoAddressCheck(){
var add1 = $("#txtAddressMaintLine1");
if (add1.val().length < 1) {
return confirm("No Address was detected.\nClick OK to proceed or Cancel to provide an address.");
}
return;
}
function DoStateCheck() {
var tb = $("#txtState");
if (tb.val().length < 2) {
alert("A state must be provided when establishing a claim.");
tb.focus();
return false;
}
return;
}
Maybe replace
return;
in DoStateCheck() with
return true;
?