1

I am trying to write a CDN fallback for datatables.min.js -- somehow, I couldn't find any on Google or on datatables.net. After reading this StackOverflow post and this DataTables post, I came up with this unsuccessful piece (even tried various expressions as shown):

<script>
    if (typeof jQuery.fn.dataTable === 'undefined') {
        document.write('<script src="~/scripts/datatables.min.js"><\/script>');            
        //document.write('<script src="~/scripts/datatables.min.js">\x3C/script>'); //same
        //document.write('\x3Cscript src="~/scripts/datatables.min.js"\x3E\x3C/script\x3E'); //same
    }
</script>

For troubleshooting, I loaded datatables.min.js directly and got these two confusing results:

1/ I get undefined (BAD) from this:

<script>
    document.write('<script src="~/scripts/datatables.min.js"><\/script>');
</script>
<script>
    alert(typeof jQuery.fn.dataTable);
</script>

2/ ... but somehow I get function (GOOD) from that:

<script src="~/scripts/datatables.min.js"></script>
<script>
    alert(typeof jQuery.fn.dataTable);
</script>

That looks the same to me, especially since document.write uses synchronous loading. I also tried a pure DOM method but no luck.

What am I missing with document.write?

Community
  • 1
  • 1
Alfred Wallace
  • 1,741
  • 1
  • 14
  • 32
  • You are inserting `script` inside `script` in `` – Parth Trivedi Dec 31 '15 at 04:37
  • use `$.getScript('~/scripts/datatables.min.js?' + Math.random(), function () { });` to load script dynamically. – Parth Trivedi Dec 31 '15 at 04:40
  • The `document.write` method has been commonly used and recommended - e.g. see CDN fallback for jQuery (http://stackoverflow.com/questions/5257923/how-to-load-local-script-files-as-fallback-in-cases-where-cdn-are-blocked-unavai). I don't think it is the problem. – Alfred Wallace Dec 31 '15 at 04:42
  • @ParthTrivedi - I tried $.getScript but it does not work either. It even returns a new `404 Not Found` error. – Alfred Wallace Dec 31 '15 at 04:46
  • Yes you are write but it loads lately. so do stuff after it completely write to `DOM` – Parth Trivedi Dec 31 '15 at 04:47
  • 1
    May be problem with `"~/scripts/datatables.min.js"` path. It can't find it and getting `404`. Can you please verify path. – Parth Trivedi Dec 31 '15 at 04:50

3 Answers3

1

Try this

    <script>
    if (typeof jQuery.fn.dataTable === 'undefined') {
        $.getScript(baseURL + '/scripts/datatables.min.js?' + Math.random(), function () {
            //do stuff here
            alert(typeof jQuery.fn.dataTable);
        });
    }
    </script>
Parth Trivedi
  • 3,802
  • 1
  • 20
  • 40
  • This does not work and returns a `404 Not Found` error followed by `undefined`. – Alfred Wallace Dec 31 '15 at 04:51
  • 1
    I have change URL. Please check. Try to give full Url Path. May be problem with relative url `"~/"`. – Parth Trivedi Dec 31 '15 at 04:57
  • Nice catch! Per http://stackoverflow.com/questions/2188218/relative-paths-in-javascript-in-an-external-file, "When in script, paths are relative to displayed page..." Tilda / relative URL does not work in script. Your solution works but with a delay compared to the corrected `document.write` technique. – Alfred Wallace Dec 31 '15 at 05:09
  • @Alfred is this answer help full to you? then do vote. – Parth Trivedi Jan 01 '16 at 03:33
1

In your code document.write and alert will process at the very same time, please realize that the alert will be done by the time "database.min.js" will be available.

Use $(document).ready() or winidow.onload and you will see expected results.

Though read the best practices, pros and cons here before doing this -

http://www.stevesouders.com/blog/2012/04/10/dont-docwrite-scripts/

I will recommend using RequireJS to do this efficiently as described by Scott Hanselman, please go through the below link before attempting to it as he talks about CDN fallback in detail and has covered every aspect of it -

http://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx

Hope it will help and will give you solid base to find correct directions.

Arvin
  • 1,232
  • 9
  • 8
  • I disagree when you say that `document.write` and `alert()` process at the same time. `document.write` is synchronous loading and executes outside of the script. Following that, `alert()` is processed, therefore after `document.write` has been executed. Therefore, `$(document).ready()` is not the way to go for loading a plugin since it will be missing while loading the page and generate errors. `document.write` is an accepted and recommended method for CDN fallbacks - see references above. – Alfred Wallace Dec 31 '15 at 05:30
  • Agree, Scott Hanselman has it the way you needed as outlined in his post in my answers above. Though you may like his post for alternatives and other for performance perspective. – Arvin Dec 31 '15 at 05:45
1

A correct CDN fallback for DataTables following accepted fallback practices is:

<script>
    if (typeof jQuery.fn.dataTable === 'undefined') {
        document.write('\x3Cscript src="/scripts/datatables.min.js"\x3E\x3C/script\x3E');
        //document.write('<script src="/scripts/datatables.min.js"><\/script>');
    }
</script>

or simply

<script>window.jQuery.fn.dataTable || document.write('\x3Cscript src="/scripts/datatables.min.js"\x3E\x3C/script\x3E')</script>

The tilda / relative path in src="" was the problem, as suggested by @ParthTrivedi (see comments). Per this post, "when in script, paths are relative to displayed page".

Community
  • 1
  • 1
Alfred Wallace
  • 1,741
  • 1
  • 14
  • 32