title: Dojo Widget Templates
body: <p>With reference to <a href="https://stackoverflow.com/questions/10984855/simple-login-implementation-for-dojo-mvc">Simple Login implementation for Dojo MVC</a> / - there is one point i don't understand. With regards to sample from phusick, the login dialog class does a call of dom.byId(&quot;dialog-template&quot;) - &quot;dialog-template&quot; is an id from the script which is the template for the dialog and should be present in an html template - not in the main html. So if I remove that, the call to dom.byId would fail</p>
  <p>so my code structure is as follows</p>
  <p>main.html ( calls Only main.js is called - nothing more)
  main.js ( Contains the following)</p>
  <pre><code>    require([
  &quot;dojo/_base/declare&quot;,&quot;dojo/_base/lang&quot;,&quot;dojo/on&quot;,&quot;dojo/dom&quot;,&quot;dojo/Evented&quot;,
  &quot;dojo/_base/Deferred&quot;,&quot;dojo/json&quot;,&quot;dijit/_Widget&quot;,&quot;dijit/_TemplatedMixin&quot;,
  &quot;dijit/_WidgetsInTemplateMixin&quot;,&quot;dijit/Dialog&quot;,
  &quot;widgets/LoginDialog&quot;,
  &quot;widgets/LoginController&quot;,
  &quot;dijit/form/Form&quot;,&quot;dijit/form/ValidationTextBox&quot;,&quot;dijit/form/Button&quot;,
  
  &quot;dojo/domReady!&quot;
  ], function(
  declare,lang,on,dom,Evented,Deferred,JSON,  
  _Widget,
  _TemplatedMixin,
  _WidgetsInTemplateMixin,
      
   Dialog,
   LoginDialog,
   LoginController
  ) {
  // provide username &amp; password in constructor
  // since we do not have web service here to authenticate against    
  var loginController = new LoginController({username: &quot;user&quot;, password: &quot;user&quot;});
  
  var loginDialog = new LoginDialog({ controller: loginController});
  loginDialog.startup();
  loginDialog.show();
  
  loginDialog.on(&quot;cancel&quot;, function() {
      console.log(&quot;Login cancelled.&quot;);        
  });
  
  loginDialog.on(&quot;error&quot;, function() {
      console.log(&quot;Login error.&quot;);
  });
  
  loginDialog.on(&quot;success&quot;, function() {
      console.log(&quot;Login success.&quot;);
      console.log(JSON.stringify(this.form.get(&quot;value&quot;)));
  });
  
    
  });
  </code></pre>
  <p>Now LoginDialog.js and LoginDialogTemplate.html is the templatised widget for the dialog
  and LoginController.js is the controller.</p>
  <p>My LoginDialog.js is</p>
  <pre><code>define([
  &quot;dojo/_base/declare&quot;,&quot;dojo/_base/lang&quot;,&quot;dojo/on&quot;,&quot;dojo/dom&quot;,&quot;dojo/Evented&quot;,&quot;dojo/_base/Deferred&quot;,&quot;dojo/json&quot;,
  
  &quot;dijit/_Widget&quot;,&quot;dijit/_TemplatedMixin&quot;,&quot;dijit/_WidgetsInTemplateMixin&quot;,
  &quot;dijit/Dialog&quot;,&quot;dijit/form/Form&quot;,&quot;dijit/form/ValidationTextBox&quot;,&quot;dijit/form/Button&quot;,
  &quot;dojo/text!templates/loginDialogTemplate.html&quot;,
  &quot;dojo/text!templates/loginFormTemplate.html&quot;,
  
  &quot;dojo/domReady!&quot;
  ], function(
  declare,lang,on,dom,Evented,Deferred,JSON,
  _Widget,
  _TemplatedMixin,
  _WidgetsInTemplateMixin,
  Dialog,
  Form,
  Button,
  template
  
  ) {
  
  return declare([ Dialog, Evented], {
      
      READY: 0,
      BUSY: 1,
      
      title: &quot;Login Dialog&quot;,
      message: &quot;&quot;,
      busyLabel: &quot;Working...&quot;,
      
      // Binding property values to DOM nodes in templates
      // see: http://www.enterprisedojo.com/2010/10/02/lessons-in-widgetry-binding-property-values-to-dom-nodes-in-templates/
      attributeMap: lang.delegate(dijit._Widget.prototype.attributeMap, {
          message: {
              node: &quot;messageNode&quot;,
              type: &quot;innerHTML&quot;               
          }            
      }),
      
      constructor: function(/*Object*/ kwArgs) {
          lang.mixin(this, kwArgs);            
          var dialogTemplate = dom.byId(&quot;dialog-template&quot;).textContent;
          var formTemplate = dom.byId(&quot;login-form-template&quot;).textContent;
          var template = lang.replace(dialogTemplate, {
              form: formTemplate                
          });
  
          var contentWidget = new (declare(
              [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],
              {
                  templateString: template                   
              }
          ));
          contentWidget.startup();
          var content = this.content = contentWidget;
          this.form = content.form;
          // shortcuts
          this.submitButton = content.submitButton;
          this.cancelButton = content.cancelButton;
          this.messageNode = content.messageNode;
      },
      
      postCreate: function() {
          this.inherited(arguments);
          
          this.readyState= this.READY;
          this.okLabel = this.submitButton.get(&quot;label&quot;);
          
          this.connect(this.submitButton, &quot;onClick&quot;, &quot;onSubmit&quot;);
          this.connect(this.cancelButton, &quot;onClick&quot;, &quot;onCancel&quot;);
          
          this.watch(&quot;readyState&quot;, lang.hitch(this, &quot;_onReadyStateChange&quot;));
          
          this.form.watch(&quot;state&quot;, lang.hitch(this, &quot;_onValidStateChange&quot;));
          this._onValidStateChange();
      },
      
      onSubmit: function() {
          this.set(&quot;readyState&quot;, this.BUSY);
          this.set(&quot;message&quot;, &quot;&quot;);
          var data = this.form.get(&quot;value&quot;);
          
          var auth = this.controller.login(data);
          
          Deferred.when(auth, lang.hitch(this, function(loginSuccess) {
              if (loginSuccess === true) {
                  this.onLoginSuccess();
                  return;                    
              }
              this.onLoginError();
          }));
      },
          
      onLoginSuccess: function() {
          this.set(&quot;readyState&quot;, this.READY);
          this.set(&quot;message&quot;, &quot;Login sucessful.&quot;);             
          this.emit(&quot;success&quot;);
      },
      
      onLoginError: function() {
          this.set(&quot;readyState&quot;, this.READY);
          this.set(&quot;message&quot;, &quot;Please try again.&quot;);
          this.emit(&quot;error&quot;);         
      },
      
      onCancel: function() {
         this.emit(&quot;cancel&quot;);     
      },
  
      _onValidStateChange: function() {
          this.submitButton.set(&quot;disabled&quot;, !!this.form.get(&quot;state&quot;).length);
      },
  
      _onReadyStateChange: function() {
          var isBusy = this.get(&quot;readyState&quot;) == this.BUSY;
          this.submitButton.set(&quot;label&quot;, isBusy ? this.busyLabel : this.okLabel);
          this.submitButton.set(&quot;disabled&quot;, isBusy);
      }            
  });
  });
  </code></pre>
  <p>My loginDialogTemplate.html is as follows</p>
  <pre><code>&lt;script type=&quot;text/template&quot; id=&quot;dialog-template&quot;&gt;
  &lt;div style=&quot;width:300px;&quot;&gt;
    
      &lt;div class=&quot;dijitDialogPaneContentArea&quot;&gt;
          &lt;div data-dojo-attach-point=&quot;contentNode&quot;&gt;
              {form}              
          &lt;/div&gt;
      &lt;/div&gt;
  
      &lt;div class=&quot;dijitDialogPaneActionBar&quot;&gt;
          &lt;div
              class=&quot;message&quot;
              data-dojo-attach-point=&quot;messageNode&quot;                
          &gt;&lt;/div&gt;      
          &lt;button
              data-dojo-type=&quot;dijit.form.Button&quot;
              data-dojo-props=&quot;&quot;                
              data-dojo-attach-point=&quot;submitButton&quot;
          &gt;
              OK
          &lt;/button&gt;
          
          &lt;button
              data-dojo-type=&quot;dijit.form.Button&quot;
              data-dojo-attach-point=&quot;cancelButton&quot;
          &gt;
              Cancel
          &lt;/button&gt;
      &lt;/div&gt;      
  &lt;/div&gt;
  &lt;/script&gt;
  </code></pre>
  <p>Since the template has the id=&quot;dialog-template&quot; so I guess when the widget calls the dom.byId(&quot;dialog-template&quot;), it throws an error &quot;TypeError: dom.byId(...) is null&quot; at the line :-&gt; var dialogTemplate = dom.byId(&quot;dialog-template&quot;).textContent;</p>
  <p>So what am I doing wrong here?</p>
  <p>If i use all the template scripts in the main html it works fine.</p>