Simple question about cross-window dropdown list loading

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joseph Barron

    Simple question about cross-window dropdown list loading

    Here is a SIMPLE problem that I'm trying to solve.
    It works in Netscape 6.2, but IE6 gives ""No such interface
    supported."

    Below are page1.htm and page2.htm .

    In page1.htm, there are two dropdown lists. If you change the
    selection of the left one (e.g. choose parentoption2), it
    should open up page2.htm in a popup window.

    page2.htm has its own dropdown list. When this page finishes loading,
    the onload() its <BODY> will call copyback() which copies the
    contents of that dropdown list to the rightmost dropdown list on
    page1.htm. In the blink of an eye, the page2.htm popup window
    then closes itself.

    So, the end result should be that the right dropdown list in
    page1.htm, instead of having "What?","What?" ,"What?" as options
    as it does originally, it should end up having childoption1,
    childoption2, and childoption3.

    *Should* be. I thought the best way to do this "replace one node
    with another" is to use replaceChild (in page2.htm).
    (Is there a better way of doing it? There is removeChild but it's
    not part of W3C, I don't believe.)

    (What I'm trying to get out of all this is to have the first
    dropdown list hold, say, a list of people. When a person is selected,
    the Javascript opens up a second page which will be something
    like a Perl or PHP script that connects to a SQL database,
    grabs all the phone numbers for that person, puts them in a
    temporary dropdown list on that page, then copies that list
    to the rightmost dropdown list of the first page.

    I know that this must be a very common requirement, but I haven't
    yet found any web site that shows code to do exactly this, and
    I certainly don't mind being told how I'm doing it all wrong!
    )

    It works in Netscape 6.2, but not in IE6! At the replaceChild
    step in page2.htm, IE6 gives the fatal error
    "No such interface supported.", usually followed by the browser
    completely terminating (nice).

    I don't think the problem is replaceChild per se, as I got the
    same error when trying other DHTML stuff like mergeAttributes (),
    etc, in the same environment, i.e. I think *possibly* the problem
    is that it's not designed to handle this kind of cross-window
    copying??

    I saw Microsoft KB support article Q237831 which kind of implies
    that you can't create stuff in one context (window or frame) and
    try to use it in another window or frame.
    This is at (note that it's all one line!) :
    support.microso ft.com/default.aspx?sc id=http://support.microso ft.com:80/s
    upport/kb/articles/Q237/8/31.ASP&NoWebCon tent=1

    Unfortunately, I tried the example in the article, which the article
    says won't work for IE5, but it DOES work for IE6 - at least, it
    worked for me. So it's not helping in solving my problem.

    What DOES work is if I comment out the
    parentnode.repl aceChild(newnod e,oldnode);
    return;
    lines in page2.htm, so that it continues and gets to the code
    which copies the select list option by option. Unfortunately,
    it is far too slow - in certain situations there are going to be
    thousands of options in the dropdown list.

    ----page1.htm----
    <html>
    <head>
    </head>
    <body>
    <select onchange='windo w.open("page2.h tm","popup","to olbar=no, width=500,
    height=250, left=0, top=0")'
    name="selectlis tparent1" >
    <option value="30">pare ntoption1</option>
    <option value="31">pare ntoption2</option>
    </select>
    <select
    name="selectlis tparent2" >
    <option value="4">What? </option><option
    value="5">What? </option><option value="6">What? </option>
    </select>
    </body>
    </html>
    ----page2.htm----
    <html>
    <head>
    <script>
    <!--
    function copyback() {
    newnodes=docume nt.getElementsB yName('selectli stchild');
    newnode=newnode s[0];

    oldnodes=opener .document.getEl ementsByName('s electlistparent 2') ;
    oldnode=oldnode s[0];
    //echodebug('oldn ode.nodeName: '+oldnode.nodeN ame,1);

    parentnode = oldnode.parentN ode;
    // IE6 can't handle this: "No such interface supported."
    parentnode.repl aceChild(newnod e,oldnode);
    return;

    // -------
    // Instead of using replaceChild above, can copy the options
    // one by one:

    // Empty the recepient dropdown list in the parent window,
    // by making a non-deep clone of it, then replacing itself
    // with the clone. Then assign 'oldnode' variable to once
    // again point to it.
    oldnodeclone = oldnode.cloneNo de(false);
    oldnode.parentN ode.replaceChil d(oldnodeclone, oldnode);

    oldnodes=opener .document.getEl ementsByName('s electlistparent 2') ;
    oldnode=oldnode s[0];

    // Copy the options from the dropdown list in the child window, to
    the
    // recepient dropdown list in the parent window.
    for (i=0;i<newnode. options.length; i++) {
    // This does work to copy them individually. But it's way too
    slow.
    oldnode.options .length++;
    oldnode.options[i].text = newnode.options[i].text;
    oldnode.options[i].value = newnode.options[i].value;
    }

    window.close();

    }

    // -->
    </script>
    </head>
    <body onload="copybac k()">
    <select name="selectlis tchild" >
    <option value="1">child option1</option>
    <option value="2">child option2</option>
    <option value="3">child option3</option>
    </select>
    </body>
    </html>
  • Yep

    #2
    Re: Simple question about cross-window dropdown list loading

    baron4-4+nspamflyaway@ unspamar.com.au (Joseph Barron) wrote in message news:<3f0aeb23@ nexus.comcen.co m.au>...
    [color=blue]
    > In the blink of an eye, the page2.htm popup window
    > then closes itself.[/color]

    What about using a hidden (i)frame? Logic remains the same, and you
    avoid blinking (moreover window.open may is not safe in an Internet
    env). If you're sure of your env you could also use XmlHttpRequest I
    think.
    [color=blue]
    > It works in Netscape 6.2, but not in IE6! At the replaceChild
    > step in page2.htm, IE6 gives the fatal error
    > "No such interface supported.", usually followed by the browser
    > completely terminating (nice).[/color]

    Well, I've got IE5.5 and get the same results, as you note here...
    [color=blue]
    > I saw Microsoft KB support article Q237831 which kind of implies
    > that you can't create stuff in one context (window or frame) and
    > try to use it in another window or frame.[/color]

    .... this is a normal behavior, the real pain is that IE doesn't
    currently support advanced DOM2 features (also note that DOM2 offers
    an importNode method and DOM3 adoptNode method for the Document
    interface, which would please you if supported).
    [color=blue]
    > What DOES work is if I comment out the
    > parentnode.repl aceChild(newnod e,oldnode);
    > return;
    > lines in page2.htm, so that it continues and gets to the code
    > which copies the select list option by option.[/color]

    That's unfortunately the generally accepted solution, regarding your
    code I'd just recommend not to use window.open in the onchange handler
    (you'll prevent any keyboard navigation for the select, such as arrows
    and letters) and use getElementById over getElementsByNa me.
    [color=blue]
    > Unfortunately,
    > it is far too slow - in certain situations there are going to be
    > thousands of options in the dropdown list.[/color]

    Maybe re-think your process then (functional solution), do some
    intermediate layer, select boxes with thousands entries aren't
    generally appreciated; or just have the server sends a parseable
    string and have innerHTML write it (technical solution). This could be
    much faster than DOM manipulation, and (probably) more cross-browser.
    The result is impressive in IE (7 times faster), correct in Mozilla
    (1.5 times faster) and not worth it in Opera 7 (DOM manipulation a bit
    faster, innerHTML doesn't seem to communicate directly with the
    parser):

    <script type="text/javascript">
    function f(){
    var d=document;
    var s=d.createEleme nt("select");
    for(var ii=0; ii<1000; ii++){
    var opt=d.createEle ment("option");
    opt.value="v"+i i;
    opt.text="t"+ii ;
    s.appendChild(o pt);
    }
    document.getEle mentById("test" ).appendChild(s );
    }
    function g(){
    var s="<select>";
    for(var ii=0; ii<1000; ii++)
    s+="<option value='v"+ii+"' >t"+ii+"<\/option>";
    document.getEle mentById("test" ).innerHTML=s+" <\/select>";
    }
    function runTest(){
    var d1=new Date();
    f();
    var d2=new Date();
    g();
    var d3=new Date();
    alert("f:"+(d2-d1)+"\n"+"g:"+( d3-d2));
    }
    </script>
    <div id="test"></div>
    <input type="button" onclick="runTes t()" value="test!">


    A quick script follows as illustration (if you happen to go for this
    conception or something similar, I'd however suggest that you adopt a
    more structured approach defining clearly the interface and message
    objects):


    page1.htm
    <script type="text/javascript">
    function generate(where, what){
    switch (where) {
    case "csel" :
    var parts=what.spli t(":"), buf=["<select>"];
    for(var ii=0; ii<parts.length ; ii+=2){
    buf.push(
    "<option value='"+parts[ii]+"'>"+
    parts[ii+1]+
    "<\/option>"
    );
    }
    document.getEle mentById("csel" ).innerHTML=buf .join("");
    break;
    }
    }
    function test(){
    //document.getEle mentById("csel" ).innerHTML="Lo ading...";
    frames.buffer.l ocation.href='p age2.htm';
    }
    </script>

    <input type="button" value="load!" onclick="test() ">
    <div id="csel">
    <select>
    <option value="4">What? </option>
    <option value="5">What? </option>
    <option value="6">What? </option>
    </select>
    </div>
    <iframe width="0" height="0"
    style="visibili ty:hidden" name="buffer"></iframe>



    page2.htm (server's response):
    <html>
    <head>
    <title></title>
    <script type="text/javascript">
    window.onload=f unction(){
    var db=document.bod y;
    if(top.generate && db)
    top.generate("c sel",db.innerHT ML);
    }
    </script>
    </head>
    <body>
    value 1:child 1:value 2:child 2:value 3:child 3
    </body>
    </html>

    Comment

    Working...