Search code examples
asp.netrequirejsascx

Scripterror when using RequireJS with .NET controls


I'm having a bit of an issue with RequireJS.

I have a .NET site with several controls that contains JS code which requires parameters generated by .NET. I've been trying to implement RequireJS into my site, but I ran into a small problem.

I've included the script tag that references RequireJS at the top of the page, as well as reference to main.js within that script tag. Inside my main.js I have the following code;

require.config({
    paths: {
        'jquery' : '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min'
    }
});

Then I have a web control that is supposed to display a flash video. This web control contains the following piece of code;

require(['jquery'], function ($) {
    if (!eval('<%= FlashAvailable.ToString().ToLowerInvariant() %>')) {
        var url = '<%= FallbackImageUrl %>';
        if (!url) {
            $("#flashcontent").remove();
        }
        return;
    }

    var link = '<%= Page.ResolveUrl("~/Templates/AlloyTech/scripts/slideshow.swf") %>';
    var width = '<%= Width %>';
    var height = '<%= Height %>';

    var variables = { xml: '<%= ConfigXml %>' };
    var params = { wmode: 'transparent' };
    var attributes = { };

    swfobject.embedSWF(link, 'flashcontent', width, height, '10', false, variables, params, attributes);
});

This should be working fine right? However, executing the page results in two sets of errors.

 1. GET http://episerversite6/scripts/jquery.js 404 (Not Found)
 2. Uncaught Error: Script error http://requirejs.org/docs/errors.html#scripterror

Why is it trying to find jquery.js when I've defined the path for jquery is 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min'. I've tried adding a second parameter for the path, which is a local fallback jQuery file, and that makes everything work, but I'd still get the first error in my console.

Secondly, why am I getting the scripterror message? I've checked my code several times and I can't seem to find anything wrong with it. Does it have something to do with the code being executed before jQuery has time to load?

So I guess what I'm asking is, what's the best way to use RequireJS with inline scripts? I hope someone can help. Thanks in advance.


Solution

  • It seems I have misunderstood how RequireJS works and the need to rewrite my code accordingly.

    So what I decided to do instead is append all ASP.NET generated variables to the elements they're affecting as data-* attributes, and moving all JavaScript codes to individual files which are then referenced in the main.js script that runs on page load. The data-* attribute values are fetched later when the script and its dependencies have been loaded.

    So here's what I did to the project I mentioned in my initial question, which is actually an EPiServer CMS demo project called Alloytech.

    Flash.ascx

    <div id='flashcontent'  data-flash-available="<%= FlashAvailable.ToString(CultureInfo.InvariantCulture).ToLowerInvariant() %>"
                        data-fallback-image="<%= FallbackImageUrl %>"
                        data-flash-link="<%= Page.ResolveUrl("~/Templates/AlloyTech/scripts/slideshow.swf") %>"
                        data-flash-width="<%= Width %>"
                        data-flash-height="<%= Height %>"
                        data-flash-variables="<%= ConfigXml %>">
        <img src='<%= FallbackImageUrl %>' alt='<%= FallbackImageAlt %>' />
    </div>
    

    main.js

    require.config({
        shim: {
            'swfobject' : {
                exports: 'swfobject'
            }
        },
    
        paths: {
            'jquery': ['http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min', '/Scripts/jquery-1.7.2.min'],
            'alloytech': '/templates/alloytech/scripts/alloytech',
            'mobile': '/templates/alloytech/scripts/mobile/mobile',
            'swfobject': '/Templates/AlloyTech/scripts/swfobject'
        }
    });
    
    define(['jquery', 'alloytech', 'mobile', 'swfobject'], function ($, A, M, swfobject) {
        $.fn.addFlash = function () {
            return this.each(function () {
                var el = $(this);
                var flashAvailable = el.data('flash-available'),
                    fallbackImage = el.data('fallback-image'),
                    flashLink = el.data('flash-link'),
                    flashWidth = el.data('flash-width'),
                    flashHeight = el.data('flash-height'),
                    flashVariables = el.data('flash-variables');
    
                if (!eval(flashAvailable)) {
                    var url = fallbackImage;
                    if (!url) {
                        el.remove();
                    }
    
                    return;
                }
    
                var link = flashLink;
                var width = flashWidth;
                var height = flashHeight;
    
                var variables = { xml: flashVariables };
                var params = { wmode: 'transparent' };
                var attributes = {};
    
                swfobject.embedSWF(link, 'flashcontent', width, height, '10', false, variables, params, attributes);
            });
        };
    
        $(function () {
            $("#flashcontent").addFlash();
        });
    });
    

    I hope someone else will find this useful.