We have a platform developed with AngularJS. The platform is the same for all our customers.
We must include Adobe DTM only for a client.
I sometimes have external scripts that aren't loaded.
Do you have a better way to do it?
var adobedtm = '//assets.adobedtm.com/5249...abe2e5/satelliteLib-2d8560...eb5937-staging.js';
if( window._env.environment === 'production' ){
adobedtm = "//assets.adobedtm.com/5249...abe2e5/satelliteLib-2d8560...eb5937.js"
}
$.getScript('//cdnjs.cloudflare.com/ajax/libs/postscribe/2.0.8/postscribe.min.js', function (data, textStatus, jqxhr){
postscribe(document.body, '<script src="' + adobedtm + '" type="text/javascript"><script type="text/javascript">_satellite.setDebug(true);</script><script type="text/javascript">_satellite.pageBottom();</script>');
});
I believe there is no better way other than embedding DTM library in the header section of your HTML file. the external scripts are added using document.write() which only work while the page is loading.
Reference: http://javascript.info/modifying-document#a-word-about-document-write
Related
I have a page1 which has a wrapper with articles.
<div id="wrapper">
<article>...</article>
<article>...</article>
<article>...</article>
<article>...</article>
</div>
I am loading new articles from page2 with Ajax and appending them to the wrapper
$.ajax({
url : page_to_load,
success : function (data) {
$('article',data).appendTo('#wrapper');
}
});
But some of this new articles might need specific scripts that were not loaded in page1 but would be loaded if accessed directly page2.
So the problem is some of the content in new articles breaks as they are missing those scripts.
What is the best solution? I can think of checking the new loaded page scripts and compare them with the already loaded and download the new ones, but I have no idea of how to do this.
EDIT
I noticed if I set the dataType to 'html' I cant search for the scripts, although they are there:
$('script',data)//doesn't match anything
But if I do:
console.log(data);
I can see the whole page with <html> and <script> tags
There is no problem actually, if you append HTML to the Dom then script calls will be interpreted as if the page was loaded directly, just make sure you use the same parameters as the shorthand jquery $.POST method.
I actually do this all the time and the <script src=""> are called and interpreted correctly
Just make sure you're accessing the scripts from the right scope as if the html was hardcoded on page1.
If this doesn't work, then check with the web inspector if the scripts are loaded or not.
Working solution:
$.ajax({
url : page_to_load,
success : function (data) {
// load the scripts
var dom = $(data);
dom.filter('script').each(function(){
var scriptSrc = $(this).attr('src');
if(!$('script[src="'+ scriptSrc +'"]').length && scriptSrc !== undefined) {
var script = $("<script/>");
script.attr('src', scriptSrc);
$("head").append(script);
}
});
// load the articles
$('article',data).appendTo('#wrapper');
}
});
Not sure but maybe you could add a script in the AJAX call - I'm not sure of this because I haven't tried it:
Proxy.Scripts.Add(new ScriptReference(AddVersion("/Pages/Items/SearchList/SearchList.Grid.js" )));
This workflow should work :
After every page request :
Get all the script tags in the loaded page.
Loop over the scripts
If it's not loaded yet , load it.
Here is the code snippet :
$.ajax({
url : 'http://localhost',
success : function (data) {
$('article',data).appendTo('#wrapper');
$.each($.parseHTML(data,null,true),function(){
if($(this)[0].tagName == "SCRIPT"){
var src = $(this).attr('src');
if($('script[src="'+ src +'"]').length){
$.getScript(src);
}
});
}
});
Disable async.
$.ajax({
url : page_to_load,
async: false,
success : function (data) {
$('article',data).appendTo('#wrapper');
}
});
you can use RequireJS or HeadJs library for calling js files.
RequireJS is a JavaScript file and module loader and HeadJS, a small library for Responsive Design, Feature Detections & Resource Loading
HeadJs is great and useful, try it.
I was trying to read an info.json file, using the jQuery API. Please find the code below, which is part of test.html.
$.getJSON('info.json', function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
The test.html file resides on my local machine and when I try to open it in the browser, the Ajax call is not getting triggered and the info.json file is not read.
Is it not working because I don't have a web server? Or am I doing anything wrong in the code? (I don't see any errors in the Firebug console though).
Thanks in advance.
You will always have to host your site from where you are making AJAX call. Otherwise it will throw this exception.
origin null is not allowed by access-control-allow-origin
Host your page on localhost server and I guess everything will work nicely.
While technically you don't need a web server for this, some of the libraries you use to abstract network access may not work with local files and some browsers don't let local files do a lot, so something like a little test web server for static files would be very useful for your development and testing.
Install a small webserver like http://jetty.codehaus.org/jetty/
easy to install, and small download ;)
By putting your JSON string into a text file and loading it in a iframe, you can extrapolate the data. (Most browsers can load .txt files in iframes.)
var frame = document.createElement("IFRAME"); //Create new iframe
var body = document.body;
frame.onload = function() { //Extrapolate JSON once loaded
data = JSON.parse(frame.contentDocument.documentElement.innerText); //Loads as a global.
body.removeChild(frame); //Removes the frame once no longer necessary.
}
frame.style.display = "none"; //Because the frame will have to be appended to the body.
body.appendChild(frame);
frame.src = "your JSON.txt"; //Select source after the onload function is set.
I am trying to solve a small issue. I have built an entire web ASP.NET application using mostly client side (JQuery/JavaScript) code. I use generic handlers to do some lazy loading of data, as well as for auto-completes and the likes.
One of the requirements is that one page needs to be able to upload a file, as well as display meta information about the uploadead files.
I as wondering if there is a way to upload a file entirely out of JQuery/JavaScript. I researched a whole ot of plugins but they all rely on having a php backend.
My thought was to create a post:
$(function(){
$('#submit').live('click', function(event){
$.post('/SomeOtherHandler.ashx', //can be '/someotherpage.aspx'
{
filename: $('#fileUpload').val(),
timestamp: (new Date()).toString()
}, function(data){
//do something if the post is successful.
});
});
});
Would that work? I know that if you include the json object { filename: value, timestamp: value } it will show up in the HttpContext.Request.Params collection where I can read it without problems.
The problem is however that I don't know how this will work since the FileUpload html control only stores the file name in its value. Therefore I would be sending a string to my server with the filename, not an array of bytes.
Any thoughts on this would be greatly appreciated!
I'm using the uploadify plugin (http://www.uploadify.com/) - as Jeremy said, it's not in javascript - It's not possible. It's in flash. It's very easy to install.
$('#file_upload').uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '/uploadify/uploadify.ashx',
'cancelImg' : '/uploadify/cancel.png',
'folder' : '/uploads',
'auto' : true,
'fileExt': '*.xls;*.xlsx;*.csv',
'buttonText': 'Select your file',
'onError' : function (event,ID,fileObj,errorObj) {
alert(errorObj.type + ' Error: ' + errorObj.info);
},
'onComplete' : function(event, ID, fileObj, response, data)
{
var obj = jQuery.parseJSON(response);
if (obj.error != "" & obj.errror != null)
{
lblTable.html("error : " + obj.error);
}
else
{
lblTable.html(obj.table);
lblEditData.show();
lblTable.hide();
}
}
});
And on the uploadify.ashx :
public class uploadify : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
System.Web.HttpPostedFile file = context.Request.Files["Filedata"];
//Check extension
string extension = "";
try
{
extension = file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
if (extension != "xls" & extension != "xlsx" & extension != "csv") throw new Exception("Error of the extension");
}
catch
{
context.Response.Write("{\"error\",\"Error with the extension of the file\"");
}
string linkFile = System.Web.HttpContext.Current.Server.MapPath("~") + "uploads" + "\\" + DateTime.Now.ToString("yyMMddHHmm") + APIReportPro.DocumentPDF.RandomString(4) + "." + extension;
file.SaveAs(linkFile);
...etc...
This is the nicest solution I found for asp.net
You have what boils down to three options when you are uploading files to a server. You can use native html file-upload features, Flash or Java. Javascript cannot upload a file to a server, it can only decorate the built in html functionality. With that said I can only assume you are attempting to mimic ajax like uploading functionality. If that is so there is a way to upload files using an iframe which will look like you are using ajax.
You will be creating a form
<form id="file_upload_form" method="post" enctype="multipart/form-data" action="upload.aspx">
<input name="file" id="file" size="27" type="file" /><br />
<input type="submit" name="action" value="Upload" /><br />
<iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe>
</form>
This form uses the iframe to post the file, which will cause the main page to never refresh. You can hook up your jquery to process the response the iframe returns and handle user information.
If this is not the part of the equation you were looking for please feel free to comment and clarify what it is you are looking to accomplish.
If you can dictate which browsers your app is accessed through (e.g. it's an internal business app), it's worth checking out the new File API which is part of the "HTML5" stack of technologies that are beginning to show up in the latest browsers. This gives you direct access to files via clientside Javascript without the need to post the file to the server first.
If your app is public-facing then you can still use the File API, but you will need to check for support for it in your code and apply some kind of fallback mechanism (such as Uploadify) for those with older browsers.
You can read more about the File API here and here amongst other places.
I'm pretty sure it's not possible; if it is then it's a big security hole - Javascript should not be able to get bytes from the user's hard drive.
So you're stuck using the native input type=file or using pre-existing desktop bytes, like Flash. Several popular uploaders use this method...my favorite is Uploadify. Take a look at that, and see if that doesn't suit your needs.
HTH.
I have implemented an ASP.NET Handler for uploading file using Valums ajax Upload control. You can check solution here. You can also upload large file. This handler supports IE, FF and Chrome browser. You can also drag drop multiple files from FF and Chrome (HTML 5)
http://ciintelligence.blogspot.com/2011/05/aspnet-server-side-handler-for-valums.html
Using jquery you can do something like:
<input type="file" name="file" id="file1" runat="server" />
$("#<%=file1.ClientID%>").change(function () {
//Do stuff
$(this).upload('youHandler.ashx', function (res) {
//do stuff on success
}
}
Now on yourHandler.ashx you can do something like that:
public void ProcessRequest(HttpContext context)
{
if (context.Request.Files.Count > 0)
{
var fileCount = context.Request.Files.Count;
var fileStram = var file = context.Request.Files[0].InputStream;
//Do whatever you want
}
}
$.ajax({ url: "plugin.js", dataType: 'script', cache: true, success: function() {
alert('loaded');
}});
1) I can't get the script to load, probably due to incorrect path, but how do I determine the correct path? The above code is in init.js, plugin.js is also in the same folder.
2) Can I load multiple plugins at once with the same request? eg. plugin.js, anotherplugin.js?
root
|
|_ html > page.html
|
|_ static > js > init.js, plugin.js
Thanks for your help
You need to use getScript, not ajax. Ajax is for loading data, not for executing code.
If you need to load multiple files, try something like this:
var scripts = ['plugin.js', 'test.js'];
for(var i = 0; i < scripts.length; i++) {
$.getScript(scripts[i], function() {
alert('script loaded');
});
}
1) The path will be relative to the page it's loaded from (not the path of your init script) since that's the url the browser will be at when it executes the ajax request.
Edit: Based on your edit, the path to load your script from is either /static/js/plugin.js (if it'll be deployed at the root of your domain), or ../static/js/plugin.js to be safe (assuming all pages that it'll be loaded from will be in /html).
2) No. If they're in different files, they'll need to be different requests. You could merge them into one file on the server-side though...
As an update, the better way to do this with jQuery 1.9.x is to use Deferreds-methods (i.e. $.when), such as follows:
$.when(
$.getScript('url/lib.js'),
$.getScript('url/lib2.js')
).done(function() {
console.log('done');
})
The .done() callback function has a number of useful params.
Read the documentation: http://api.jquery.com/jQuery.when/
Check out the jQuery .getScript function, which will load the script and include it in the current document.
1) The path should be /static/js/plugin.js, relative to your document.
2) No. Each file is loaded by a single HTTP request.
I would check Firebug's net tab to see if it was loaded correctly, and the path it is trying to load from.
The path will be from the document where the JavaScript was included.
I also keep a config object like this (PHP in this example)
var config = { basePath: '<?php echo BASE_PATH; ?>' };
Then you could do
var request = config.basePath + 'path/to/whatever.js';
You can use '../' to set the script path as base path. Then add the relative path for the
$.getScript("../plugin.js").done(function(script, textStatus ) {
alert("loaded:" + textStatus);
}).fail(function(script, textStatus ) {
alert("failed: " + textStatus);
});
is there anyway to load other JS files from within a single JS file. I would like to point my individual pages "ITS" js file and that js file would load jquery, other js files.
I know i can just pop all these into the html i.e.
I was thinking of separations of concerns so i was wondering if anything exists already without me reinventing the wheel....
That i would just need to edit home.js to change what other js (jquery etc) are loaded for home.htm ... home.htm would just point to home.js
Thanks
You can take a look at dynamic script loading. Here's an excerpt from the article:
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'helper.js';
head.appendChild(script);
For external domain JS link
var loadJs = function(jsPath) {
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', jsPath);
document.getElementsByTagName('head')[0].appendChild(s);
};
loadJs('http://other.com/other.js');
For same domain JS link (Using jQuery)
var getScript = function(jsPath, callback) {
$.ajax({
dataType:'script',
async:false,
cache:true,
url:jsPath,
success:function(response) {
if (callback && typeof callback == 'function') callback();
}
});
};
getScript('js/other.js', function() { functionFromOther(); });
This is similar to Darin's solution, except it doesn't make any variables.
document.getElementsByTagName('head')[0].appendChild(document.createElement("script")).src = "helper.js";
I'd suggest you take a look at labJS. It's a library made specifically to load Javascript. As they say..."The core purpose of LABjs is to be an all-purpose, on-demand JavaScript loader, capable of loading any JavaScript resource, from any location, into any page, at any time."
See the labJS home page for more information.
Google offers centrally hosted versions of the major javascript libraries like jQuery. They can be dynamically loaded using the google loader.
http://code.google.com/apis/ajaxlibs/documentation/