Emjiz
Emjiz

Reputation: 19

How to attach an event listener to dynamically added widget content in Dojo toolkit

I'm using laravel and dojo, so forms are generated by the server and are requested via ajax meaning there is no loading of the entire page, I want to assign an even listener on the submit button of the dynamically added content, with jquery I could simply do this on dom ready:

$('body').on('click','element',function(){//something});

But I have no clue how to do the same on Dojo, I can only assign event listeners to nodes that are already loaded on the page, and for widgets I use registry.byId('element').on('click',function(){//something})

And the documentation on dojo doesn't help at all

The HTML is generated by laravel then sent back as an ajax response it looks like this:

`{{Form::open(array('class'=>'rm-form','id'=>'rm-form','files'=>true))}}
<h3>Capture Raw Material</h3>
    <div class="form-group">
    <label for='mpo'>Enter MPO:</label>
        <input data-dojo-type="dijit/form/TextBox" data-dojo-props='required:1' value='{{Input::old('mpo')}}' type="text" id='mpo' name='mpo' placeholder='Enter MPO Number' required />
            @if($errors->has("mpo"))
                <span class="invalid">{{$errors->first('mpo')}}</span>
            @endif
    </div>
   <div class="form-group">
    <label for='rm-width'>Enter Width:</label>
        <input id="rm-width" type="text" data-dojo-type="dijit/form/NumberTextBox" value='{{Input::old('rm-width')}}' name= "rm-width"  placeholder='Enter Width' constraints="{pattern: '0.######'}" required="true" />
        @if($errors->has("rm-width"))
                <span class="invalid">{{$errors->first('rm-width')}}</span>
            @endif
    </div>
   <div class="form-group">
    <label for='rm-weight'>Enter Weight:</label>
        <input id="rm-weight" type="text" data-dojo-type="dijit/form/NumberTextBox" name= "rm-weight" value='{{Input::old('rm-weight')}}' placeholder='Enter Width' constraints="{pattern: '0.######'}" required="true" />
        @if($errors->has("rm-weight"))
                <span class="invalid">{{$errors->first('rm-weight')}}</span>
            @endif
    </div>


    <div class="form-group">
    <label for='blanks'>Enter Estimated blanks:</label>
        <input id="estimated-blanks" type="text" data-dojo-type="dijit/form/NumberTextBox" name= "estimated-blanks" value='{{Input::old('estimated-blanks')}}' placeholder='Enter Enter Estimated Blank' }"
required="true" />
            @if($errors->has("estimated-blanks"))
                <span class="invalid">{{$errors->first('estimated-blanks')}}</span>
            @endif
    </div>
    <div class="form-group">
    <label for='grade'>Grades</label>
        <select name="grade" id='grade' data-dojo-type="dijit/form/Select">
            @foreach($grades as $grade)
            <option value='{{$grade}}' {{$grade==Input::old('grade')?'checked':''}}>{{$grade}}</option>
            @endforeach
        </select>
    </div>
     <div class="form-group">
    <label for='grades'>Date</label>
        <input type='date' name="text" id='date' data-dojo-type="dijit/form/DateTextBox" constraints="datePattern: 'dd-MM-yyyy'" value='{{Input::old('date')}}'  />
          @if($errors->has("date"))
                <span class="invalid">{{$errors->first('date')}}</span>
            @endif 
    </div>

    <div class="form-group">
        <label for='grades'>Notes</label>
            <textarea name="notes" id='notes' data-dojo-type="dijit/form/Textarea"  >
                {{Input::old('notes')}}
            </textarea>
           @if($errors->has("notes"))
                <span class="invalid">{{$errors->first('notes')}}</span>
            @endif
    </div>
        <div class="form-group">
        <div class="form-group">
        <input type='file' id='file' name='file'/>
        </div>
        </div>
    <div class="form-group">
    <button id="save-rm" type='button' data-dojo-type="dijit/form/Button" >
        Create
    </button>
    </div>{{Form::close()}}`

And this is how I put it on DOM

function rmrespnse(data) { require(['dijit/registry',"dijit/layout/ContentPane","dojo/domReady!"], function(registry,ContentPane){ var cp = registry.byId('rm-body'); cp.set('content',data); });}

Upvotes: 1

Views: 1500

Answers (1)

frank
frank

Reputation: 3330

I do not have knowledge about the backend (laravel). I will anyway try to do some guess work. Hopefully it will help you to make further inroads to help you solve your issue.

I am assuming that the laravel code that you have posted returns a HTML fragment and the data type is text/string as the response to the AJAX call.
HTML Fragment: It is the piece of text/code that does not contain the head and the body tag. e.g <div> <form> ...additional element tag.. </form></div>

You can check the output of the Ajax response to confirm the type of data it return as follows.

function rmrespnse(data)
{
   console.log("Ajax Response:", data);
   ...other statements...
}

After getting the response from Ajax ( assuming it returns HTML text), we need to Parse the HTML text(response data) into DOM Nodes and Dojo Widgets and place it in the Document for rendering.
Lets assume for the sake of simplicity that your Main HTML page is something like below and is already rendered on the browser.

</html>
   <head>
   </head>
   <body>
     /* The div element where we will be placing the Response data
        recieved from Ajax.*/
     <div id="container">
     </div>
   </body>
</html>

You rmrespnse() call would look something like this.

function rmrespnse(data)
{

  /* Check the Ajax response */
  console.log("Ajax Response:", data);

  /* Process the response data */
  require([
    'dojo/parser', 'dojo/dom', 'dojo/on'
  ], function (parser, dom, on) {
    /* 
      find the container node where we would be placing the Ajax content 
    */
    var containerNode = dom.byId('container');

    /* 
       Place the Ajax content (response).
       This will convert the raw HTML text to DomNodes. 
     */
    containerNode.innerHTML = data;

    /* 
       Now we need to parse the domNodes to convert them into Dojo Widgets.
       The Dojo widgets which will be instantiated will be now available 
       to use in the then() function call as shown below
    */
    parser.parse(containerNode).then(function () {
      /* Attach an eventHandler to the click event of the saver-rm button */
      on('save-rm', 'click', function () {
        // custom save code
      });
    });
  });
};

some links for your reference.
Dojo Parser
Parser Examples

Upvotes: 0

Related Questions