Issue #32 resolved

Dynamic javascript loading in dashboard doesn't work

mandx
created an issue

This code:

{{{

!html

// load jquery if it's not loaded yet if (typeof jQuery == 'undefined') { var script_url = '{{ media_url }}/admin_tools/js/jquery/jquery.min.js'; document.write(unescape('%3Cscript src="' + script_url + '" type="text/javascript"%3E%3C/script%3E')); } // load jquery ui if it's not loaded yet if (typeof jQuery.ui == 'undefined') { var script_url = '{{ media_url }}/admin_tools/js/jquery/jquery-ui.min.js'; document.write(unescape('%3Cscript src="' + script_url + '" type="text/javascript"%3E%3C/script%3E')); } // load json if it's not loaded yet if (typeof JSON == 'undefined') { var script_url = '{{ media_url }}/admin_tools/js/json.min.js'; document.write(unescape('%3Cscript src="' + script_url + '" type="text/javascript"%3E%3C/script%3E')); } // load jquery cookie if it's not loaded yet if (typeof jQuery.cookie == 'undefined') { var script_url = '{{ media_url }}/admin_tools/js/jquery/jquery.cookie.min.js'; document.write(unescape('%3Cscript src="' + script_url + '" type="text/javascript"%3E%3C/script%3E')); }

}}}

jQuery remains undefined after the first load, and fails to load everything thereafter... Tested with Firefox and Chrome.

Using the current revision http://www.bitbucket.org/izi/django-admin-tools/changeset/c179e18b0f2f

Comments (10)

  1. Anonymous

    Yes, and Firebug reports that these admin_tools files are loaded:

    http://127.0.0.1:7000/media/admin_tools/css/dashboard.css

    http://127.0.0.1:7000/media/admin_tools/js/jquery/jquery.dashboard.js

    http://127.0.0.1:7000/media/admin_tools/js/jquery/jquery.min.js

    http://127.0.0.1:7000/media/admin_tools/images/admin-tools.png

    And in that order. That's why I think that javascript files are loaded asynchronously. I have added admin_tools to a second project of mine and the result is the same!

    This is what I do to install django-admin-tools:

    • Add 'django.core.context_processors.request' to TEMPLATE_CONTEXT_PROCESSORS
    • Insert 'admin_tools', 'admin_tools.theming', 'admin_tools.menu', 'admin_tools.dashboard' at the top of INSTALLED_APPS
    • $ python manage.py syncdb
    • Added the url pattern at the end of urls.py, like this urlpatterns += patterns('', url(r'^admin_tools/', include('admin_tools.urls')),)
    • $ ln -s /django-admin-tools/admin_tools/media/admin_tools/ site_media/ (where "/django-admin-tools" is the dir creating with hg-clone, and "site_media/" is the MEDIA_ROOT, relative to project root dir)
  2. David Jean Louis repo owner

    Sorry for the delay... bitbucket fails to send updates on bugs now :(

    I'll try to fix this, but I fear the only solution is to fallback to <script> tags with the risk of conflicts if the file is already loaded (and is a different version)...

    -- David

  3. mandx reporter

    Add entries in the settings module for this. Anyway, why not use a "chained" loading? In the link I mentioned, shows how a callback function can be triggered when a script is loaded dynamically. You can use that to load the "next" script...

    Some pseudo code:

    js_files = [
        'url1',
        'url2'
    ]
    
    function load_script(index){
        if (0 <= index < js_files.count) {
            // add script element
            script_elem.src = js_files[index];
            script_elem.onload = load_script(index + 1);
        }
    }
    
    // Init the chain
    load_script(0);
    

    Don't know much of Javascript, but this could be done, doesn't?

    Let's try if setting "asigned to" make notifications work... :D

  4. Mikhail Korobov

    Hi David.

    The code works with firefox but chrome and safari are still broken. There is a race between load_scripts and inline scripts: inline scripts begin to execute before all jquery-ui, etc. scripts are loaded.

    I've introduced a fix in my branch: process_bookmarks and init_dashboard are now executed in callback so we can be sure that all necessary scripts are loaded.

    I have one remaining concern: process_bookmarks and init_dashboard scripts must be executed after all scripts are loaded AND after the DOM is loaded (ready event). My approach is to attach .ready callback in loadScripts callback. It is incorrect if it is possible that ready event is fired before our scripts are loaded. I haven't figured out what is the browsers' behavior regarding injected script tags. This code works for me now.

  5. David Jean Louis repo owner

    Hey Mikhail, I've pulled your changes, I think it's ok, I just had to add a try/catch to the script test because it was still failing on Opera, but otherwise it seems to work very well.

    Thanks !

    -- David

  6. Log in to comment