How do i get the relative path with JQuery? - javascript

I recognize that this has been asked before but I have yet to find an answer that is working for me. I'm basically following a solution for keeping an ASP session alive I found at dotnetcurry by Malcom Sheridan.
I have the following JQuery defined on the masterpage of an asp.net site. As the default page is on the same level, it has no problems making the serverside call every 7 seconds; however, when I navigate to another page, deeper in the file structure, the ajax post starts to fail.
var interval;
$(function () {
setheartbeat();
});
function setheartbeat() {
interval = setInterval("heartbeat()", 7000);
}
function heartbeat() {
$.post("./SessionHeartbeat.ashx", null, function (data) {
})
.done(function () {
alert('done');
})
.fail(function () {
clearInterval(interval);
alert('Failed to keep session alive. Please close the browser and log back in.');
});
}
Besides the sample from above, I've already tried, with none of them working:
$.post("/SessionHeartbeat.ashx", null, function(data) {...}
$.post(window.location.pathname + "/SessionHeartbeat.ashx", null, function(data) {...}
$.post(vpath + "/SessionHeartbeat.ashx", null, function(data) {...} where vpath = "<%=ApplicationVirtualPath %>"; after I've included the System.Web.Hosting.HostingEnvironment namespace
Anyone have any thoughts?
Thank you

Related

javascript update modal form element whilst the ui is blocked due to code execution

ok, I have seen many, many articles about this. But so far I have not got any to work. So this is my take on the issue.
I have a list of employee names with ids held in a select option, and a button that when clicked, calls a routine for each option in the select
$(document).on("click", ".js-button-update-all-drivers", function (e) {
e.preventDefault();
myApplication.busy(true);
$("#modalInfo-body span").text("Starting update ...........");
$('.modalInfo-header .title').text("Information");
var modal = document.getElementById('modalInfo');
myApplication.openModal(modal);
var selected = document.getElementsByClassName('js-dropdown-selector');
for (var i = 0; i < selected[0].options.length; i++) {
var Id = selected[0].options[i].value;
$("#modalInfo-body span").text("Updating - " + Id);
doWork(Id);
}
myApplication.closeModal(modal);
myApplication.busy(false);
});
This calls a function call doWork which is defined as async/wait
async function doWork(employeeId, taxWeek, taxYear) {
try {
const response = await processUpdate(Id);
} catch (err) {
$("#modalInfo-body span").text("Report Error - Thank you.");
}
}
Which in turn calls the following function:
function processUpdate(Id) {
return new Promise((resolve, reject) => {
$.ajax({
url: '/myTest',
async: false,
data: {
Id: Id
},
method: 'post',
dataType: 'json',
success: function(retData) {
if (retData === false) {
resolve('Completed');
} else {
reject('An error has occurred, please send a screen shot');
}
},
error: function(xhr, error) {
reject('An error has occurred, please send a screen shot'); }
});
});
}
Although this code works, the element $("#modalInfo-body span") is not updated as it loops around the doWork function.
I already have a spinner on the screen, but am looking for a more visual aid to how this is progressing.
OK, I am going to start this by saying that I knew the browser is single threaded, and this was not going to be easy.
I did try callbacks and that did not work completely, as I encountered a delay in updating the screen.
So ultimately, I replaced this with a simple spinner.
Thanks to all that took the timer to look at this.

angularjs: open a page then only loading data

My current ionic code able to get data then open the page. However, I want to open the page then only loading to get the data. I want to change the sequence since it takes 10s to load some data.
Here is my code:
$scope.openDetail = function (stock) {
console.log(stock.symbol);
$ionicLoading.show();
//stockCondition
if(stock.symbol.length<=$scope.stockCondition) {
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = data.news;
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
}
else{//WarrentCondition
$stockDataFactory.getWarrentDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = {};
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert("Stocks Not Found.");
console.error(error);
$ionicLoading.hide();
}
);
}
};//end
In order to open the $state.go("app.page1"); first, then only loading data, how shall I made changes of my code?
You should show the page1's html templet .
My approach will be using ng-if="personalStockData" with the $setTimeout() trick to show the data only when it's loaded. looks something like this
//page1 controller
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$setTimeout(function(){
$scope.personalStockData = data.details;
$scope.personalStockNews = data.news;
})
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
html
<div>
...
<div ng-if="personalStockData">
</div>
<div ng-if="personalStockNews">
</div>
...
</div>
anyways try not to use global variables, those are really hard to track.
You'll have to bring over the decision data that are explicit to the current page over to app.page1. For instance $scope.stockCondition. I suspect it is the same forstock.symbol. Will have to see what stock variable is.
There are many ways you can achieve this. Using query string is one option and is also the most conventional way. Some people prefer to store them in cookies, not efficient but applies to certain use-cases.
Again, I am not sure what $state is. Assuming it is angular-ui-router's statemanager. Then you can achieve this by;
$state.go("app.page1", {
stockCondition: $scope.stockCondition,
stocksymLen: stock.symbol.length
});
Then on app.page controller you can retrieve the values of the query string parameters by doing $state.params.stockCondition.
Once you have brought the decision variables across to the next page. The next step would be to plug them into the if-else statement you got from the other page onto app.page1.
Pseudo code:
angular.module('blah')
.controller('app.page1', function($scope, $state) {
// on page load
if($state.params.stocksymLen <= $state.params.stockCondition) {
// do your REST call
...
else {
...
}
});

How can I put javascript variable into Url.Action

I have a post that work well when I run from VS2015 debug:
$("#DisplayChartType").bind("change", function () {
$.post("../Employee/ChangeDisplayChartType", { displayChartType: $("#DisplayChartType").val() }, function (data) {
iDependOnMyParameter(data);
})
});
But post does not work once I have published to IIS. I tried using ../, / and ~/ in the post but none work. I searched web and found the approach below but I still get ARG1 being sent as a parameter instead of my javascript variable.
$("#DisplayChartType").bind("change", function () {
$.post("#Html.Action("ChangeDisplayChartType", "Employee", new { displayChartType = "ARG1" })".replace("ARG1",$("#DisplayChartType").val()) , function (data) {
iDependOnMyParameter(data);
})
});
How should I do this? I really would like to stay with $.post approach as that works nicely in VS.
You can try this code.
$("#DisplayChartType").bind("change", function () {
var chartType = $("#DisplayChartType").val();
var url="#Url.Action("ChangeDisplayChartType", "Employee", new { displayChartType = "ARG1" })";
$.post(url.replace("ARG1", chartType), function (data) {
iDependOnMyParameter(data);
})
});
So add it to the url
$.post("../Employee/ChangeDisplayChartType?displayChartType=" + encodeURIComponent($("#DisplayChartType").val()), function(){});
or change your original code to GET and the value will be added to the querystring.
You can use window.location.origin or document.location.origin to get the origin of your website, whether running in VS 2015 debug or on IIS.
So instead of doing
$.post("../Employee/ChangeDisplayChartType"
You can try
$.post(document.location.origin + "/Employee/ChangeDisplayChartType"
#OJ Raqueno put me on the right path.
At top of script I now declare "myPath". My website URL ends with "secure" so this test gives me the right path:
var myPath = document.URL;
if (!myPath.endsWith("secure")) {
myPath = "";
}
Then I do this:
$("#DisplayChartType").bind("change", function () {
$.post(myPath + "/Employee/ChangeDisplayChartType", { displayChartType: $("#DisplayChartType").val() }, function (data) {
alert($("#DisplayChartType").val());
iDependOnMyParameter(data);
})
});

NightwatchJS .waitForElementPresent abortOnFailure not working

I'm using NightwatchJS with NodeJS: http://nightwatchjs.org/api
I have a modal dialog, which may or may not appear. It has a #close_button that needs to be clicked (if the modal does appear) to continue.
I set the abortOnFailure parameter of waitForElementPresent to false so the script continues if the modal does not appear. However I can't get it to work.
Any suggestions?
module.exports = {
"Test" : function (browser) {
browser
.url("http://domain.com/")
.waitForElementPresent('#close_button', 5000, false, function() {
this.click('#close_button')
})
.setValue('#username', 'test#email.com')
//more code here
.end(); //does end() go here or inside .waitForElementPresent() above?
}
}
abortOnFailure works fine, however waitForElementPresent has a bug now in which the callback you passed it's not called in the correct context. That will be fixed.
In the mean time you can write your test like this, with placing the click outside, which is the same thing and looks cleaner:
module.exports = {
"Test" : function (browser) {
browser
.url("http://domain.com/")
.waitForElementPresent('#close_button', 5000, false)
.click('#close_button')
.setValue('#username', 'test#email.com')
//more code here
.end(); // end() goes here
}
}
I ran into something similar, I was waiting for an iframe to be present. I created a function to actually close it:
pageObject function:
Home.prototype.closeIframe = function(browser) {
var self = this;
console.log('Checking for iframe');
this.browser
.isVisible(iframeSelectors.iframe, function(result) {
if (result.value === true) {
self.browser
.log('iframe visible')
.frame(iframeSelectors.name)
.waitForElementVisible(iframeSelectors.closeLink)
.click(iframeSelectors.closeLink)
.assert.elementNotPresent(iframeSelectors.iframe)
.frame(null)
.pause(2000); //allow for proper frame switching
} else {
console.log('iframe is not visible');
}
});
return this;
In my test I wait for the page to fully load before executing the above function.

Function scope within IF Statement

hoping some one can shed some light on my problem. Basicly I only want to execute a block of code if a certain DOM element exists. If it does I then perform a few bits and bobs and then call a function. However it complains that the function is not defined, suggesting that the function is not in scope. Below is the code :
$(document).ready(function ()
{
if ((document.getElementById("view<portlet:namespace/>:editSplash")!= null)) {
console.log("notifications scripted started");
// hide loading box/ notify on body load
$('.ajaxErrorBox').hide();
$('.loadingNotifications').hide();
$('.notifyWindow').hide();
getFeed();
// set up refresh button for reloading feed
$('.refreshFeed').click(function() {
$('.notifyWindow').hide();
$('.notifyWindow').empty();
console.log("notifications clicked");
getFeed();
});
// begin ajax call using jquery ajax object
function getFeed ()
{
$('.notifyWindow').empty();
console.log("ajax call for feed starting");
$.ajax ({
type: "GET",
url: "http://cw-pdevprt-05.tm-gnet.com:10040/notificationsweb/feed?username=uid=<%# taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %><wps:user attribute="uid"/>",
dataType: "text/xml",
timeout: 10000,
success: parseXml
});
};
// show loading box on start of ajax call
$('.notifyWindow').ajaxStart(function() {
$('.refreshFeed').hide("fast");
$('.notifyWindow').hide();
$('.ajaxErrorBox').hide();
$('.loadingNotifications').show("fast");
});
// hide loading box after ajax call has stopped
$('.notifyWindow').ajaxStop(function() {
$('.loadingNotifications').hide("slow");
$('.refreshFeed').show("fast");
});
$('.notifyWindow').ajaxError(function() {
$('.loadingNotifications').hide("slow");
$('.ajaxErrorBox').show("fast");
$('.refreshFeed').show("fast");
});
// parse the feed/ xml file and append results to notifications div
function parseXml (xml) {
console.log("xml parsing begining");
if (jQuery.browser.msie)
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
$(xml).find("entry").each(function()
{
var $item = $(this);
var title = $item.find("title").text();
var linkN = $item.find("link").attr("href");
var output = "<a href='" + linkN + "' target='_self'>" + title + "</a><br />";
$(".notifyWindow").append($(output)).show();
});
}
}
else {
console.log("notifications not available");
return false;
}
});
If the DOM element exists I then try and call the getFeed function "getFeed();" however it comes back undefined. If anyone could shed some light on this it would be greatly appreciated.
Thanks in advance
It seems that you're calling getFeed before it is defined. Try moving the if statement to after the function definition. Note that this behaviour is actually implementation specific, so some browsers may work this way and some may not.
Oh - And seriously? view<portlet:namespace/>:editSplash for an id?
Problem solved - I moved my functions outside of the if statement. We live and learn lol :-)

Categories