Search code examples
javascriptdojo

Tried to register widget with id but that id is already registered


I have two buttons and would like to load a different custom template widget into a div depending on which button is pressed. It works fine the first click, but then comes up with the subject error when either of the buttons is clicked again. I've got this very simplified example to try and get the concept working

my template code (there are two very similar to this):

define([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
  "dijit/_TemplatedMixin",
  "dojo/text!Templates/Person.htm"
], function (declare, _WidgetBase, _TemplatedMixin, personTpl) {
    return declare([_WidgetBase, _TemplatedMixin], {
        templateString: personTpl
    });
});

my template (there are two very similar to this):

<div>
  <p>Bob Jones</p>
</div>

Main page:

 <body class="claro">

    <script>
        require([
        "dijit/form/Button", 
        "Templates/Person", "Templates/Person2", "dojo/domReady!"
     ], function (Button, Person, Person2) {
         var Button1 = new Button({
             label: "Person1",
             onClick: function () {
                 var p = new Person({}, "page");//error occurs here after a button has been pressed once
             }
         }, "btnPerson1").startup();

         var Button2 = new Button({
             label: "Person2",
             onClick: function () {
                 var p2 = new Person2({}, "page"); //error occurs here after a button has been pressed once
             }
         }, "btnPerson2").startup();
     });
    </script>
    <button id="btnPerson1" type="button"></button>
    <button id="btnPerson2" type="button"></button>
    <div id="page"></div>
  </body>

Thanks for any ideas


Solution

  • Hey I took your code and I created a jsfiddle test and now I realized what is your problem.

    If I understood correctly you are getting in trouble just when creating the second object and the other ones. For the first widget I believe you are ok.

    So, the reason that the first object is ok is because the dojo creates the widget using your id and they have something named widgetid. The widgetid is put in a list and it is just removed from there if you call the destroy method of the widget; however, when you call the destroy method of your widget it will destroy the node. Here is the jsfiddle link that fixes your problem, please let me know if I understood correctly.

    http://jsfiddle.net/cyeddpe5/26/

    define("Person",[
      "dojo/_base/declare",
      "dijit/_WidgetBase",
      "dijit/_TemplatedMixin",  
    ], function (declare, _WidgetBase, _TemplatedMixin, personTpl) {
        return declare([_WidgetBase, _TemplatedMixin], {
            templateString: "<div><p>Bob Jones</p></div>"
        });
    });
         require([
            "dijit/form/Button", 
            "Person", "dojo/domReady!"
         ], function (Button, Person) {
             var Button1 = new Button({
                 label: "Person1",
                 onClick: function () {
                     //Here is the trick
                     if(window.p)
                     {
                         window.p.destroy(false);
                         var page = document.createElement("div");
                         dojo.body().appendChild(page);
                         page.setAttribute("id","page");
                     }
    
                     window.p = new Person({}, "page");//error occurs here after a button has been pressed once
                 }
             }, "btnPerson1").startup();
         });
    

    I do not like to use id in a div to create my widgets, instead of this I normally use a reference to the widget, but it is up to you. Remember to destroy the widget and recreate the node. I am quite sure that there is a way to destroy the widget keeping the node alive, but I did not have time to find it. Sorry.