Dojo - dojo.byId () over ajax response

I am using Dojo support for Ajax

function handleSubmit(evt, targetUrl, submitForm, updateDiv) {
            dojo.stopEvent(evt);
            dojo.xhrPost( {
                url: targetUrl,
                handleAs: "text",
                load: function(response){
                    updateDiv.innerHTML = response;
                    wireEvents();
                    return response;
                    },
                form: submitForm,
                error: function(response, ioArgs) { 
                    console.error("HTTP status code: ", ioArgs.xhr.status); 
                    return response; 
                }               
            });
        }

      

The response from the server contains more data than I need. I would like to be able to replace this

load: function(response){
  updateDiv.innerHTML = response;
  wireEvents();
  return response;
},

      

into something like

   load: function(response){
      updateDiv.innerHTML = dojo.byId('elemToExtract', response);
      wireEvents();
      return response;
    },

      

I have to refresh my page with the ajax part of the response. I need the ability to use the dojo.byId selector over the response (using the response as the context root, or something like what I found in jQuery).

Do you know how I can achieve this?

thank

+2


source to share


3 answers


Max and Set .. thanks a lot!

In the end, the solution is based on what Massimiliano suggested.

I adapted it to dojo 1.2.3 (as the dojo.empty () function is missing in this text). "Results [0] .innerHTML" must be called to retrieve the dom from the dojo variable. Then, without calling empty (), I can directly replace the innerHTML of the target "updateDiv"

The key point here is the ability for dojo.query () to query the tree passing the domNode as context (sorry ... I'm new to dojo).



load: function(response){
      var tempDiv = document.createElement("div");
      tempDiv.innerHTML = response;
      var results = dojo.query("[id=elemToExtract]", tempDiv);
      updateDiv.innerHTML = results[0].innerHTML;
      wireEvents();
      return response;
 },

      

I'm not sure why, but checking "if (results.length) {" gives runtime problems. If I am debugging JS I think I add some delay and it works fine. The problem is at runtime, it seems that the condition evaluates to false ... I'm not sure why

Thanks again

0


source


The response you get is plain text defined by the handleAs parameter for the ajax call. If you want to request the markup contained in this answer using dojo.byId, you need to convert it to parsed HTML by creating a DOM for that. For this, you can create a temporary html element with a response; then you can extract the part you want using dojo.byId.

load: function(response){
    var tempDiv = dojo.create('div', {innerHTML: response});
    updateDiv.innerHTML = dojo.byId('elemToExtract', tempDiv);
    wireEvents();
    return response;
},

      

EDIT:

The above errors contain errors because dojo.byId requires a document to be used as the second argument, and it doesn't accept Node (see also Seth's answer ); moreover, it returns a Node instance which cannot be assigned innerHTML. In a working solution, when you have a temporary element, you need to extract the part you want using dojo.query. Then you can insert it inside the DOM on a real page using dojo.place. Note that if you want to replace the previous content, you need to remove all child objects of the Node target using dojo.empty before using dojo.place.



load: function(response){
    var tempDiv = dojo.create('div', {innerHTML: response});
    var results = dojo.query('[id=elemToExtract]', tempDiv);
    if (results.length) {
        dojo.empty(updateDiv);
        dojo.place(results[0], updateDiv);
        wireEvents();
    }
    return response;
},

      

Note that the dojo.place and dojo.create functions were added in versions 1.2 and 1.3, respectively; if you have a previous version it can be replaced using the DOM api:

load: function(response){
    var tempDiv = document.createElement('div');
    tempDiv.innerHTML = response;
    var results = dojo.query('[id=elemToExtract]', tempDiv);
    if (results.length) {
        dojo.empty(updateDiv);
        updateDiv.appendChild(result[0]);
        wireEvents();
    }
    return response;
},

      

+4


source


The problem is what the dojo.byId

document expects for the second argument. Another problem is that the ID is not known until the element is placed in the DOM. (I might be wrong on this last point and / or it might be browser dependent. In the experiments I did, dojo.byId didn't return anything until the HTML was in the DOM.)

That being said, you can accomplish what you want by putting the data returned by your ajax call in a hidden element and then using dojo.query

on it.

Assuming you have this in your HTML:

Then your xhrGet looks like this:

dojo.xhrGet( { 
    url: 'http://jsbin.com/erawu',
    handleAs: 'text',
    load: function(data) {
       var storage = dojo.byId('storage');
       storage.innerHTML = data;
       var want = dojo.query('#iwant', storage )[0];  // or dojo.query(...).forEach(...)
       if (want) {
          dojo.byId('hello').innerHTML = want.innerHTML;
          // depending on what you want
          // you could also use dojo.place( want, dojo.byId('hello'), 'first')
       }
    },
    error: function() {
        console.log( arguments );
        console.error('ONOES!');
    }
});

      

Here's a working example using dojo 1.2.

+1


source







All Articles