“Uncaught TypeError: undefined is not a function” error when loading jstree inside of Ektron widget editor

StackOverflow https://stackoverflow.com//questions/25083036

  •  02-01-2020
  •  | 
  •  

Question

I've got an ASP.NET user control that contains a jsTree object and a jqGrid object. the control works fine when embedded directly onto a page.

However I'm running into problems when I place the control inside of an Ektron widget editor control. I'm getting an "Uncaught TypeError: undefined is not a function" when loading the tree.

The HTML looks like:

<table class="men-content-selector">
    <tr>
        <td style="width: 280px;">
            <div id="tree" class="men-tree" style="overflow: auto; width: 280px; height: 340px;">
                <div id="jstree_demo_div"></div>
            </div>
        </td>
        <td style="vertical-align: top;">
            <div class="men-grid" style="overflow: auto; height: 340px;">
                <table id="jqgrid_demo"></table>
            </div>
        </td>
    </tr>
</table>
<button id="select-this-content" type="button">Select Content</button>

The JavaScript as follows:

$('#jstree_demo_div').jstree({
    'core': {
        'data': {
            'url': function (node) {
                return node.id === '#' ?
                    '/HttpHandlers/Folders.ashx?folderId=0' :
                    '/HttpHandlers/Folders.ashx?folderId=' + node.id;
                // return '/HttpHandlers/Folders.ashx?folderId=82';
            },
            'data': function (node) {
                return { 'id': node.id };
            }
        }
    }
}).on('changed.jstree', function (e, data) {
    var nodeId;
    if (data.selected.length == 1) {
        nodeId = data.instance.get_node(data.selected[0]).id;
    }
    $('#folder-id').html('Selected Folder ID: ' + nodeId);
    $("#jqgrid_demo").setGridParam({ url: '/HttpHandlers/FolderContents.ashx?folderId=' + nodeId });
    $("#jqgrid_demo").trigger('reloadGrid');
});

The scripts that are loaded in both the working and non-working pages are:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="/Includes/js/jquery.dropkick.js"></script>
<script type="text/javascript" src="/Includes/js/whitespace.js"></script>
<script type="text/javascript" src="/Includes/js/global.js"></script>
<script type="text/javascript" src="/Scripts/rbsmaster.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
<script type="text/javascript" src="/Includes/js/jqTree/jstree.min.js"></script>
<script type="text/javascript" src="/Includes/js/jqGrid/i18n/grid.locale-en.js"></script>
<script type="text/javascript" src="/Includes/js/jqGrid/jquery.jqGrid.min.js"></script>

The error occurs on the line - $('#jstree_demo_div').jstree({

Any help would be appreciated.

Cheers, Stuart.

Was it helpful?

Solution

It sounds like the jstree JS file is not being loaded hence the browser not understanding what jstree() is. I would check the Network tab in Chrome to make sure all your JS files are loading. Failing that use the Console tab in Chrome to see if there are any earlier errors occuring which are stopping jstree from working.

You may also find that you are loading 2 jQuery libraries (one from Ektron and one of your own) so this may stop jQuery from working properly. If so, remove your own.

By adding your code into an Ektron widget you are adding your JS code into a load of other JS code. Inevitably there are conflicts. Using Chrome's Console or Firefox's Web Developer toolbar will help track them down.

OTHER TIPS

When working within a widget, it is usually a good idea to register your scripts with the Ektron API:

// for CSS files
Ektron.Cms.Framework.UI.Css.Register(this, "~/css/widgetstyle.css");

// for JS files
Ektron.Cms.Framework.UI.JavaScript.Register(this, "~/Includes/js/jquery.dropkick.js");
Ektron.Cms.Framework.UI.JavaScript.Register(this, "~/Includes/js/whitespace.js");
// etc.

This will make sure your scripts are only on the page once even if more than one instance of your widget is dropped on the page. However, this will put the script tags up in the <head> of the document, so be careful, especially if you are putting other scripts at the bottom of the page.

I agree with rf_wilson that two copies of jQuery are being loaded. jstree is being added to one copy then when you reference $, you are referencing the copy that does not have jstree loaded into it.

An easy thing to try would be to call $.noConflict() immediately before your line $('#jstree_demo_div').jstree({

That will assign the $ variable to the other copy of jQuery.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top