Can I inject google AJAX API autoload anywhere else than globally? - javascript

There is this issue I am struggling with. I know that the autoload for the google visualization geomap must be in the part of your document.
The thing is every time I reload some other pages in my application the google reloads everything and this I want to take out. So I tried taking the :
<script type="text/javascript" src="http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22geomap%22%2C%22table%22%5D%7D%5D%7D"></script>
out of my global template and inject it when the page call happens. So to only load the google API when I need it so to keep loading times to an absolute low. I want to know if this is do-able and if the google autoload MUST exist in the global at all times.
I am using Prototype Javascript framework and here is my code to inject the autoload :
var element = new Element('script', {
src: "http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22geomap%22%2C%22table%22%5D%7D%5D%7D",
type: 'text/javascript'
});
$$('head')[0].appendChild(element);
This keeps it out of the rest of the site but doesn't work at all. Am I thinking about this wrong or is there some possibility of me only loading the API in one place and not everywhere.
Thank you

It seems like if you do it in the template of the view you are using it works fine. Every time the template gets rendered it refreshes the page resulting in the Google API code loading.

Related

Loading Google visualization API before/during page load

I am in a scenario where I need to display a google chart that is presentable and ready to display "before" the entire page loads. I've tried loading modules using the "ignoreWindowOnLoad" property, messing with different async call methodologies, and different versions of the API. I've also tried loading the scripts the following ways:
<script type="text/javascript" src='https://www.google.com/jsapi?autoload={"modules":[{"name":"visualization","version":"current","packages":["gauge"],"ignoreWindowOnLoad":true}]}'></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
google.load("visualization", "current", { packages: ["corechart"], ignoreWindowOnLoad: true});
The issue is that by the time the page loads and I try to draw the chart immediately after load, I get an exception:
Uncaught TypeError: Cannot read properties of undefined (reading 'arrayToDataTable')
at drawChart
I am using ASP.NET (not Core) as the backend, and using an SSR technology such as node.js isn't a viable option in my scenario, but if I can achieve SSR without a framework (if it's not an overkill solution) that may be acceptable. The chart loads fine if I call drawChart after the page fully loads.
Basically I'm looking for a way to ensure all visualization-related APIs are fully loaded before the page presents itself, so a single web request can pull the entire page and its contents, charts included. Any advice on how to achieve this would be greatly appreciated.

Force browser to refresh javascript code while developing an MVC View?

Pretty straight-forward, I'm developing an MVC5 application and have noticed (lately) that my Browser appears to be caching the JavaScript code I have on the view within #section Scripts { }.
Currently I am developing with Chrome and I have tried CTRL+F5 & CTRL+SHFT+R which reloads the page, but the alert() I uncommented within the javascript code is still rendering as commented. I also tried going to my localhost through Incognito Mode as well as other Browsers (Firefox, IE) and am getting the same behavior. This is my /Home/Index.cshtml View, which is the default View which loads when the application starts. I have also tried adding some extra HTML text into the page and again the new code is not taking effect/showing.
My current Chrome version is Version 41.0.2272.118 m if anyone has any ideas what might be going on?
UPDATE:
I have gone under the Developer Tools => General Settings in Chrome and checked [X] Disable cache (while DevTools is open) and then repeatedly (with DevTools still open) tried CTRL+SHFT+R and CTRL+F5 with the same results of before where my changes are not taking effect.
UPDATE 2:
With DevTools open I have also held the Refresh button down and tried Normal/Hard/and Empty Cache & Hard Reload options all with the same result. For simplicity of testing I added an alert in the below to dispaly as soon as the page loads (and currently no alert comes up):
$(document).ready(function () {
alert("Test");
// Other Code/Functions -- No Error showing in Console
});
If you are using Bundling from MVC, you have two options to disable caching:
Use BundleTable.EnableOptimizations. This instructs the bundling to minify and optimize your bundle even while debugging. It generates a hash in the process, based on the content of the script, so your customers browsers can cache this file for a long time. It will generate a whole different hash the next time your file changes, so your customers can see your changes. The downside is that your script will become unreadable and you won't be able to debug it, so this might not be your best option.
Use System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("url", true) to resolve your script's URL, the second parameter (true) is requiring a hash to be generated with the URL, thus, preventing caching from your browser when you change the file. This is exactly the same hash generated in the first option, but without minifying.
I created a small demo showing that the second option prevents caching from happening, the trick is getting the hash generated from your script's content without minifying your script.
I created a script file called myscript.js with this content:
$(document).ready(function () {
alert('a');
});
Then I added this to my BundleConfig.cs:
// PLEASE NOTE this is **NOT** a ScriptBundle
bundles.Add(new Bundle("~/bundles/myscripts").Include(
"~/Scripts/myscript*"));
If you add a ScriptBundle, you will get a minified response again, since ScriptBundle is just a Bundle using JsMinify transformation (source). That's why we just use Bundle.
Now you can just add your script using this method to resolve the script URL with the hash appendend. You can use the Script.Render
#Scripts.Render(System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/myscripts", true))
Or the script tag:
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/myscripts", true)"></script>
Either way will generate a URL with a hash to prevent caching:
After editing my file:
You might want to add a no_cache variable after your script url like:
<script src="js/stg/Stg.js?nocache=#random_number"></script>
If you manage to put a random number to the place i indicated, the browser will automatically download the latest version of the script after an F5
A quick trick that solves this problem consists of opening the script file in a new tab, then refresh it on this page.
If you happen to have Chrome dev tools open it will even refresh it there.
From dev tool you can even easily right click-open in new tab the script.

Get URL in javascript without file extension

In Google Analytics I'm tracking goals with virtual page views. I take
trackingURL = window.location.pathname+'thankyou.php';
and then
_gaq.push(['_trackPageview',trackingURL]);
The issue is when a page is something like www.domain.com/page.php it ends up being domain.com/page.phpthankyou.php and not tracking properly, but if it was domain.com/page/ and then it became domain.com/page/thankyou.php it would track properly.
How can I get the full url, without the extension, so I can add on /thankyou.php, but if it is already a directory with the / at the end, then I just want to add thankyou.php to it?
Thanks!
Use this (which only replaces the extension with a slash if it finds it):
trackingURL = window.location.pathname.replace(".php","/") +'thankyou.php';
Which replaces domain.com/page.php with domain.com/page/

Add Script Reference (JavaScript) to Script Manager on Microsoft AJAX Partial Postback

I am trying to add a script reference to the script manager in the event of a Microsoft AJAX Partial Postback, ie a user clicks on a link in an Update Panel.
ScriptManager.RegisterClientScriptInclude(Page, Page.GetType(), "UniqueName",
Page.ResolveUrl(scriptPath));
Doesn't work and either does
ScriptReference script = new ScriptReference(scriptPath);
MyScriptManager.Scripts.Add(script);
From what I have read on the net, RegisterClientScriptInclude should work even in a partial postback.
http://www.codeproject.com/KB/ajax/addingCssJsAjaxPartialPos.aspx
Can anyone give any ideas why these don't work, or another way to do it?
EDIT: Additional information.
I am working with a very large legacy code base that has the forms and script manager in each page rather than in the master page. I would like to place the code into a class and use the following call to add the javascript effect.
ClientSideScripts.BackgroundColourFade(Page, ScriptManager, Control);
The reasons I want to include the script in the method call is
Consumes of the method don't have to remember to include the script
Changing the script used only requires a change in one place
Only include the javascript when needed to keep the load time of the page down
Have a look at this SO-Question because it answers your question:
ScriptManager.RegisterClientScriptInclude does not work in UpdatePanel
function dynamic() {
alert('dynamic');
$('#divDyn').text('Dynamic!');
}
// notify that the script has been loaded <-- new!
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Lazyloading Google API not working

Here's the deal. I've tried a number of methods of lazy loading the Google Maps API JavaScript, and every time in do it, with any Lazy Loader I use, FireFox "blocks." It lazy loads just fine in Chrome.
What I mean by "blocks" is that the elements in the HTML don't display, and instead, the browsers spin trying to make a connection to download the Maps JavaScript.
The code follows. Put it in an HTML file and open it in your browser:
<html>
<head>
<script type="text/javascript" src="http://github.com/rgrove/lazyload/raw/master/lazyload.js"></script>
</head>
<body>
Open your console. Wait for "entering debugger..." message.<br />
You can't see me in FireFox, can you?
<script type="text/javascript">
// If I remove the `sensor` from the query string key and value,
// Google rejects the request and alert() does occur
LazyLoad.js("http://maps.google.com/maps/api/js?sensor=false", function() {
console.log("entering debugger...");
});
</script>
</body>
</html>
In Chrome, I see the "Open your console..." contents of the page, and the JavaScript is requested and downloaded, async, in the background.
In FireFox, the "Open your console..." contents never appear, and it hangs (status bar says "Read" from a Google DNS), never finishing or displaying the page contents.
Are you sure you need to write your own loader? What about using a previously tested implementation: Lazy Load
Are you trying to load Google Maps on demand? To load the API dynamically, pass a callback parameter, as shown on the Example
I think you'll need to rename your LazyLoad script, because it already exists. :) Speaking of which, it already exists, so why write it again?
If you just want to see how it's done, the source code is available.
Yeah, why reinvent the wheel. You seem to be using jQuery.
try this plugin:
Load image only when it is viewable?
Found a solution:
Check the URL:'http://maps.google.com/maps/api/js?sensor=true'
You would find main.js is being imported by it . A simple getScript for sensor=true will not give whole google object so next import also required.
var t=setTimeout(function(){
jQuery.getScript('http://maps.google.com/maps/api/js?sensor=true');
jQuery.getScript('http://maps.gstatic.com/intl/en_us/mapfiles/api-3/10/20/main.js');
},1000);
PS: Similar issue thread Lazy loading google map api

Categories