Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Javascript into Ajax context... Unusual problem, no eval() issues

  1. #1
    Join Date
    Nov 2007
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Javascript into Ajax context... Unusual problem, no eval() issues

    Hi everyone!

    First thank you for reading this post and yes, you probably already see that kind of topic title somewhere but the problem I've got today might be different than the 100 topics I've seen so far that did not resolve my problem...

    Environment and problem: I have a page A with Ajax.js and a <div id="ajx">Content</div> that changes when clicking on a link. Another page, page B, gets loaded into page A and (tries) to load a javascript. When I click on the page A's link, the page B gets loaded but the javascript doesn't load.

    What else? I tried several things to get it work (load the javascript with the XHR request, load the javascript from an <img src="" onload="javascript.js">, eval();, global.eval(); with var global = this; to force the script to start, I also tried the script from various topics I've seen...) but nothing worked. Well it did when I tried to load the js with the XHR request but it did not load properly and since I must load the js at the end of page B and not at the beginning so it doesn't work.

    Here are my scripts samples:

    Ajax.js
    Code:
    var loadedobjects=""
    var rootdomain="http://"+window.location.hostname
    
    function ajaxpage(url, containerid, tp, poststr){
    var page_request = false
    if (window.XMLHttpRequest) // if Mozilla, Safari etc
    page_request = new XMLHttpRequest()
    else if (window.ActiveXObject){ // if IE
    try {
    page_request = new ActiveXObject("Msxml2.XMLHTTP")
    } 
    catch (e){
    try{
    page_request = new ActiveXObject("Microsoft.XMLHTTP")
    }
    catch (e){}
    }
    }
    else
    return false
    document.getElementById(containerid).innerHTML='<img src="http://localhost/img/ld.gif">'
    page_request.onreadystatechange=function(){
    loadpage(page_request, containerid)
    
    }
    
    if (tp != 'POST'){
    page_request.open('GET', url, true)
    page_request.send(null)
    } else {
    page_request.open('POST', url, true);
    page_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    page_request.setRequestHeader("Content-length", poststr.length);
    page_request.setRequestHeader("Connection", "close");
    page_request.send(poststr);
    }
    }
    
    function loadpage(page_request, containerid){
    if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))
    	document.getElementById(containerid).innerHTML=page_request.responseText
    }
    
    function loadobjs(){
    if (!document.getElementById)
    return
    for (i=0; i<arguments.length; i++){
    var file=arguments[i]
    var fileref=""
    if (loadedobjects.indexOf(file)==-1){ //Check to see if this object has not already been added to page before proceeding
    if (file.indexOf(".js")!=-1){ //If object is a js file
    fileref=document.createElement('script')
    fileref.setAttribute("type","text/javascript");
    fileref.setAttribute("src", file);
    }
    else if (file.indexOf(".css")!=-1){ //If object is a css file
    fileref=document.createElement("link")
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", file);
    }
    }
    if (fileref!=""){
    document.getElementsByTagName("head").item(0).appendChild(fileref)
    loadedobjects+=file+" " //Remember this object as being already added to page
    }
    }
    }
    Page A ### loadobjs is the method that load the js with the XHR
    Code:
    <a href="#" onclick="javascript:ajaxpage('up/load', 'ajx', 'GET'); loadobjs(alpha.js)">Upload</a>
    <br>
    <div id="ajx"></div>
    Page B
    Code:
    <script>
    var ext_allowed='<TMPL_VAR ext_allowed>';
    var ext_not_allowed='<TMPL_VAR ext_not_allowed>';
    var max_files=<TMPL_VAR max_files>;
    var max_size=<TMPL_VAR max_size>;
    var descr_mode=<TMPL_VAR enable_file_descr>;
    </script>
    
    ##> Page design and information <###
    
    <iframe src="javascript:false;" name="alpha" style="position:absolute;left:-9999px;"></iframe>
    <script>InitSelector();</script>
    So, for the page B, I need to load the first script with has no function but providing information and the InitSelector(); which is inside alpha.js. This is an atypic request but there must be something to solve it, init?

    Thanks a lot in advance.. I've been chasing a solution for 20hours... dang! :-[

    uNo! Weni
    Last edited by wenijah; 11-08-2007 at 07:05 AM.

  2. #2
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Nothing new here

    The traditional solution is to loop through all the script elements in the element once it's been parsed and eval() their innerHTML. This kind of works, but it's ugly and in some cases will fail. Instead, I suggest that rather than sending the response as a big blob of HTML, you encode it in a format more readily accessible to Javascript, such as XML or JSON, and recreate it that way. E.G., instead of sending:
    Code:
    <script type="text/javascript" src="somescript.js"></script>
    <p id="someID">
      <span class="someClass">Some text...</span>
      Some more text...
    </p>
    You might send:
    Code:
    [
      {"_tag" : "script",
        "type" : "text/javascript",
        "src" : "somescript.js"
      },
      {"_tag" : "p",
        "id" : "someID",
        "_children" : [
          {"_tag" : "span",
            "className" : "someClass",
            "_children" : ["Some text..."]
          },
          "Some more text"
        ]
      }
    ]
    Here's a sample JSON-to-DOM parser for this format:
    Code:
    function jsonToDom(o) {
      if (typeof o === "string")
        return document.createTextNode(o);
    
      var r = document.createElement(o._tag);
    
      for (var x in o)
        if (o.hasOwnProperty(x)
            && x.indexOf("_") !== 0)
          r[x] = o[x];
    
      if(o._children && o._children.length)
        for (var i = 0, e = o._children, n = e.length; i < n; ++i)
          r.appendChild(jsonToDom(e[i]));
    
      return r;
    }
    Last edited by Twey; 11-08-2007 at 11:06 AM. Reason: Stricter JSON compliance.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  3. #3
    Join Date
    Nov 2007
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thanks a lot for your reply Twey!! May I ask you something else though? I'm not sure I get it all and I don't know JSON thaaat much (matter of fact, I don't know it at all)... Where should I put...

    Code:
    [
      {_tag: "script",
        type: "text/javascript",
        src: "somescript.js"
      },
      {_tag: "p",
        id: "someID",
        _children: [
          {_tag: "span",
            className: "someClass",
            _children: ["Some text..."]
          },
          "Some more text"
        ],
      }
    ]
    ...In the Ajax.js? As a function? And then use the JSON-to-DOM parser? Thanks for your help!
    Last edited by wenijah; 11-08-2007 at 07:08 AM.

  4. #4
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    I don't know JSON thaaat much
    There's nothing to know. JSON stands for JavaScript Object Notation. It just uses the standard Javascript object literal notation (well, a subset of it). If you know Javascript, you know JSON.

    As for where to use it, the code I gave you above would be what you'd return from your server-side script rather than HTML. The Javascript would eval() that, then pass the resulting objects to the jsonToDom() function I provided above in order to obtain the equivalent DOM nodes. As a side effect of creating those nodes, however, everything necessary (e.g. scripts) would be pulled in and executed.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  5. #5
    Join Date
    Nov 2007
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I see... Matter of fact, that's THE problem because I just cannot load the js before the page B is completly loaded... Otherwise it would already work..

    Is it possible to load a javascript at the end of page B? If not, then I should reconsider my structure right now =/

    Thank you!

    (by the way, why does it say yingguo as your country?)

  6. #6
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    I see... Matter of fact, that's THE problem because I just cannot load the js before the page B is completly loaded... Otherwise it would already work..
    You don't see The JSON objects I provided were a sample page B in themselves.

    (by the way, why does it say yingguo as your country?)
    Yīng guó in Mandarin, えいこく (eikoku) in Japanese. England is the meaning in both, I think? I don't know much Mandarin.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  7. #7
    Join Date
    Nov 2007
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Chea! Got it! =) Thank you and thanks w3school and HTML DOM Tutos.. Ok, so to be clear:

    Page B will be a JS by itself? Like, I dont use HTML vars but only Nodes, right?

    And everything will be parsed by the JsonToDOM function?

    I'm not sure... page B is a "template" generated from a perl application... Will it be possible to retrieve all datas sent by the CGI into the new JS?

    Thanks!!

    (yeah yingguo is England in Mandarin.. Owee i'm learning mandarin, that's why lol)

  8. #8
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    I'm not sure... page B is a "template" generated from a perl application... Will it be possible to retrieve all datas sent by the CGI into the new JS?
    Your server-side script can work exactly as it did before. Only the output format need change.
    (yeah yingguo is England in Mandarin.. Owee i'm learning mandarin, that's why lol)
    It's a nice language. I wish I had time to study it in more depth (as I wish of so many things these days, it seems).
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  9. #9
    Join Date
    Nov 2007
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Mandarin is cool but i wish I could speak javascript better than mandarin ! :/ Well, I want to use the JSON-to-DOM parser but I just don't really know how integrate all that in my script... Like, does JSON-to-DOM has to be on page B or when I call AJAX? And what are the "[" and "]" before and after the vars to fetch the js? I'm sorry, I'm kinda lost there... I've found an issue but I hate using iframe so if you got a couple more minutes, could you just explain me how to set it up?

    Thanks a lot!

    ~w~
    Last edited by wenijah; 11-08-2007 at 02:23 PM.

  10. #10
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Well, I want to use the JSON-to-DOM parser but I just don't really know how integrate all that in my script... Like, does JSON-to-DOM has to be on page B or when I call AJAX?
    It has to be on page A. You use XMLHttpRequest (this isn't AJAX, there's no XML involved) to retrieve the content from your server-side script, evaluate it, then call jsonToDom() on the resulting object, before appending it to the <div>, or perhaps we should replace the <div> entirely.
    And what are the "[" and "]" before and after the vars to fetch the js?
    Square brackets in Javascript indicate an array. If we were to replace the <div>, however, that wouldn't be necessary.
    Code:
    // xhr.js
    
    var XHR = {
      jsonToDom: function jsonToDom(o) {
        if (typeof o === "string")
          return document.createTextNode(o);
    
        var r = document.createElement(o._tag);
    
        for (var x in o)
          if (o.hasOwnProperty(x)
              && x.indexOf("_") !== 0)
            r[x] = o[x];
    
        if(o._children && o._children.length)
          for (var i = 0, e = o._children, n = e.length; i < n; ++i)
            r.appendChild(jsonToDom(e[i]));
    
        return r;
      },
      getXHR: function() {
        if(typeof XMLHttpRequest === "function")
          return new XMLHttpRequest();
        else if(ActiveXObject)
          try {
            return new ActiveXObject("Msxml2.XMLHTTP");
          } catch (e1) {
            try {
              return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e2) {
              return null;
            }
          }
        else return null;
      },
      updateElement: function(url, element) {
        var xhr = XHR.getXHR();
        xhr.open("GET", url, true);
        xhr.onreadystatechange = function() {
          if(this.readyState === 4 && this.status === 200) {
            element.parentNode.replaceChild(jsonToDom(eval("(" + xhr.responseText + ")")), element);
            xhr = element = null;
          }
        };
        xhr.send(null);
      }
    };
    Code:
      <!-- Page A -->
      <style type="text/css">
        iframe.alpha-frame {
          position: absolute;
          left: -9999%;
        }
      </style>
      <script type="text/javascript" src="xhr.js"></script>
      <script type="text/javascript" src="alpha.js"></script>
    </head>
    <body>
      <p>
        <!-- Your previous use of <br> was an abuse.  -->
        <a
            href="up/load"
            onclick="XHR.updateElement(this.href + '?xhr=true', document.getElementById('ajx')); return false;">
          Upload
        </a>
        <div id="ajx"></div>
    Note: up/load should return a full HTML page if accessed directly (without the GET "xhr" parameter) for non-Javascript users.
    Code:
    ##> Page B <###
    {"_tag" : "div",
      "id" : "ajx",
      "_children" : [
        {"_tag" : "script",
          "type" : "text/javascript",
          "_children" : [
            "var ext_allowed = '<TMPL_VAR ext_allowed>';",
            "var ext_not_allowed = '<TMPL_VAR ext_not_allowed>';",
            "var max_files = <TMPL_VAR max_files>;",
            "var max_size = <TMPL_VAR max_size>;",
            "var descr_mode = <TMPL_VAR enable_file_descr>;"]},
    
        {"_tag" : "iframe",
          "src" : "about:blank",
          "name" : "alpha",
          "className" : "alpha-frame"},
    
        {"_tag" : "script",
          "type" : "text/javascript",
          "_children" : ["InitSelector();"]}]}
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •