I am creating a webapp and I have been using tag in my JSPs to ensure that all my links (both to pages and to resources such as images/css) are always consistent from the root of the application, and not relative to my current location.
Some of the content I am creating using jQuery, for example, I am creating a HTML table by parsing a JSON object and using jquery.append() to insert it in to a div.
My question is, if I want to dynamically create a link using jquery how can I achieve a consistent URL regardless of the page being executed? I have tried just building the html with the tag in it, but no joy.
Thanks!
var baseURL = "/* Server-side JSP code that sets the base URL */";
$("<a />", { href: baseURL+"/my/resource/here.jsp" }); //Your proper link
Or you could do:
var baseURL = "http://"+location.host+"/my/base/url/";
//Which gives you something like http://mySite.com/my/base/url/
Get the root value of your webapp into a string using a jsp tag inside your javascript.
var root = < %=myRootVariable%> //This evaluates to http://www.myapp.com
var dynamicBit = "/foo/bar"
var dynamicLinkUrl = root + dynamicBit
var $newa = $("Hello, world");
$someJQElement.append($newa)
Hopefully none of this will occur in the global namespace. Just sayin'
Related
I have a site http://www.example.com
I serve my static files from a different domain.
eg http://www.eg.com
in my js file which is located at http://www.eg.com/js/myscript.js
I have a variable which is an image.
var myvar = "images/example.gif";
I thought the image link would be http://www.eg.com/images/example.gif but it looks like (when I view the console) it grabs the domain name so it is getting http://www.example.com/images/example.gif
Is this expected behaviour?
Is there a way around this besides hardcoding the variable to be
var myvar = "http://www.eg.com/images/example.gif";
It's not ideal to hardcode as if the domain changes I will then need to update it twice?
It is the expected behavior because it's relative to the current URL.
If you need to use a different domain for your links/images then I would add a var to hold the host name and reference it in your JS file so you only have to change it in one place if you move the file.
So:
var domain = 'http://eg.com/';
var myvar = domain + "images/example.gif";
Or if you don't want to hardcode the domain, you could pull it from the JS source attribute:
HTML:
<script type="text/javascript" id="myjs" src="http://eg.com/myscript.js"></script>
Inside myscript.js:
var myjs = document.getElementById('myjs');
var domain = myjs.getAttribute('src').replace('myscript.js','');
var myvar = domain + "images/example.gif";
You could also just use the base tag in your header but there are some gotcha's.
All relative links are relative with respect to what you see in the address bar of the browser.
The only exception to this are images loaded in CSS (eg background-images), in which case paths are relative to the CSS file.
Edit: Though I haven't used it personally, W3C seems to define the base tag which could work for what you want
I'm trying to dynamically set the thumbnail shown when sharing to Facebook using javascript. I tried adding the meta tag "og:image" to the page (it's a JSP) and that works, but what I want to do now is to replace such image with another one dynamically loaded by javascript.
Basically, the page is calling an API upon loading, using javascript, and retrieves a list of images. I want to use one of those as the thumbnail.
I tried using javascript to replace the content of the meta tag, but Facebook doesn't seem to care abou t it (it does change if I check with my browser).
Is it possible to do this?
Thanks in advance!
Here is a function I used to extract the image url from a flash object tag's flashvars parameter, and then assign it to a meta tag by using jquery:
$(window).load(function(){
//Use $(window).load() instead of $(document).ready(), so that the flash code has loaded and you have all the html you need process with javascript already in place when you start processing.
var stringToExtractFrom = $('param[name="flashvars"]').attr('value');
//Get the flashvars parameter value which we'll use to extract the preview image url from.
var pos = stringToExtractFrom.indexOf("&");
//Search for the position ampersand symbols which surround the image url.
var stringToUse;
//The final string we'll use.
var startOfImageSrc = null;
//The first position where we discover the ampersand
var endOfImageSrc;
//The second position where we discover the ampersand
var lengthToSubstract
//How many symbols to chop off the flashvars value.
while(pos > -1) {
if(startOfImageSrc == null){
startOfImageSrc = pos;
}
else {
endOfImageSrc = pos;
lengthToSubstract = endOfImageSrc - startOfImageSrc;
}
pos = stringToExtractFrom.indexOf("&", pos+1);
}
stringToUse = stringToExtractFrom.substr(startOfImageSrc+7, lengthToSubstract-7);
$('meta[property="og:image"]').attr('content', stringToUse); });
Facebook robot never runs a java script code
but why you don't try to set og tags in in server-side ?
I'm using jquery to rewrite a list of links on the page. If the location.host is NOT the vendor location.host AND the cookie isn't set to a specific value then it locates the links and rewrites them to the alternate values. The code I'm using works great in FF but not in IE7. Please help!
<script type="text/javascript">
// link hider
var hostadd = location.host;
var vendor = '172.29.132.34';
var localaccess = 'internal.na.internal.com';
var unlock = 'http://internal.na.internal.com/Learning/Customer_Care/navigation/newhire.html';
// link rewriter
$(document).ready (
function style_switcher(){
//if not a vendor or not accessing from lms reroute user to lms
if (hostadd != vendor && $.cookie("unlockCookie") != unlock){
var linkData = {
"https://www.somesite.com": "https://internalsite.com/something",'../Compliance/something/index.html':'../somethingelse.html'
};
$("a").each(function() {
var link = this.getAttribute("href"); // use getAttribute to get what was actualy in the page, perhaps not fully qualified
if (linkData[link]) {
this.href = linkData[link];
}
});
}
});
</script>
What you could do, if you insert the links dynamic, is store them in a data attribute like data-orglink="yourlink" which wouldnt be transformed by the browser, then check on that -and if its in the object array - change the href. Do you have access to creating the data attribute?
IE7 have problems with internal links, because it puts the host info on, before JS can reach the link..
http://jsfiddle.net/Cvj8C/9/
Will work in all, but IE7. So you need to use full paths if to use JS for this function :(
You had some errors in your JS.
But it seems to work fine?
See: http://jsfiddle.net/s4XmP/
or am i missing something? :)
How do I get the absolute or site-relative path for an included javascript file.
I know this can be done in PHP, (__file__, I think). Even for an included page, one can check the path (to the included file). Is there any way to have this self awareness in Javascript?
I know I can can get the page URL, but need to get the JS URL.
Eg. Javascript needs to modify the src of an image on the page. I know where the image is relative to the JavaScript file. I don't know where the Javascript is relative to the page.
<body>
<img id="img0" src="">
<script src="js/imgMaker/myscript.js"></script>
</body>
function fixPath(){
$$("#img0")[0].set('src','js/imgMaker/images/main.jpg');
}
Please do not tell me to restructure my function - the example is simplified to explain the need.
In the actual case, a Mootools class is being distributed and people can put it into whatever folder they want.
I would just read the src of the script element, but the class can be part of any number of javascript files, so I can't know what the element looks like.
JavaScript (not JScript) has no concept of file names. It was developed for Netscape back in the days. Therefore there is no __file__ feature or anything similar.
The closest you can come are these two possibilities:
What you already mentioned: Harvest all src attributes of all JS files and try to figure out which one is the right.
Make it a necessary option, that the path to the images must be set in the embedding HTML file. If not set, use a reasonable and well-documented default:
<script type="text/javascript">
var options = {
'path_to_images': '/static/images/' // defaults to '/js/img/'
};
</script>
Based on http://ejohn.org/blog/file-in-javascript/
(function(){
this.__defineGetter__("__FILE__", function() {
return (new Error).stack.split("\n")[2].split("#")[1].split(":").slice(0,-1).join(":");
});
})();
(function(){
this.__defineGetter__("__DIR__", function() {
return __FILE__.substring(0, __FILE__.lastIndexOf('/'));
});
})();
Then later
img.setAttribute('src', __DIR__ + '/' + file);
if you have folders:
/webroot
/images
/scripts
Then images would be an absolute path of /images/whatever.jpg and scripts would be an absolute path of /scripts/js.js
I'm using the following method to get the base URL and using it for loading the other prorotypes, maybe this is what you need. Lets say current script name is 'clone.js'.
/*
* get the base URL using current script
*/
var baseURL = '';
var myName = 'clone.js';
var myPattern = /(^|[\/\\])clone\.js(\?|$)/;
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
var src;
if (src = scripts[i].getAttribute("src")) {
if (src.match(myPattern)) {
baseURL = src.replace(myName, '');
break;
}
}
}
Var baseURL should contain what you need.
The path to the JS is irrelevant; links in the HTML file are always relative to the HTML file, even if you modify them from external JS.
[EDIT] If you need to build a path relative to the current web page, you can find its path in document.location.pathname. This path is relative to the web root but you should be able to find a known subpath and then work from there.
For example, for this page, it pathname would be /posts/1858724. You can look for posts and then build a relative path from there (for example posts/../images/smiley.png)
I know this question was asked awhile back but I have a similar situation to Sam's.
In my case, I have two reasons for the situation:
The user can access different sub-domains, each with its own index page.
The user can enter a password that causes index.php to adjust the paths.
Most of the references point to the same src locations for the scripts, but some do not. For instance, those at a different level of the tree would require a different path.
I addressed it by assigning an id to the index page's script tag. For example, the head might include...
<script id='scriptLocation' type='text/javascript' language='javascript' src='../scripts.test/script.js'></script>
My JavaScript is then able to read the path...
var myPath = document.getElementById("scriptLocation").src;
Found another approach, perhaps someone with more JS ninja can flush this out.
CSS stylesheet are able to find the node that called them using document.stylesheets.ownernode.
I could not find a similar call for javascript files.
But, in some cases, if one can include a CSS file together with the javascript, and give the first rule some unique identifier.
One can loop through all stylesheets till they find the one with the identifier [if(document.stylsheets[i].cssRules[0] == thisIs:myCSS)], than use ownerNode to get the path of that file, and assume the same for the JS.
Convoluted and not very useful, but its another approach - might trigger a better idea by someone.
Any smart way of doing a "root" based path referencing in JavaScript, just the way we have ~/ in ASP.NET?
Have your page generate a tag with something like:
<link rel="home" id="ApplicationRoot" href="http://www.example.com/appRoot/" />
Then, have a function in JavaScript that extracts the value such as:
function getHome(){
return document.getElementById("ApplicationRoot").href;
}
Use base tag:
<head>
<base href="http://www.example.com/myapp/" />
</head>
...
from now any link use on this page, no matter in javascript or html, will be relative to the base tag, which is "http://www.example.com/myapp/".
You could also use the asp.net feature VirtualPathUtility:
<script>
var basePath = '<%=VirtualPathUtility.ToAbsolutePath("~/")%>';
</script>
Notice: I don't encode the path to a JSON-string (escape quotes, control characters etc). I don't think this is a big deal (quotes for example aren't allowed unescaped in an URL), but one never knows...
I usually create a variable at the top of the js file and assign it the root path. Then I use that variable when referencing a file.
var rootPath = "/";
image.src = rootPath + "images/something.png";
~/ is the application root and not a literal root, it interpets ~/ to mean <YourAppVirtualDir>/
To do a literal root in JavaScript it's just /, i.e "/root.html". There's no way of getting an application level path like that in JavaScript.
You could hack it in the ASPX file and output it in a tag but I would consider the security implications of that.
Kamarey's answer can be improved to support a dynamic base path:
<head>
<base href="http://<%= Request.Url.Authority + Request.ApplicationPath%>/" />
</head>
This will ensure a correct root path regardless of deployment configuration.
To be fair, this doesn't answer the original question, but it elimiates most needs for getting the root path from javascript. Simply use relative URL's everywhere, without prefixing with slash.
Should you still need to access it from javascript, add an id attribute and use document.getElementFromId() as MiffTheFox suggested - but on the base-tag.
Another option that's a bit simpler and more universal would be to take the following:
<script src="/assets/js/bootstrap.min.js"><script>
and use Page.ResolveClientUrl like so:
<script src='<%=ResolveClientUrl("~/assets/js/bootstrap.min.js")%>'></script>
then regardless of what subdirectory the urls will always be rendered correctly.
The following function will calculate the root of the currently running application. I use it to locate the absolute location of resources, when called from somewhere deep within the application tree.
function AppRoot() {
//
// Returns the root of the currently running ASP application.
// in the form: "http://localhost/TRMS40/"
//
// origin: "http://localhost"
// pathname: "/TRMS40/Test/Test%20EMA.aspx"
//
// usage:
// window.open( AppRoot() + "CertPlan_Editor.aspx?ID=" + ID);
//
var z = window.location.pathname.split('/');
return window.location.origin + "/" + z[1] + "/";
}
In the PreRender of your .NET base page, add this:
protected override void
OnPreRender(EventArgs e) {
base.OnPreRender(e);
if (Page.Header != null)
{
//USED TO RESOLVE URL IN JAVASCRIPT
string baseUrl = String.Format("var baseUrl='{0}';\n",
HttpContext.Current.Request.ApplicationPath);
Page.Header.Controls.Add(new LiteralControl(String.Format(Consts.JS_TAG,
baseUrl)));
}
}
Then in your global JavaScript function, add the following:
function resolveUrl(url) {
if (url.indexOf("~/") == 0) {
url = baseUrl + url.substring(2);
}
return url; }
Now you can use it like this:
document.getElementById('someimage').src = resolveUrl('~/images/protest.jpg');
May be a little much for some projects, but works great for full fledged applications.
Solution for ASP.NET MVC applications
This works when using IIS and also IIS Express in VS.
Put this snippet before all scripts load, in order to have the root url variable "approot".
at your service in the scripts:
<script>
var approot = "#Url.Content("~")";
</script>
--> other scripts go here or somewhere later in the page.
Then use it in your script or page script.
Example:
var sound_root_path = approot + "sound/";
var img_root_path = approot + "img/";
the approot variable will be something either:
"/YourWebsiteName/" <-- IIS
or just:
"/" <-- IIS Express
For ASP.net MVC Razor pages, Create a base tag like below in the <Head> tag
<base href="http://#Request.Url.Authority#Request.ApplicationPath" />
and in all your relative javascript URLs, make sure to start without a slash(/) otherwise it will refer from the root.
For ex. create all your urls like
"riskInfo": { url: "Content/images/RiskInfo.png", id: "RI" },
or
$http.POST("Account/GetModelList", this, request, this.bindModelList);
If you want to use it in HTML Still you can use ~, see this
href = #Url.Content("~/controllername/actionName")
See the check box click event in my MVC Application
#Html.CheckBoxFor(m=>Model.IsChecked,
new {#onclick=#Url.Content("~/controller/action("+ #Model.Id + ", 1)"),
#title="Select To Renew" })