The new Dijit CheckBox Tree

Introduction

For those of you familiar with the Dijit CheckBox Tree project this is the third installment in the checkbox tree series. The first document discussed the initial project requirements and implementation details based on dojo version 1.3 and 1.4. The second document showed the addition of the so-called Multi-State checkboxes whereas in this episode I’m going to introduce you to the completely new, AMD compliant, version of the Dijit CheckBox Tree.

CheckBox Tree

Dojo & Dijit

Since dojo 1.4 many things have changed with regards to the dojo toolkit, especially the introduction of dojo 1.6 set the wheels of Asynchronous Model Definition in motion. AMD is a new standard detailing how to write modular JavaScript code which can be loaded using an AMD compliant loader. Any AMD compliant module is fully self-contained that is, no more dependencies on global variables, a module can reference other AMD modules by explicitly declaring a dependency using the new require() syntax. This modular approach allows you to be very specific in what needs to be loaded in order to make your application shine. As a result, AMD compliant applications tend to load faster as only the modules you really need are loaded.

In addition to the dojo toolkit enhancements, I received several feature requests, most of them centered around the topic of making it easier to programmatically change the checked state of a checkbox. As of dojo 1.6 people also starting reporting rendering issues with the CheckBox Tree and finally there was of course my private nice to have list.

This first step was to solve the rendering issues, make it dojo 1.7 compliant and add functionality to make it easier to programmatically alter a checkbox checked state. The second step was to create a fully AMD compliant version of the Dijit CheckBox Tree, add some of the Nice To Have features and extend the API’s. This document focuses on the second part.

Special thanks goes to Vladimir Elistratov who tirelessly perfromed code reviews and provided valuable feedback and suggestions. If you ever feel lost go checkout his great JavaScript geo library

New is better

Now that the new AMD implementation of the ChecBox Tree is available the interim version for dojo 1.7, which addressed the rendering issues, will no longer be available for download.

A New Project

Due to new dojo features, the number of enhancement I had in mind and the new AMD approach, instead of trying to refactor the existing code base I decided to start the AMD implementation as a completely new project called cbtree, short for ‘CheckBox Tree’. The Dijit CheckBox Tree code repository is now available at GitHub allowing you to actively follow any new Dijit CheckBox Tree developments. The download section of the project holds the latest stable version of the project.
cbtree directory

A new project comes with a new directory layout. Please note that the cbtree directory is located at the same level as dojo and dijit. This is important as the included demo applications and unit tests all use relative paths when referencing dojo and dijit modules.

If you haven’t done so already and you want to setup a local HTTP server, the instructions can be found here. However, instead of downloading dojo 1.3.2 as recommended you need to get the latest dojo toolkit instead.

When migrating

If you are planning to migrate from the original Dijit CheckBox Tree to the new AMD implementation please refer to the documentation for a detailed description of all available properties. Also see the New Properties section for additional information.

What’s New

Following is a summary of some of the new features and enhancements, the table is by no means a complete overview. Please refer to the CheckBox Tree documentation for more details.

New and enhanced Feature Description
Tree Styling API The CheckBox Tree comes with a simple TreeStyling API which is loaded as a separate tree extension. The Tree Styling API allows you to dynamically manage tree node icons, labels and row styling either for the entire tree or on a per data item basis.
Store Model API The Store Model API extends the functionality of the standard CheckBox Tree Store Models. The API allows the user to programmatically build and maintain checkbox trees. For example, you can create your store starting with an empty JSON dataset or use an existing data store and use the Store Model API to add, move, remove or change store items.
Custom Widgets Instead of the default Multi-State checkbox that comes with the CheckBox Tree you are now able to specify alternative widgets to represent a store items checked state. The CheckBox Tree packages comes with two demos, tree04.html and tree05.html demonstrating this capability. Demo tree04.html uses the dojox TriStateCheckbox whereas tree05.html uses the dijit ToggleButton widget. An image of the CheckBox Tree with the ToggleButton widget is included below.
Read Only Checkboxes Checkboxes can now be marked as read-only using the tree properties branchReadOnly and leafReadOnly
Multi Model Support The new AMD CheckBox Tree implementation now handles multiple models operating on the same store correctly. Changes made by one model are automatically reflected by any tree associated with other models operating on the same store. For example: all trees on the left in the online demo are associated with just one store, checking a checkbox on one tree will automatically update all other trees.
Updated Event Handling The internal event handling system has been rewritten and optimized to even support trees with thousands of checkboxes. In addition, updates to the checked state of a data item directly in the underlaying store using, for example: store.setValue(), will result in an automatic update of any parent-child relationship keeping the store, model and tree in a synchronized state.
The new event handling also allows you to map any store item property to a tree node property. (see the advanced section in the documentation for details).

Design Principles

In trying to understand what benefits AMD brings to the table and how to leverage it I decided to redesign and, as a result, rewrite the entire Dijit CheckBox Tree. As I mentioned before, AMD is, among other things, about loading only what you need without having implicit external dependencies. Therefore the practice of declaring multiple modules in a single source file is strongly discouraged and as a side effect, it truly creates cleaner code. What about the additional overhead of loading all these smaller modules you ask? Well, I haven’t seen any HTTP 1.0 server in the last couple of years so I guess you won’t notice the difference. Keep in mind you load a lot less code to begin with then you would have with previous dojo implementations, meaning a lot less network I/O. In addition, loading modules cross domain using a CDN, for example, has become a piece of cake.

Code Separation

Originally all modules, that is, CheckBox, CheckBoxStoreModel, _CheckBoxTreeNode and CheckBoxTree were all included in a single source file. With the new implementation however, they have been split into separate files and turned into anonymous classes. In addition, the CheckBox Tree now comes with it own dedicated store models which no longer inherit from the original dijit tree models.

Simple Accessors

Starting with dojo 1.6 simple accessors like get() and set() have been made available for all dijit widgets. These accessors are now also available for the NEW CheckBox Tree, Tree Styling API and Store Model API. For example, setting or getting the checked state of a tree node is as simple as:

nodeWiget.set(“checked”,true)
nodeWiget.get(“checked”)

New Properties

Even though the project is still referred to as The Dijit CheckBox Tree, the reality is that with the new implementation any widget capable of presenting a so-called checked state can now be used. For example, when creating a CheckBox Tree you can, by means of the tree widget property, specify a toggle button, or any other widget for that matter, to be used instead of the default checkbox.

Toggle button Tree

The example on the left demonstrates the use of the ToggleButton widget. Because of these new capabilities the CheckBox Tree store models no longer refer to a CheckBox state, instead they refer to the more generic Checked state.

Therefore all properties formerly prefixed with checkBox are now simply prefixed with checked like: checkedAll instead of checkboxAll. In addition, new properties have been added while others have been removed or have moved from the tree to the model to better decouple the tree from the model.

If you are planning to migrate from the original Dijit CheckBox Tree to the new implementation please refer to the documentation for a detailed description of all available properties including many code samples how to use them.

Tree Styling

The AMD CheckBox Tree comes with a separate Tree Styling API which allows the user to apply styling to either the tree as a whole or set styling properties on a per data item basis using simple accessors like get() and set(). Styling can be applied to the tree node row, icon or label.

Custom Icons

In contrast to the standard dijit tree, which applies tree node styling using callback functions, the Tree Styling API offers the ability to programmatically set styling properties. For example, to change the label styling for a given data item simply call:

tree.set(“labelStyle”,{color:red}, item)

To set an icon, or a set of icons, for a for a given data item call:

tree.set(“icon”, {iconClass:”myIcon”}, item)

or

tree.set(“iconClass”,”myIcon”, item)

Alternatively, you can designate a data item property as the default icon for the given item by setting the new iconAttr property of the store model. If set, both the model and the tree will recognise the item property as an icon class. Please refer to the Tree Styling documentation for details.

Note: With the Tree Styling API loaded you can still use the original dijit tree callback style styling.

Online Demo

The CheckBox Tree package includes a set of demo applications as well as some unit tests which you can you use to verify proper installation. A comprehensive AMD CheckBox Tree demo is also available online.

Custom Icons

The online demo illustrates the CheckBox Tree configurable properties, the tree
styling API, drag and drop feature and the extended store model API.

Also, the left accordion panel demostrate the multi model support, that is, click a checkbox on one tree and all other trees with checkboxes are automatically updated.

Download

The Dijit CheckBox Tree source code, documentation and demos can be downloaded straight from the GitHub repository or as zip file from the associated download section. Note, the download section holds the latest stable version of the code. When installing the CheckBox Tree package make sure you install it according the above shown directory structure.

Documentation

All included documentation is written using the Markdown format and is also available online here.

Code Sample

The following is a simple application which creates a CheckBox Tree and connect to the onCheckBoxClick event. Whenever a checkbox on the tree is clicked the function checkBoxClicked() is called displaying the updated checked state for the associated tree node.

  1 <html lang="en">
  2   <head>
  3     <title>Dijit Tree with Checkboxes</title>
  4     <style type="text/css">
  5       @import "../../dijit/themes/claro/claro.css";
  6       @import "../themes/claro/claro.css";
  7     </style>
  8     <script type="text/javascript">
  9       var dojoConfig = {
 10             async: true,
 11             parseOnLoad: true,
 12             isDebug: true,
 13             baseUrl: "../../",
 14             packages: [
 15               { name: "dojo",  location: "dojo" },
 16               { name: "dijit", location: "dijit" },
 17               { name: "cbtree",location: "cbtree" }
 18             ]
 19       };
 20     </script>
 21     <script type="text/javascript" src="../../dojo/dojo.js"></script>
 22   </head>
 23   <body class="claro">
 24     <h1 class="DemoTitle">Dijit Tree with Multi State CheckBoxes</h1>
 25     <div id="CheckboxTree">
 26       <script type="text/javascript">
 27         require([
 28           "dojo/_base/connect",
 29           "dojo/data/ItemFileWriteStore",
 30           "dojo/domReady",
 31           "cbtree/Tree",                    
 32           "cbtree/models/ForestStoreModel"  
 33           ], function( connect, ItemFileWriteStore, domReady, Tree, ForestStoreModel) {
 34             function checkBoxClicked( item, nodeWidget, evt ) {
 35               alert( "The new state for " + this.getLabel(item) + " is: " + nodeWidget.get("checked") );
 36             }
 37             var store = new ItemFileWriteStore( { url: "../datastore/Family-1.7.json" });
 38             var model = new ForestStoreModel( {
 39                                 store: store,
 40                                 query: {type: 'parent'},
 41                                 rootLabel: 'The Family'
 42                              });
 43             var tree = new Tree( {
 44                               model: model,
 45                               id: "MenuTree",
 46                               branchIcons: true,
 47                               branchReadOnly: false,
 48                               checkBoxes: true,
 49                               nodeIcons: true
 50                             });
 51             connect.connect( tree, "onCheckBoxClick", model, checkBoxClicked );
 52             domReady( function() {
 53               tree.placeAt('CheckboxTree');
 54             });
 55         });
 56       </script>
 57     </div>
 58     <h2>Click a checkbox</h2>
 59   </body>
 60 </html>

The CheckBox Tree package and documentation include many more examples.

How Does It Work

The easiest way to exaplain how the Dijit CheckBox Tree works is by using some simplified sequence diagrams and a high level overview of some of the internal functions. If you want all the details then the source code is going to be your best friend. In this How To section I’m going to use two diagrams to explain how the above sample code works and what happens under the hood.

Creating the CheckBox Tree

On lines 37-50 we instantiate the store, model and tree. When the model is created it connects, or better yet subscribes, to the onSet event of the store. Whenever a property of a data item changes, the store will generate an onSet event. The onSet event holds information about the data item, the property that changed and what the new property value is.
When the tree is created on line 43, it internally connects to the onChange event of the model. As part of the post create stage of the tree it starts loading the data store by calling validateData() and for each data item a tree node and checkbox is created.

The models validateData() is an essential part of the CheckBox Tree, it loads the store data items and synchronizes their checked state when the parent-child checkbox relationship is requested.

The diagram below shows the sequence of events involved in creating a CheckBox Tree.

Custom Icons

If you take a closer look at the sequence diagram you will notice that the tree never interacts with the store directly, this is part of the Model-View-Controller design pattern.

Getting notified

In order for our sample application to get notified whenever the user clicks a tree checkbox it needs to connect to the onCheckBoxClick event of the tree. On line 51 the application connects to the event specifying checkBoxClicked as the callback function.

connect.connect( tree, "onCheckBoxClick", model, checkBoxClicked );

The function checkBoxClicked() on line 34 will be called in the context of the model, that is, the “this” object equates to model.
So what happens when a user clicks a checkbox? The following diagram show the sequence of events that take place each time a user clicks a tree checkbox. The first thing the tree node will do is to verify the click event took place on a DOM element of type “input”, if so, it gets the new checked state from the checkbox.

Custom Icons

Next, the tree node will tell the store model to update the checked state for the data item associated with the node by calling setChecked(). Simply speaking, the model will take the request and in turn asks the underlying store to do the same. On completion the store will generate an onSet event.

Because the model subscribed to the onSet event of the store, as shown in the first diagram, it gets notified about the store update and this is were the interesting stuff starts to happen. Any data item in the store may have any number of parent items so, assuming the parent-child relationship for the model is enabled, the model will take the onSet event and updates the checked state of all parent items according to the new state of the checkbox that just got updated.
Although not visible on the sequence diagram, any update to a parent item results in another call to the setChecked() function untill all have been updated. So a single click on a tree checkbox can result in several store updates. In addition, if the tree node whose checkbox was clicked has any children those children will also be updated.

Being the system architect that you are, you are wondering: why not update the parent items and potential children as soon as the original setChecked() call comes in? It would make things alot easier as you don’t have to handle the onSet event from the store.
The answer is: there can be multiple models operating on the same store. For example, lets assume you have two trees A and B, and each tree has its own model A and B. If a checkbox gets clicked on tree A, the tree will call setChecked() of model A therefore model B has no notion of any click event. However, because both models are subscribed to the onSet event of the common store, both models will be notified of the store update thus allowing both model A and B to update their own tree.

Finally, when the model receives the onSet event it will generate a matching onChange event which is caught by all trees associated with the model. Note, you can associated multiple trees with a single model. The tree will then search for all tree nodes associated with the data item and send a set(“checked”, newValue) request to each of them.

131 Replies to “The new Dijit CheckBox Tree”

  1. Terrific work.

    However, I can’t seem to get it to work with dojox.data. FileStore as the store (and its backend filestore.php for getting a file directory tree from server); I get ‘cbTree/ForestStoreModel::constructor(): store is not write enabled.’ I’m hardly a data store expert – should it be able to work with FileStore? Thanks.

    1. Mike,
      The checkbox tree store models currently only works with the ‘/dojo/data/ItemFileWriteStore’. So why doesn’t the ‘/dojox/data/FileStore’ work? There are a couple of reasons:

      1. The dojox FileStore has no write interface (as the error already indicated).
      2. The internal structure of the FileStore lacks several features offered by the ItemFileWriteStore and cbtree ItemFileWrtieStore extension which are required by the cbtree models.

      First, in order for the checkbox tree to maintain a consistent checked state the tree models stores the checked state with the data item in the store. This is why the store must support the write interface.

      Second, for the tree models to be able to maintain the so-called parent-child relationship the store must support a reversed parent reference, that is, each child must have a reference back to its parent(s). This is something which is not supported by the dojox FileStore either.
      The solution here would be to write you own cbtree model or, after loading the FileStore convert it to a ItemFileWriteStore. The model interface is defined in /cbtree/models/Model.js

      Future releases of the Dijit CheckBox Tree may include a more generic model that doesn’t rely on some of the specific ItemFileWriteStore features.

  2. Hello, great job indeed.

    Right now I am using this kind of idea on a project however in your checkbox tree when I tryed to use I realized there is a widget id named “content” and if there is another widget named “content” already, error happens.

    Unfortunately I am not able to change the entire project right now but I liked your check box tree and will try on future works for sure.

    Good luck,

    1. Maryl,

      I guess I understand your problem but I just build a new tree, loaded all possible extensions and API’s but still the CheckBox Tree did not create a widget with id “content”. Try using dijit.byId(‘content’) to see what type of widget your ‘content’ widget is. Or post the section of code your are using that produces the problem.

    1. Well, the Checkbox tree has been tested with over 25000 data items without any problem. If you load your sample code in Firefox and enable firebug you’ll see that on line 80 you call ‘parseXml(taxdata).documentElement’ and apparently parseXml is not declared. Next, you data has duplicate name attribute value, therefore on line 83 remove the “identifier” attribute and turn it into: ‘var EmptyData = { label:’name’, items:[JSON.parse(data)] }’ which will allow multiple instances of the same name. Finally, remove line 107 ‘dom.byId(“codeSegm”).innerHTML = html[0]’ I assume left from some copy and past operations.

      I would recommend to put your data in a file, makes maintaining it a lot easier.

      Good luck.

      1. the parseXml error was just a copy-paste-edit mistake. Sorry about that. removing the “identifier” attribute made it work! Thanks a ton man! I think I’ll look into the API to learn further about how to get the list of checked elements.

    1. Currently you can’t. Making a store item read-only requires an additionnal property in the store itself, this because a store item can appear multiple times in a single tree (think of a family tree). Therefore, just making an individual checkbox read-only doesn’t make sense. Remember a checkbox is just a presentation of the checked state of a store item.

      1. like in the tree constructor you can make leaf read only. I want to make some of the nodes read only. So their checkboxes’ values change based on tree relationships but they themselves can not be clicked.

        1. As I mentioned before, you need to add an additional property to the store items and create you’re own instance of ‘_createCheckBox()’. BTW: only parents (tree branches) inherit their checked state based on their childrens state which is handled by the model and not the tree.

    1. I’m not sure what you mean by element? Are you talking about a store item, a tree node, a checkeck box or a DOM element.

      1. I mean an element in the tree heirarchy. a tree node. Essencially when I perform queries in the model, I want this to be included in the result but I don’t want this to be visible to the user in the tree heirarchy.

        1. The only way to hide store items from being included in a tree is by means of the initial store model query. You can specify a query argument when instanciating the model and optionally set the queryOption ‘deep’ to true. This however may change the overall structure of your tree as all items matching the query will become top level entries in the store and thus root elements in your tree. If this doesn’t work for you you will have to mess with the tree itself which is much more involved.

    1. The answer is no, you can however test the tree node property ‘isExpanded’ to see if a tree node is currently expanded.

    1. Yes, when you create the CheckBox Tree set both the branchIcons and nodeIcons properties to false. Like in:


      var myTree = new Tree( { branchIcons: false, nodeIcons: false, ... } );

      That will do the trick.

      1. Does it mean you reuse the dijit.tree feature to hide the branch icon and node icon? I did not find dijit.tree has the branchIcons and nodeIcons properties , how you achieve this function ?

  3. Hey, I met a problem when use cbtree.Tree and dijit.Tree together.
    Let’s say, the first page has a dijit.Tree. of course, required js files were marked include in that page. And I have another empty page which is only including the following files:
    “cbtree/Tree”, “cbtree/TreeStyling”, “cbtree/models/ForestStoreModel”
    After I visit the second page(after download the js files to local), the dijit.Tree will not shown any more.
    Is there a way to make the cbtree.Tree working well with dijit.Tree together?

    1. After I read some of your code, it seems like you are using dojo.connect to append your code in TreeStyling.js, could you tell me how to dojo.disconnect the link after the show of cbtree.Tree. how to restore the connect when we want the cbtree.Tree to be shown again?

      Thanks in advance,

      1. Loading the TreeStyling module will extend the CheckBox Tree not the fact that it connects to the “onDelete” event of the model. The connect onDelete is required to make sure all styling elements are removed whenever a store item is deleted, you should NOT disconnect from the event.

    2. It is not recommended to use both trees at the same time as the CheckBox Tree extends the dijit tree. You can easily replace your dijit tree on page one with the CheckBox Tree and set its checkBoxes property to false like in:

      var myTree = new cbtree( {checkBoxes: false, ... } );

      The CheckBox Tree will appear as a regular dijit tree.

  4. var model = new cbTree.models.ForestStoreModel({
    store: ConSectionTreeStoreA,
    query: { ID: ‘0’ },
    rootLabel: ‘The Network’,
    childrenAttrs:”children”,
    checkedAll: true,
    checkedRoot: true,
    checkedState: true,
    checkedStrict: true
    });

    var tree = new cbTree.Tree({
    model: model,
    id: “ConSectionTreeid”,
    checkboxMultiState: true,
    icon: { iconClass: “networkIcon”, indent: true },
    branchIcons: true,
    nodeIcons: true
    }, “SectionEditTreeContent”);
    tree.startup();

    1. Thanks for pointing this out. This issue is fixed in the upcoming 1.8 release, for the time being use one type of tree in your application, that is, either the dijit/Tree (without the tree styling) or cbtree/Tree. If you use the CheckBox Tree and want it to look like the original dijit tree, create the CheckBox Tree with the checkBoxes set to false as in:

      var myTree = new cbtree( {checkBoxes: false, ... } );

      Alternatively, don’t load the cbtree/TreeSyling extension, this extension is only required if you want to apply tree node styling on a per store item bases.

      Hope this helps.

  5. Hello, I’m trying to get checkboxes to appear. I see the space where they should appear. I look at the css and I see a css rule for .dijitCheckBoxInput (claro.css:520) with an opacity set to .01. if i turn this off I can see a checkbox, but it’s not the nicely styled checkbox you have in your demos. Would appreciate some guidance and I hope that this is an easy answer. Thank you.

    Here is my code:

    var categoryData = { “identifier”: “name”,
    “label”: “name”,
    “items” : self.categoryTree
    };
    console.log (” the data = “, JSON.stringify(categoryData, undefined, 2));

    var store = new ItemFileWriteStore( { data: categoryData });
    var model = new ForestStoreModel( {
    store: store,
    query: {“type” : “parent”},
    rootLabel: “Categories”,
    });
    var tree = new Tree( {
    model: model,
    id: “Categories”,
    });

    tree.placeAt( “categoryTree” );
    tree.startup();

    And here is a snippet of the categoryTree (json):
    the data = {
    “identifier”: “name”,
    “label”: “name”,
    “items”: [
    {
    “name”: “Travel”,
    “type”: “parent”,
    “children”: [
    {
    “name”: “GPS Software”,
    “type”: “category”,
    “checked”: true
    },
    {
    “name”: “Transportation”,
    “type”: “category”,
    “checked”: true
    },
    ]
    }
    ]
    }

    1. Sarah,

      Your code snippet looks fine, I think, without having seen all of the code, your are missing the CheckBox Tree css file. In addition to the standard dijit theme you MUST load the CheckBox Tree css file as well otherwise you won’t see any checkboxes.

      If you have unzipped the CheckBox tree package without modification you can find the CheckBox Tree css file(s) in the directory /cbtree/themes. If you are running the dijit Claro theme you would need to load /cbtree/themes/claro/claro.css.

      To make you application work you would typically include, at a minimum, the following files:

      
          <style type="text/css">
            @import "../../dijit/themes/claro/claro.css";
            @import "../themes/claro/claro.css";
          </style>
      

      The first file is the standard dijit css file, the second the CheckBox Tree css file. The above snippet was taken from one of the demo files included in the package.

      Hope this will fix your problem,
      Good luck

  6. Hi,
    I am fan of your checkbox tree from the first second (I also used it with dojo 1.4 and 1.6). For now I am migration to dojo 1.8 and tried to use you checkbox tree, but it fails with a “Uncaught lang.hitch: scope[“_onMouseEnter”] is null (scope=”[Widget dijit._TreeNode, dijit__TreeNode_0]”) ” error. The examples (all of them) also fail.
    I also looked at your demo but it uses dojo 1.7.2. Sadly I am not aware if it makes a huge difference. May you have any suggestions where I could look at to get it working. Thanks in advance.

        1. Hi Paul,

          Just to verify the procedures I downloaded dojo 1.8 from http://dojotoolkit.org/download/ and did a clean install, fetched the cbtree 0.9.2 package from https://github.com/pjekel/cbtree/downloads/ and installed it as a subdirectory of dojo 1.8. Note: you need to rename the /cbtree-0.9.2 directory to /cbtree. I ran all demos in the /cbtree/demos directory and they all work.

          It looks to me that your dojo 1.8 environment isn’t installed correctly or your ‘dojoConfig’ is setup incorrectly and thus loading stuff from locations you did not expect. Try the steps descibed above and let me know if you still have the same problem. If you don’t, you need to take a close look at your current dojo 1.8 installation and make sure you use the correct package definitions.

          1. Hi,

            so I reinstalled dojo (SDK and normal) and cbtree several times, but the output is still the same. However if I use Googles CDN it work quite nicely.

            Sadly I can’t use that offline (e.g. if you want to work while sitting in a plane or train). If I have more time I’ll reinvestigate this issue.

            Thanks for your help, I appreciate that.

          2. It clearly sounds to me you have an issue with relative paths. When using Googles CDN your are specifying an absolute URL whereas local installations rely on relative paths. For example, all demos load dojo as follows:

            <script type="text/javascript" src="../../dojo/dojo.js">

            All demo also have dojoConfig defined as:

            
                  var dojoConfig = {
                        async: true,
                        parseOnLoad: true,
                        isDebug: true,
                        baseUrl: "../../",
                        packages: [
                          { name: "dojo",  location: "dojo" },
                          { name: "dijit", location: "dijit" },
                          { name: "cbtree",location: "cbtree" }
                        ]
                  };
            

            Notice the baseURL defined relative too.

            To troubleshoot the issue here are a couple if things I would look at:

            – What does your HTTP document root look like.
            – Check your server configuration for any rewrite rules and aliases.
            – Check all your .htaccess files for rewrite rules.

            Good luck, let me know when you find the problem.

  7. Hi,

    I didn’t investigate the issue with the loading further so far. But I found another problem with the tree (probably I did something wrong again). I prepared a small example here: http://campusgis.geo.tu-freiberg.de/webgl/testCase/tree/tree.html . If I check one checkbox the proper event is getting fired, but the checkbox itself is not updated. Furthermore the events are not called if I check the branch checkbox. Is there any better event to catch or to put my callback?

    Thanks for you help.

    1. Paul,

      There are a couple of things you have to consider. The AMD version of the checkbox tree, that is dojo 1.7 or higher, no longer support native HTML checkboxes. As a result you MUST load the appropriate cbtree css file for any given theme. I noticed your sample is using a non standard dijit theme ‘giga’, which is perfectly fine but it means you will have to create a similar theme for the cbtree and load it accordingly.

      Now lets assume you would be running the dijit ‘claro’ theme using the google CDN in which case you need to load the dijit and cbtree css file as follows:

      <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.8.0/dijit/themes/claro/claro.css" />
      <link rel="stylesheet" href="<your_cbtree_path>/cbtree/themes/claro/claro.css" />

      Actually, the dijit themes may be loaded automatically when loading dojo from a CDN. Anyway, in the above example replace <your_cbtree_path> with whatever your configuration requires. In addition, (running the claro theme) the body would look like:

      <body class="claro">
      ....
      </body>

      If you need the checkbox tree with the your ‘giga’theme you would have to create a new cbtree themes sub-directory called giga as in: /cbtree/themes/giga and create your custom css files and images.

      Good luck.

    2. Paul,

      One more thing I wanted to point out in you sample. The ForestStoreModel can simply be created as:

      treeModel = new ForestStoreModel({
      store: store,
      query: {
      classType: 'featureClass'
      },
      rootLabel: 'FeatureList',
      rootId: 'FeatureList',

      checkedAll: false,
      iconAttr: 'icon'

      I haven’t seen your ‘features.json’ file but if you are not planning on using the per store item icon feature you can remove the ‘iconAttr’ property as well. In addition, for standard cbtree operation there is no need to load the TreeStyling extension.

  8. Hi,
    Thanks for this great extension to the Dijit library.

    Is it possible to have a MIX of nodes with and without checkBoxes? Could it be achieved by an attribute in the data store?

    e.g. “displayCheckBox” below :-
    {
    id: ‘LDN’,
    name:’London’,
    type:’city’,
    displayCheckBox:true,
    checked:true
    }

    Jason

    1. Yes, you can. When creating your model set the ‘checkedAll’ property to false, this will force cbtree to only create checkboxes for those store items that have a ‘checked’ property. For example:


      var myModel = new ForestStoreModel( {store: myStore, checkedAll:false, ....});

      Now, in your data file define the items with or without the ‘checked’ property, as in:

      {id:’LDN’, name:’London’, type:’city’, checked:true}
      {id:’BOS’, name:’Boston’, type:’city’}

      With this dataset London will get a checkbox whereas Boston won’t.

      As an alternative, you can make individual checkboxes ‘read-only’ by adding a custom property to the data items as in:

      var myModel = new ForestStoreModel( {store: myStore, enabledAttr:"enabled", ....});

      And define your data items as follows:
      {id:’LDN’, name:’London’, type:’city’, checked:true, enabled:false}
      {id:’BOS’, name:’Boston’, type:’city’, checked:true, enabled:true}

      In this case both London and Boston will get a checkbox but the one for London is grayed out and not clickable. Your can dynamically change the enabled state by doing something like:

      myModel.setItemAttr( storeItem, "enabled", true );

      For more detailed information please refer to the online documentation for the model at:
      https://github.com/pjekel/cbtree/blob/master/documentation/StoreModels.md

      Hope this helps.

      1. It works! Thanks for that – I already knew about the disable option but this is better.

        I assumed ALL nodes get a checkbox – I didn’t know that if you left out the “checked:” attribute in the store model, then no checkbox would appear for it. Should that be explicitly explained in the documentation?

  9. I have another question – in the node icons, instead of the default folder and file icons, I have a simple div box showing a particular color for each node.

    Is it possible to make the icon clickable such that a dijit.ColorPalette is shown for the user to change the color if the div box?

    Any ideas how we could do that?

    Thanks
    Jason

    1. Jason,

      There is no specific event for clicking tree node icons however, you can try the following:

      
      function nodeClicked( item, nodeWidget, evt ) {
        if (evt.target.nodeName == "IMG" ) {
          console.log( "Icon clicked" );
        }
      }
      
      tree = new Tree( { ... } );
      tree.on( "click", nodeClicked );
      

      Hope this helps a little.

  10. I have my own widget that inherits from digit.Tree and digit._TreeNode, but now wish to use cbtree, it seems the cbtree._TreeNode is not visible to be inherited.

    How can I inherit from cbtree and its tree node?

  11. Hi guys,

    I’ve been trying to figure out how to refresh the contents of the tree. I’ve narrowed it down to the following, but I am unsure how to proceed.

    1) In my ItemFileWriteStore, specify a URL, clearOnClose=true, and urlPreventCache=true

    2) When the contents of the remote store (the url) change and the tree must be reloaded:
    store.close()
    store._jsonFileUrl = “newUrl” // if desired; optional
    store.fetch({
    onComplete: myFunc
    }) // as per the dojo.data Read API

    3) In myFunc, I’ve got access to the new list of items, gotten from the XHR made to the store URL.

    4) ???

    At present, when I try to manipulate entries in the tree, I get ItemFileWriteStore errors indicating “invalid item argument”.

    What additional (or alternate?) steps do I need to perform in order to expose the new store data to the tree?

    Much obliged,
    – Peter

    1. Peter,

      There are a number of issues at play here. First the ItemFileWriteStore is very strict in terms of object references. If an object passed to the store is not an instance that belongs to the store an exception is thrown. If, for example, you close the store and reload the exact same data from the original URL you will have the same problem simply because the store created new objects. When the tree and model are created they (the model) loads the data from the store and each tree node will have a object reference for each store item. As a result you can’t delete/refresh the store without destroying the tree and model. The dijit/Tree implementation was never designed to support a store close/refresh. You may have noticed there is no event or callback associated with the store close operation, therefore the model and tree are completely unaware of the fact that a store was closed.

      At first glance you may think, no big deal it can’t be that hard to fix, well….. not really. First and foremost, the ItemFile(Read/Write)Store has been deprecated and probably will no longer be available in dojo 2.0. therefore, even known issues related to the use of those stores will not be fixed in dojo. As of dojo 2.0 the CheckBox Tree (cbtree) will remove all support for those types of stores and related models. To fix the issue with the existing stores and models would require a significant amount of work.

      The good news is that the next release of the cbtree comes with a new set of stores, all based on the new dojo/store/api/Store API, and a new set of models. Even better news is that those cbtree stores and models do fully support the concept of a store refresh. Be advised, we are talking about the CBTREE stores and models, not the standard dojo/store or dijit/tree models. With the new release you could simply refresh you store by doing something like:

      
      require(["cbtree/Tree",
               "cbtree/store/Hierarchy",
               "cbtree/model/TreeStoreModel"
              ], function (Tree, Hierarchy, Model) {
          var myStore = new Hierarchy( {url:"/some/file"});
          var myModel = new Model( {store:myStore, clearOnClose:true... });
          var myTree = new Tree({model:myModel, ...}, "someDiv");
          myTree.startup();
                                 ...
          store.close();
                                 ...
          store.load( {url:"some/other/file"});
        }
      });
      

      The store close operation forces the model to go into a so-called ‘reset’ state which it will not exit from until the store becomes ‘ready’ again.

      The next cbtree-v0.9.3 release will be made available in the next 2-3 weeks depending on the availability of dojo 1.9 although cbtree-v0.9.3 supports both dojo 1.8 and 1.9. In the mean time, most of the documentation for the new release is already available at the Wiki pages at https://github.com/pjekel/cbtree/wiki with detailed information about the new store and model API’s.

      I’m currently in the final phase of testing and adding some more real world demos combining the cbtree with the ArcGIS 3.3 JavaScript API.

      Hope this helps and let me know what you think.

  12. Hello,

    last time you’ve been asking for a link to my application. I somehow wanted to send it to you, but I think I forgot it. So here it is: http://campusgis.geo.tu-freiberg.de/webgl/gstws/.

    I have a question regarding the checking of the checkboxes via JavaScript. I tried to use
    model.setChecked(storeItem);
    but somehow the checkboxes are not updated.

    I am really looking forward for your features you have announced (like refreshing tree).

    Good work, again and again.
    Cheers,
    Paul

    1. Paul,

      When calling model.setChecked() you must specify both the store item AND the new checked state as in: model.setChecked(item, true). The checked state can be either true, false or “mixed” however, if you have normalization enabled (the default), the mixed state translates to boolean true.

      I took a look at you website and although I don’t understand all the specifics I always like 3D models, really cool. I’m sure you are aware it doesn’t render properly in IE, that is IE 9.

      Anyway, with regards to the upcoming cbtree release (I’m waiting for the offical dojo 1.9 release to come out) several of the new features will only be supported using the new cbtree stores which all implement the new dojo/store API.

      The new cbtree stores will eventually be replaced with the IndexedStore, which currently is still under construction: https://github.com/pjekel/indexedStore
      The IndexedStore implementation will make the tree models alot simpler.

      If you like, you can try the upcoming release by downloading the source package at https://github.com/pjekel/cbtree/tree/dojo-1.9

  13. Hi,

    Love the cbtree, very good!

    Now I managed to create some data that gives me a nice tree, with some of the checkboxes checked. This is all according to plan. Now I want to send the data back to the server, so I put in a form, and add a submit button, but none of the form fields (checkboxes) are sent, because they don’t have a name. Here is the HTML that Firebug shows me:

    As you can see, there is an input field of type checkbox that has an “id” attribute, but no “name” attribute. I fixed this in my form “onsubmit” method by adding code that runs through all the input fields, copying the id to the name for the ones that don’t have one. Is this a feature or a bug, or am I missing something.

    This works, because now data goes to the back end. All good, except that the “value” of the input/checkbox field is set to the “label” in the datastore, rather than the identifier. To help make this clear, this is the first part of the json data file:

    {
    “identifier” : “id”,
    “label” : “name”,
    “items” : [
    {
    “name” : “Proposal”,
    “children” : [
    {“_reference” : “/Proposal/Venetian Macau Visitor Profile.doc”},
    {“_reference” : “/Proposal/VenetianMacauVisitorProfile.xls”}
    ],
    “type” : “parent”,
    “id” : “/Proposal”
    },

    So for this first item, it sends the value “Proposal”

    I would have expected that the value to be sent would be the identifier (in this case “id”), rather than the label (in this case “name”). This causes me problems because all of the id’s in my tree are unique, whereas the names are not.

    I am hoping that there is some setting that will fix this for me. I have looked through the source code of cbtree, but couldn’t find anything.

    Excellent work, look forward to hearing from you.

    Mike

    1. Mike,

      Thanks for your post. First, setting the name and value of checkboxes is only required when, as you do, submit a form. The challange with general purpose widgets, like cbtree, is always what fields to use as the checkbox name or value. For example, your application requires certain values whereas other users may require completely different value for the name and/or checkbox value. In addition, simply using the store item name as the checkbox name may work for you but remember those names may clash with other DOM element names already present in the document especially if you have a larger form. Also, store item names may change before submitting the form.

      To make it a little easier for user who want to sumbit forms I will add the store item to the checkbox widget which allows you to setup the checkbox anyway you like just before submitting the form. In your onsubmit() method you could do something like:

      
      function onsubmit () {
        var collect  = document.forms["myForm"].elements;
        var elements = Array.prototype.slice.call(collect);
        elements.forEach( function (element) {
          if (element.type == "checkbox") {
            var checkboxWidget = dijit.getEnclosingWidget( element );
            var storeItem = checkboxWidget.item;
            element.value = storeItem.id;
            element.name  = storeItem.id;
          }
        });							...
      }
      
      

      Hope this will help.

      1. This is excellent, I downloaded the latest and it works just as I want. I changed the name line to be

        element.name=element.id

        This is safer, as it’s using dojo’s generated field id’s

        Thanks heaps for the fast response!

        Mike

        1. Mike,

          Just an update. The questions: How do I submit Checkbox Tree checkboxes in a form? kept popping up, I therefore added build-in support for checkbox submission. As of cbtree v0.9.4 the tree has an additional property called attachToForm and an optional extension TreeOnSubmit.

          Detailed information is available at:

          https://github.com/pjekel/cbtree/wiki/CheckBox-Tree-Usage#wiki-checkboxes-in-html-forms
          https://github.com/pjekel/cbtree/wiki/CheckBox-Tree-in-Forms

          I would appreciate it if you could provide some feedback.

  14. Hi,

    It looks to be a problem with rendering in IE10. IE8 and IE9 work fine.

    Open http://www.thejekels.com/cbtree/demos/ in IE10
    (my version 10.0.9200.16540, update version 10.0.4)

    When you move cursor over check box or you check and uncheck checkBox, there is problem with rendering. Accidentally you can see checked box but it should be uncheck and vice versa. Also rendering of square around check box is not correct.

    What to do with it?

    Thank you
    milan

  15. Hi,
    there is a problem with

    .dijitCheckBoxInput {
    opacity: 0.01;
    }

    I have changed it to

    .dijitCheckBoxInput {
    opacity: 0;
    }

    and it works.

    Thanks
    milan

    1. Mosine,

      I’m not sure why you would want to disable the icon and label but the short answer is that the cbtree has no capabilities to disable those elements. Only the checkbox can be disabled.

  16. Hello. I write an application which needs to navigate through addresses and check them. Let the root node to be some region -> city -> street -> house -> flat (leaf)

    I want to lazy load every node on expand event. All I need to do with server is to ask for another node and that’s all. And fill the tree store. Do you have any examples of lazy load? Is it only possible with jsonrest store? May I, say, populate already filled memory store as I click expand and then see that data on the screen?

    1. Slavs,

      Lazy loading is typically used when either your dataset is dynamic or is very large. If you have less than 5000 addresses I would recommend to simply loading them using a URL. If you still require the lazy loading concept take a look at the following example:

      https://github.com/pjekel/cbtree/blob/master/demos/store/tree40.html

      This example use the cbtree FileStore and FileStoreModel to load file information from a back-end server. The server part of the example can be found here: https://github.com/pjekel/cbtree/tree/master/store/server

      However, keep in mind that lazy loading using a back-end server can be complicated considering you now will also have to deal with the server-side application.

      Hope this helps.

      1. Thank you very much for your answer. I realized that fetching already constructed tree structure is much faster. What for server side scripts – there’s no problem here, I am perl programmer and server side now is still easier for me than dojo. This great tool (cbtree) helped me alot to solve some usability tasks in my business webapp. Thank you again.

  17. Hi,

    I have discovered what looks like a fairly major flaw…

    When the user clicks submit, only the checkboxes that are visible get submitted. So any parts of the tree that are collapsed do not get sent, even if their checkboxes are checked. To my mind the collapsing and expanding of the tree is a convenience for the user to navigate around, and the tree parts that are currently hidden should not be ignored.

    So, 1) am I being reasonable in this expectation and 2) is there anything that can be done about it sure of expanding the full tree when submitting?

    Cheers

    Mike

    1. Mike,

      The issue is not so much a cbtree issue as it is a forms submit issue. Submit only posts document elements that, 1) visible or at least included in the form and 2) have a name. The only options you have is to either permanently expand your tree using the tree property ‘autoExpand’ or in your onsubmit() method query the store and attach the results to a hidden form field.

      1. Mike,

        Just an update. The questions: How do I submit Checkbox Tree checkboxes in a form? kept popping up, I therefore added build-in support for checkbox submission. As of cbtree v0.9.4 the tree has an additional property called attachToForm and an optional extension TreeOnSubmit.

        Detailed information is available at:

        https://github.com/pjekel/cbtree/wiki/CheckBox-Tree-Usage#wiki-checkboxes-in-html-forms
        https://github.com/pjekel/cbtree/wiki/CheckBox-Tree-in-Forms

        I would appreciate it if you could provide some feedback.

    1. There are two ways to programmatically checking all tree nodes:

      1 – Assuming the model property ‘checkedStrict’ is set to true (default) simply execute:

      
      model.setChecked(model.root, true);
      

      2 – Load the store model extension cbtree/model/StoreModel-EXT.js

      
      require(["cbtree/model/StoreModel-EXT", ... ], function (modelExt, ... ) {
              ...
          model.check({checked: false});
              ...	
      }
      

      For additional info on the store model extension please refer to https://github.com/pjekel/cbtree/wiki/Model-Extension

  18. Possibly better formatted example JSON:

    [{
    id: 123,
    parent_1_property: "abc",
    parent_1_prop2: "abd",
    parent_children: [{
    id: 11,
    data: "abc",
    child_children: [{
    id: 11000,
    value1: "blue"
    }]
    },{
    id: 12,
    data: "abd"
    }]
    },{
    id: 124,
    parent_2_property: "gbc",
    parent_2_prop2: "aqd",
    parent_children: [{
    id: 122,
    data: "abc"
    },{
    id: 123,
    data: "abd",
    child_children: [{
    id: 10010,
    value1: "green"
    }]
    }]
    }]

    1. Before I can help you, I need to know the following:

      1 – What cbtree version are you using?
      2 – What dojo version are you using?
      3 – What type of store are you or will you using?
      4 – Is you data static or dynamic (e.g. will you be adding/removing store entries when the tree is created)?

      Keep in mind, regardless of the type of store, data object have either a parent or children but not both. The legacy dojo/data stores use children whereas the new dojo and cbtree stores use a parent property.

      1. (fyi, I think the actual text of my question was in the other comment I left, so the question won’t be easily searchable without that context.)

        As for your questions, I’m using cbtree 0.9.3-3 (the latest listed on the download page) and Dojo 1.8. The data I’m using is static, and after being retrieved will never need to be updated.

        The store I tried using was a Hierarchy store, but to be honest, I’m not sure if that’s right, and was one of the parts of my question I was hoping to figure out – if there’s an existing store that can read my data as it already exists (without needing to create a new object with parent references) then I’d probably prefer that.

        Thanks for your help.

        1. Thanks for the additional information. I understand you would like to keep your existing
          objects however, the dojo and/or cbtree store require a certain object structure regardless if
          you are using the legacy dojo/data store or the new dojo/store or cbtree/store.

          Looking at your data objects it looks like you want to have some sort of parent-child
          relationship and, as you stated, the data is static therefore you can use the cbtree
          Hierarchy or ObjectStore store. (the ObjectStore also works with dynamic data).

          In order to maintain the parent-child relationship each object must at least have a
          property identifying its parent, the default property is ‘parent’ but can be configure
          using the models ‘parentProperty’ property. As a result, you data could look like this:

          
          var data = [
          	{id: 11, parent: 123, ... },
          	{id: 12, parent: 123 },
          	{id: 10010, parent: 123 },
          	{id: 11000, parent: 11 },
          	{id: 122, parent: 124 },
          	{id: 123, parent: 124 }
          	{id: 124 }
          ];
          

          Make sure, all id’s are unique. Also, if you need to keep the ‘parent_children’ and/or
          ‘child_children’ property I would recommend to pick a generic property name like ‘children’
          simply because children of a parent and children of a child (grandchildren) are both children.

          If an object has multiple parents (like in a family tree) you can define the parent
          property as an array, for example:

          
          	{id: 122, parent: [123, 124], ... }
          

          I would highly recommend to adopt a object structure as list above as that is the way
          forward with the dojo and cbtree stores. Please take a look at the example at
          https://github.com/pjekel/cbtree/blob/master/demos/store/tree00.html

          If you really can’t modify your object layout because of other constraints there still
          is the option of data handlers. However, it requires some in depth knowledge of dojo and
          stores in general. For a detailed description of custom data handlers please refer to
          https://github.com/pjekel/cbtree/wiki/Store#data-handlers and
          https://github.com/pjekel/cbtree/wiki/Data-Handlers

  19. Thanks for adding the TreeOnSubmit extension. Is there a way to get the same JSON encoded array for checked items (including those that are collapsed) when sending the data as a dojo xhr (AJAX) request?

      1. Alternatively, you could use the model extension StoreMolde-EXT.js and call the fetchItemsWithChecked(). However, that function returns and array of all matching store objects, not the summary array used in the TreeOnSubmit extension.

        
        model.fetchItemsWithChecked({checked: ["mixed", true]}, function (results) {
           var encoded = JSON.stringify(results);
                    ...
        });
        

        Just a thought.

          1. Dave, just as an FYI:

            The next version of the cbtree will get a new model method called getItems(). The reason for this is that the current TreeOnSubmit extension violates the MVC pattern. There are cbtree users who provide their own model without using a store. So, go forward, instead of calling fetchItemsWithChecked() you will be able to do something like:

            
            when (model.getItems({checked: ["mixed", true]), function (items) {
                var encoded = JSON.stringify(items.slice());
            	                 ...
            });
            

            I have already updated the github branch cbtree-v0.9.5 to reflect the aforementioned changes.

  20. Hi,

    I am using cbtree version 0.9.4, dojo version 1.9. The cbree works fine in other browsers but does not work in IE version 8 on Windows XP. It throws the following error on Console.

    description “Object doesn’t support this property or method”
    info “Object doesn’t support this property or method”
    message “Object doesn’t support this property or method”
    name “TypeError”
    number -2146827850

    The above error doesn’t get displayed in other browsers. I have briefly tested dojo 1.9 and other widgets on IE 1.8 they work fine but when creating cbtree tree widget, the browser gets this error. The tree displays but the event’s on the tree do not get called and all the javascript breaks after the tree creation statement ( var tree = new Tree … ) .

    I load dojo as follows

    @import “$!{relHrefPrefix}ext/default/dojo-toolkit/dijit/themes/claro/claro.css”;
    @import “$!{relHrefPrefix}ext/default/dojo-toolkit/cbtree/themes/claro/claro.css”;
    @import “$!{relHrefPrefix}ext/default/dojo-toolkit/dijit/themes/tundra/tundra.css”;
    @import “$!{relHrefPrefix}ext/default/dojo-toolkit/cbtree/themes/tundra/tundra.css”;

    var dojoConfig = {
    async: true,
    //parseOnLoad: true,
    parseOnLoad: false,
    isDebug: true,
    baseUrl: “$!{relHrefPrefix}ext/default/dojo-toolkit/”,
    // baseUrl: “ext/default/dojo-toolkit/”,
    packages: [
    { name: “dojo”, location: “dojo” },
    { name: “dijit”, location: “dijit” },
    { name: “cbtree”,location: “cbtree” },
    { name: “dojox”, location: “dojox” }
    ]
    };

    My webpage using the cbtree contains the following:

    require([
    “dojo/fx/Toggler”,
    “dojo/parser”,
    “dojo/dom”,
    “dijit/form/Button”,
    “dojo/on”,
    “dojo/ready”,
    “dojo/store/Observable”,
    “cbtree/Tree”, // Checkbox tree
    “cbtree/model/TreeStoreModel”, // ObjectStoreModel
    // “cbtree/model/ObjectStoreModel”, // ObjectStoreModel
    “cbtree/store/Hierarchy” // Object Store with hierarchy
    ], function( Toggler, parser, dom, Button, on, ready, Observable, Tree, ObjectStoreModel, ObjectStore) {

    var regionData = $allRegionsJSONString;

    var store = Observable( new ObjectStore( { data: regionData, idProperty:”region_id” }) );
    var model2 = new ObjectStoreModel( { store: store,
    query: {name: “International”},
    rootLabel: “International”,
    enabledAttr: “enabled”,
    checkedAttr: “checked”,
    multiState: false,
    // checkedStrict: “inherit”, //inherit try
    //checkedStrict: “inherit” ,
    checkedStrict: false,
    checkedRoot: true
    // , options: {sort: mySortFunc}
    });
    function testAlert() {
    alert(“hello world”);

    }

    var testAlert2 = function() {
    alert(” hello world 2″);
    }
    dojo.setObject(‘testAlert2’, testAlert2);

    ready(function(){

    var tree = new Tree( { model: model2,
    id: “CheckboxTree”,
    checkBoxes: true, // nodeIcons: false,
    branchIcons: false,
    openOnChecked: true, closeOnUnchecked: false, leafIcons:false,
    attachToForm: {name:”checkedRegions”, checked: true }
    }, “CheckboxTree” );

    tree.on(“checkBoxClick”, testAlert2);
    // tree.on(“checkBoxClick”, checkBoxClicked);
    tree.startup();

    alert(“end alert”);
    });

    });

    The variable regionData holds the json data and $allRegionsJSONString gets expanded to the following.

    var regionData = [{“region_id”:”14″,”name”:”Southland”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”6″,”name”:”Chatham Islands”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”1″,”name”:”International”,”checked”:false,”enabled”:true,”parent”:”20″},{“region_id”:”7″,”name”:”Gisborne”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”17″,”name”:”Waikato”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”15″,”name”:”Taranaki”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”8″,”name”:”Hawke’s Bay”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”2″,”name”:”New Zealand”,”checked”:false,”enabled”:true,”parent”:”1″},{“region_id”:”3″,”name”:”Auckland”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”5″,”name”:”Canterbury”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”10″,”name”:”Marlborough”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”16″,”name”:”Tasman”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”4″,”name”:”Bay of Plenty”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”13″,”name”:”Otago”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”9″,”name”:”Manawatu-Wanganui”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”18″,”name”:”Wellington”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”12″,”name”:”Northland”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”11″,”name”:”Nelson”,”checked”:false,”enabled”:true,”parent”:”2″},{“region_id”:”19″,”name”:”West Coast”,”checked”:false,”enabled”:true,”parent”:”2″}];

    I need my application to support IE 8, so any help provided would be greatly appreciated.

    Thanks,
    Waqas

    1. Waqas,

      As much as I would like to help you here, it is impossible for me to test any deployment on Windows XP. I haven’t had
      a XP platform for the last 7 years. However, I took your example and ran it on Windows Vista/7/8 with IE 7/8/9/10 and 11 without any problems. One of the issues is that the older IE implementations will throw exceptions but the information presented is completely useless. (e.g. “Object doesn’t support this property or method”, what object? what method?)

      If you can pinpoint the specific module, object and/or method that’s throwing the exception I’m more then happy to fix it. However, that may take some serious debugging.

      I’m sure you have legitimate reasons why you are still on Windows XP but just as a warning, Microsoft will drop all support on Windows XP starting in April 2014:

      http://www.microsoft.com/en-us/windows/enterprise/endofsupport.aspx

      I’m sure they will have a big going away party 🙂

    2. Hi,

      Thanks for your response to my message. I really like this checkbox tree extension as it makes it very easy to setup a Dojo tree with checkboxes and I am using it in a number of places in my application.

      I made a new Windows Vista installation and installed IE 8 on it, and found the same error. Again on other browsers it works. I added the following try catch block to get more info. Unfortunately IE does not provide with a line number in console or stacktrace.

      try
      {
      var tree = new Tree( { model: model2,
      id: “CheckboxTree”,
      checkBoxes: true, // nodeIcons: false,
      branchIcons: false,
      openOnChecked: true, closeOnUnchecked: false, leafIcons:false,
      attachToForm: {name:”checkedRegions”, checked: true }
      }, “CheckboxTree” );
      } catch(err){
      txt=”There was an error on this page.nn”;
      txt+=”Error description: ” + err.message + “nn”;
      txt+=”Click OK to continue.nn”;
      alert(txt);
      }

      Console Details are:
      description “‘undefined’ is null or not an object”
      info “‘undefined’ is null or not an object”
      message “‘undefined’ is null or not an object”
      name “TypeError”
      number -2146823281

      It is my customer’s business requirement that the application runs on IE including IE8. Wherever IE8 will run, I have to ensure that this application runs there. We are using Dojo because it supports many browsers and Dojo is working on IE8 without problems. There are going to be thousands of users of this application and many will be running old machines with Windows XP and Vista. And I can not get them to upgrade OS or browser.

      Any help you can provide will be greatly appreciated.

      Thanks,
      Waqas

      1. Waqas

        I ran your example again on a Windows Vista platform with IE8 however, I can’t reproduce the error you are reporting. Your console output indicates that ‘undefined’ is null or not an object. This is strange as ‘undefined’ is a JavaScript base type UNLESS you specifically re-declare ‘undefined’ as something else. Keep in mind ES3 engines (including IE8) allow you to redefine ‘undefined’ whereas ES5 engines silently prevent assigning a new value to ‘undefined’. This may be the reason why you don’t have issues with other browsers (e.g. Chrome, FF, Safari).

        BTW: redefining JavaScript base types is a really bad practice.

        Scan your code and see if ‘undefined’ is re-declared anywhere (including any other libraries you use). If that’s not the case, find the references to ‘undefined’ in the cbtree code and set breakpoints to determine which statement exactly throws the exception.

        Another simple test you can try at the start of your code is:

        console.log(typeof undefined);

        This should return the string “undefined”

        1. Hi,
          Thanks for these suggestion. I included the ‘undefined’ to log and have removed everything from my source. The only includes are now dojo and cbtree files. I have also included stacktrace.js to get more info on the error. The src has now :

          console.log(“undefined is ” + typeof undefined);

          try
          {
          var tree = new Tree( { model: model2,
          id: “CheckboxTree”,
          checkBoxes: true, // nodeIcons: false,
          branchIcons: false,
          openOnChecked: true, closeOnUnchecked: false, leafIcons:false,
          attachToForm: {name:”checkedRegions”, checked: true }
          }, “CheckboxTree” );
          } catch(err){

          txt=”There was an error on this page.nn”;
          txt+=”Error description: ” + err.message + “nn”;
          txt+=”Click OK to continue.nn”;
          alert(txt);
          var trace = printStackTrace();
          alert(trace.join(‘nn’));
          console.log(” trace is ” + trace);
          console.log(” Error is ” + err.message);

          }

          This gives me the following in IE 8:
          LOG: undefined is undefined
          LOG: trace is {anonymous}(),printStackTrace(),{anonymous}(),{anonymous}(),{anonymous}(),{anonymous}(#function),{anonymous}([#function],#function),{anonymous}(“idle”,[]),{anonymous}(#function),{anonymous}()
          LOG: Error is Object doesn’t support this property or method

          Waqas

          1. Waqas,

            I’m sure you would agree that the ‘stack’ trace is completely useless. As I said before I can’t reproduce the error, you need to do some debugging yourself.

            First, start debugging the most basic tree disabling all options and features as in:

            var tree = new Tree({model: model2, checkBoxes: false});

            If that works, start adding each required feature one by one.

  21. Hi Thanks for cbtree library. I am able to build tree with icons. However I am not able to get value of any key/value. For eg, I have var dataSet = [ {name:’Clement’, age:’45’, height:”165″}, {name:’Ellen’, age:’40’, height:”160″} ];. I know that I am able to get age by “tree2.mapEventToAttr( null,’age’,’label’, makeLabel );” but I can’t seem to get height by “tree2.mapEventToAttr( null,’height’,’label’, makeLabelHeight );”. How do I do that? Please advise.

    1. Although I’m note sure how icons are related to mapEventToAttr() in your application, the mapEventToAttr() method is only called if the associated item property in the store changes. For example:

      item.height++;
      store.put(item);

      Note that the store.put() call is essential.

      If however, you’d like to change icons based on item property values I suggest you take a look at:

      https://github.com/pjekel/cbtree/wiki/Tree-Styling#wiki-item-property-mapping

      Hope this helps.

  22. Hi Thanks for reply in my previous post.

    Another thing regarding the branch icon.

    How do I collapse and grey out all other branch icons
    whenever I click on the leaf icon?

    Please advise. Thanks in advance

    1. Currently there is no click event associated with icons therefore there is no easy way to tell if the tree node icon was clicked or if the tree node label was clicked. Keep in mind, cbtree is a Checkbox Tree and not an Icon Tree.

  23. Issue 1: I have followed all instruction in Following example. http://www.thejekels.com/blog/dojo/step-2-the-dijit-tree/ Tree for country details is coming fine . But when I click on any node in Dojo Tree as given in http://www.thejekels.com/blog/dojo/step-3-adding-checkboxes-2/ it is showing follwing error :

    Message: ‘nodeName’ is null or not an object Line: 15 Char: 138393 Code: 0 URI: http://{host}:{port}/{context_root}/target/source/js/dojo/dojo.js

    Issue 2 : My actual requirement is to create a Checkbox Tree in Dojo using Lazy loading . I have already checked cbtree example [using FileStore,FileStoreModel]. But I am using Java Servelet instead of PHP . So I am totally confused about [basePath:”.”] .

    var myStore = new dojox.data.JsonRestStore({
    target:””,
    labelAttribute:”name”
    });
    var myModel = new dijit.tree.ForestStoreModel({
    store: myStore,
    rootLabel: ‘ICD-10’, //added
    rootId: “root”, //added
    deferItemLoadingUntilExpand: true,
    query: “”,
    childrenAttrs: [“children”]
    });

    var myTree = new tmpdir.CheckBoxTree({model: myModel,
    id: ‘contextMenu’, showRoot:false,
    onMouseDown:function(ev,node){
    if(ev.button==2){
    var here=dijit.getEnclosingWidget(ev.target);
    this.set(‘selectedNode’,here);
    }
    }

    }, ‘treeElement’);

    Issue 3: I have already created a Tree using dojox.data.JsonRestStore . I want to add checkbox before every node . When I use the following block checkbox is comimg properly only for child nodes . Parent Node checkbox is getting deleted .

    _createTreeNode: function(args) {
    var tnode = new dijit._TreeNode(args);
    // alert(args.label);
    tnode.labelNode.innerHTML = args.label; var cb = new dijit.form.CheckBox();
    cb.placeAt(tnode.labelNode, “first”); dojo.connect(cb, “onChange”, function() {
    treeNode = dijit.getEnclosingWidget(this.domNode.parentNode);
    alert(treeNode.item.name+”==,==”+this.value);
    });
    return tnode;
    },

    Please help . Thanks in advance .

  24. Hi, I am using the following:
    cbtree-v09.4-0 with Dojo 1.9

    Great job on the project, I like it a lot.

    I am stuck. I successfully was able to get the data/tree11.html to work with the cbtreeFileStore.php. I am also able to get the store/tree30.html to work with the attachToForm. My problem is when I try to combine the attachToForm, following the wiki instructions, into my tree30.html example, I don’t get anything from json_decode($_POST[“checkboxes”]);

    Any help would be appreciated. Thanks.
    Steve

    1. The demo’s in the demos/data directory are intended for the use with the legacy dojo/data/store and the associated models in the cbtree/models directory (notice: models (plural)). See also the installation instructions at https://github.com/pjekel/cbtree/wiki/Installation

      The demos in the cbtree/demos/store directory are intended for the newer dojo/store and cbtree/store stores. These demos use the models in cbtree/model directory (model (singular)).

      The attachToForm feature has only been tested with the newer models and stores. If you want to combine examples use cbtree/demos/store/tree30.html and cbtree/demos/store/tree40.html

      Hope this helps.

      1. Thanks for your fast reply. After changing the references from the legacy store to the new, everything worked nicely. Thanks for putting together something that is very useful. I look forward to follow your project.
        Steve

  25. Hello, I have one additional question. I searched your API docs as well as the examples without any luck.

    I am using the FileStore with the back-end cbtreeFileStore.php as you have in the tree40.html. I have the checkBoxClicked event passing in
    checkBoxClicked( item, nodeWidget, event ).

    If I click on a file checkbox represented in the tree, I would like to obtain it’s properties “size” and “directory” initially passed in by cbtreeFileStore.php. I know it is in the store, but I don’t understand what method I need to use to extract the two values. I intend to sum the total byte size of the files that have been selected. The directory click is a little harder. If I click on a directory instead of a file, I need to obtain the total size of the files in the directory that was clicked (sub directories – children don’t matter).

    Thanks for your help. -Steve

    1. Steve,

      You could do something like this:

      
      tree.on("checkBoxClick", function (item, node, event) {
          var treeStore = this.model.store;
          var total = 0;
      
          if (item.directory) {
      	when(treeStore.getChildren(item), function (children) {
      	    children.forEach(function (child) {
      		total = total + child.size;
      	    });
      	    alert("Directory: " + item.name + " size: " + total);
      	});
          } else {
      	alert("File: " + item.name + " size: " + item.size);
          }
      });
      

      Hope this gets you going.

  26. Thank you for the greatest cbtree model. I have been using it in various places as possible.

    One thing, i am still not clear that i can see the Tree Structure inside my DIV but i can’t see any checkboxes. Is there anything special that i would need to do to make checkboxes visible?

    With the same JSON, i can see tree with folder with dijit/tree but as soon as i use cbtree/tree, code breaks.

    Thanks and Regards,
    Shay

  27. That sure did fix the issue with style that you mentioned.

    Another question i had was.

    How to undo recently clicked check boxes? Is there any intercept that i can do to undo just clicked check boxes. Say, if user checks 3 items from Restaurant “Tree” and next they also click on Hospitals “Tree”. I would to intercept here and un-check the checkboxes from Hospitals “Tree” because they don’t match the criteria.

    I looked at onclick event.

    onClick: function (item) {
    choosefield(item, “Test”, tree);
    }

    But check boxes are already checked at this point.

    1. Thanks for the reply. From your use case it is not clear if “Restaurant” and “Hospitals” are two different trees or if they are branches within the same tree. It sounds like they are different trees.

      Assuming you are using the latest version of cbtree (0.9.4) and a model from the cbtree/model directory (notice: /model and not /models (plural)) you could load the model extension cbtree/model/StoreModel-EXT.js which adds additional model methods such as: check and uncheck.

      Both methods take a query argument to select store items to either check or uncheck them. Lets assume your store items have a type property whose value is “hospital” or “restaurant”. With that knowledge you could do something like:

      
          require([
                 ...
              "cbtree/model/StoreModel-EXT"
          ], function ( ... )
      
              function checkBoxClicked(item) {
                  var model   = this.model;
                  var checked = model.getChecked(item);
                  
                  if (checked && item.type == "hospital") {
                     model.uncheck({type: "restaurant"}}
                  }
              }
      
              var tree = new Tree( ... );
      
              tree.on( "checkBoxClick", checkBoxClicked);
          }
      

      To learn more about the query argument, please checkout: https://github.com/pjekel/cbtree/wiki/Query-Engine#the-query-argument

      Hope this gets you going.

  28. Thank you. I believe, i am headed in the right direction with your Extension menthod. Quick question i had was, my store uses dojo.data.ItemFileReadStore and the model i used (as you mentioned) uses cbtree/model/ForestStoreModel. Can cbtree/model/ForestStoreModel would work with dojo/data or it has to be objectstore? When i tried with dojo.data with “dojo.data.ItemFileWriteStore({ store: RestaurantStore });”, it throws an exception.

    Thanks again for the help.
    Shay .

    1. Shay,

      Before you continue please read: https://github.com/pjekel/cbtree/wiki/Installation

      I would highly recommend you start using either the cbtree/store or dojo/store stores. The dojo/data stores have been deprecated since dojo 1.6 and will very likely disappear completely with the release of dojo 2.0 (later this year).

      The cbtree currently supports two sets of models, one set in the cbtree/model directory (model < - singular) the other set in the cbtree/models directory (models < - plural). The models in the cbtree/models directory provide support for the legacy dojo/data stores such as ItemFileReadStore and ItemFileWriteStore

      The models in the cbtree/model directory provide support for the ‘new’ cbtree/store and dojo/store stores. As a result, you can NOT use these models with any of the legacy dojo/data store.

      To migrate to the new stores (cbtree/store and dojo/store) you will need to restructure your JSON data as the new stores use a different format and no longer support data properties like children.

      The alternatives are:

      1 – Try using the dojo/store/DataStore
      2 – Use a cbtree/store with the custom data handler (https://github.com/pjekel/cbtree/blob/master/store/handlers/ifrsHandler.js)

      However, both alternatives are just band-aids.

  29. Thanks for the help. I am able to reference new store and models as you mentioned with cbtree/store and cbtree/model. It worked the magic after i restructure my json. And extension methods are exposed and works great. Thanks again.

    Shay.

  30. Hello –
    Your project has helped me out tremendously. I have the cbtree implemented with forms as presented in the examples with v0.9.4 and the attachToForm property.

    I am using the FileStore with the back-end /cbtree/store/server/PHP/cbtreeFileStore.php provided but modified.

    I modified the file server php function called “fileToStruct”, which sets the fileInfo stdClass with an additional property: $fileInfo->arcPath = $volume;

    Essentially, files can exist across multiple volumes on a server, all within the same path. For example, /Archive1//testdir & /Archive2//testdir. I roll this up to a single representation in cbtree so that a person can view their archive area.

    In the form POST is see below in firebug. I can iterate through by forEach($storeItems as $item)
    checkboxes [{“id”:”./1.pdf”,”value”:”1.pdf”,”checked”:true,”count”:1}]

    My question is:
    How can is pass my additional property $fileInfo->arcPath to the FORM so that I can access it via $storeItems = json_decode($_POST[“checkboxes”]); on the server side. I did verify it is accessible via the client side using alert( item.arcPath ); via checkBoxClicked.

    Thanks for your help and all your great work. I hope I explained things well enough. If not I can try to clarify. –Steve

    1. Steve,

      Thanks for the post. To pass additional item properties to the server is actually fairly simple, first locate the file cbtree/extensions/TreeOnSubmit.js. Near the top you’ll find the function getSummary(), what you need to do is extend the code fragment:

      
      results = results.map(function (item) {
          return {
              id: store.getIdentity(item),
              value: model.getLabel(item),
              checked: (attr ? (item[attr] || model.checkedState) : undefined)
          };
      });
      

      to read something like:

      
      results = results.map(function (item) {
          return {
              id: store.getIdentity(item),
              value: model.getLabel(item),
              volume: item.arcPath,
              checked: (attr ? (item[attr] || model.checkedState) : undefined)
          };
      });
      

      That’s all there is to it.

      Hope this helps.

  31. Hello, I got it. I apologize for clogging up your blog area. The issue was related the browser cache. Although I was hitting a F5 reload, the TreeOnSubmit.js was still cached, which I was able to catch within firebug. Thanks again for all your great work and help. -Steve

  32. Hello, my name is Nerijus

    i need little bit help, i don’t understand how i can do the parent and shild relationship, example, if i checked parent i want all children would be checked, how can i do that?

      1. Thanks i see this and i do same as in example, but still don’t work for me, if i checked parent the children’s doesn’t checked. here is my code, meaby you can help me little bit:
        require([“cbtree/Tree”,
        “cbtree/store/Hierarchy”,
        “cbtree/model/ForestStoreModel”,
        “dojo/domReady”
        ], function (Tree, Hierarchy, ForestStoreModel, domReady) {
        var data =
        [
        { id: ‘1’, description: “Deklaravimo bazė”, parent: null },
        { id: ‘2’, description: ‘2014 metų duomenys ‘, parent: ‘1’, checked: false },
        { id: ’21’, description: ‘KŽS ribos ir Nr.’, parent: ‘2’, checked: false },
        { id: ’22’, description: ‘KŽS ribos’, parent: ‘2’, checked: false },
        { id: ’23’, description: ‘Netinkami plotai’, parent: ‘2’, checked: false },
        { id: ’24’, description: ‘Maži plotai’, parent: ‘2’, checked: false },
        { id: ‘4’, description: ‘2013 metų duomenys ‘, parent: ‘1’, checked: false },
        { id: ’41’, description: ‘KŽS ribos ir Nr.’, parent: ‘4’, checked: false },
        { id: ’42’, description: ‘KŽS ribos’, parent: ‘4’, checked: false },
        { id: ’43’, description: ‘Netinkami plotai’, parent: ‘4’, checked: false },
        { id: ’44’, description: ‘Maži plotai’, parent: ‘4’, checked: false },
        { id: ‘6’, description: ‘2012 metų duomenys ‘, parent: ‘1’, checked: false },
        { id: ’61’, description: ‘KŽS ribos ir Nr.’, parent: ‘6’, checked: false },
        { id: ’62’, description: ‘KŽS ribos’, parent: ‘6’, checked: false },
        { id: ’63’, description: ‘Netinkami plotai’, parent: ‘6’, checked: false },
        { id: ’64’, description: ‘Maži plotai’, parent: ‘6’, checked: false },
        { id: ‘8’, description: ‘2011 metų duomenys ‘, parent: ‘1’, checked: false },
        { id: ’81’, description: ‘KŽS ribos ir Nr.’, parent: ‘8’, checked: false },
        { id: ’82’, description: ‘KŽS ribos’, parent: ‘8’, checked: false },
        { id: ’83’, description: ‘Netinkami plotai’, parent: ‘8’, checked: false },
        { id: ’84’, description: ‘Maži plotai’, parent: ‘8’, checked: false },
        {id: ‘1111’, description: “Redagavimo bazė”, parent:null},
        { id: ‘2222’, description: ‘2014 metų duomenys ‘, parent: ‘1111’, checked: false },
        { id: ‘221’, description: ‘KŽS ribos ir Nr.’, parent: ‘2222’, checked: false },
        { id: ‘222’, description: ‘KŽS ribos’, parent: ‘2222’, checked: false },
        { id: ‘223’, description: ‘Netinkami plotai’, parent: ‘2222’, checked: false },
        { id: ‘224’, description: ‘Maži plotai’, parent: ‘2222’, checked: false },
        { id: ‘4444’, description: ‘2013 metų duomenys ‘, parent: ‘1111’, checked: false },
        { id: ‘441’, description: ‘KŽS ribos ir Nr.’, parent: ‘4444’, checked: false },
        { id: ‘442’, description: ‘KŽS ribos’, parent: ‘4444’, checked: false },
        { id: ‘443’, description: ‘Netinkami plotai’, parent: ‘4444’, checked: false },
        { id: ‘444’, description: ‘Maži plotai’, parent: ‘4444’, checked: false },
        { id: ‘6666’, description: ‘2012 metų duomenys ‘, parent: ‘1111’, checked: false },
        { id: ‘661’, description: ‘KŽS ribos ir Nr.’, parent: ‘6666’, checked: false },
        { id: ‘662’, description: ‘KŽS ribos’, parent: ‘6666’, checked: false },
        { id: ‘663’, description: ‘Netinkami plotai’, parent: ‘6666’, checked: false },
        { id: ‘664’, description: ‘Maži plotai’, parent: ‘6666’, checked: false },
        { id: ‘8888’, description: ‘2011 metų duomenys ‘, parent: ‘1111’, checked: false },
        { id: ‘881’, description: ‘KŽS ribos ir Nr.’, parent: ‘8888’, checked: false },
        { id: ‘882’, description: ‘KŽS ribos’, parent: ‘8888’, checked: false },
        { id: ‘883’, description: ‘Netinkami plotai’, parent: ‘8888’, checked: false },
        { id: ‘884’, description: ‘Maži plotai’, parent: ‘8888’, checked: false }

        ];

        var store = new Hierarchy({ data: data, idProperty: ‘id’,multiParented:false});
        var model = new ForestStoreModel({
        store: store,
        query: { id: [‘1′,’1111’]},
        rootLabel: ‘KŽS Sluoksniai’,
        labelAttr: ‘description’,
        checkedAll: false

        });

        var tree = new Tree({
        model: model,
        branchIcons: false,
        nodeIcons: false,
        leafIcons: false,

        });

        domReady(function () {

        tree.placeAt(“CheckboxTree”);
        tree.startup();
        });

        });
        thanks a lot 🙂

        1. Interesting, I ran your code and it works fine for me. What dojo and cbtree version are you using? What OS are you running on?
          Make sure you load the correct cbtree css file. For example, if the dijit theme you are using is ‘claro’ you MUST load ‘cbtree/themes/claro/claro.css’

  33. Hi Peter,
    We have been using your package cbtree in our web-based application with Arcgis. Arcgis released new version of Javascript API which uses dojo version 1.10. This release resolved one of our problems but the cbtree-0.9.4 is not working with dojo 1.10.
    Could you please let me know if there will be next cbtree release working with dojo 1.10?

    Thank you.

    1. cbtree 0.9.4 has been fully tested with dojo 1.10 and works fine. However, ArcGIS 3.11 has changed their URL’s please see: https://developers.arcgis.com/javascript/jshelp/whats_new.html

      For example: Old ArcGIS

      
      <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/claro.css">
      <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/esri/css/esri.css">
                                             ...
      <script type="text/javascript" src="http://js.arcgis.com/3.7/">
      

      ArcGIS 3.11

      
      <link rel="stylesheet" href="http://js.arcgis.com/3.11/dijit/themes/claro/claro.css">
      <link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
      
      <script type="text/javascript" src="http://js.arcgis.com/3.11/">
      

Leave a Reply

Your email address will not be published. Required fields are marked *