locked
Can you use the changeprop function from an inline frame? RRS feed

  • Question

  • Hi all.
    I am using an inline frame in EW2 that contains a long list of items that the user can select from.

    I have tried to use the changeprop behavior so when the user clicks on an iframe item, an element on the page that contains the iframe will have it's property changed.

    The message I get says EW can't find the element (probably because the element to be changed exists on a different page, it's not on the iframe page).

    Is there a way to code the elements id in the changeprop function to tell EW which page the element to be changed, is on?

    Thanks


    Don Dean
    Monday, February 7, 2011 10:29 PM

Answers


  • OK, I now see your objective, and it makes perfect sense for what you have in mind. You should note, however, that while using an iframe does cut down on the parent page weight, the total page weight is higher, and the load time is actually increased by the additional HTTP requests involved. Just a thought.

    Anyway, got a case of "Idon'twannagotobed" tonight. so I worked up a simple test case for you using plain old javascript. You'll paste the first code below into a new page (I called mine iframe-parent-access-parent.html) that will, as you might expect, be the parent page.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Iframe Parent</title>
    </head>

    <body>
    <p id="testPara">This is the test paragraph</p>
    <iframe name="Iframe1" src="iframe-parent-access-child.html">
                    Your browser does not support inline frames or is currently configured not to display inline frames.
                </iframe>
    </body>

    </html>

    Now for the child (content) page (I called it iframe-parent-access-child.html for obvious reasons), paste this into another new page.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Language" content="en-us" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Iframe</title>
    </head>

    <body>

       <p onclick="window.parent.document.getElementById('testPara').style.backgroundColor = 'red';">Click to test!</p>

    </body>

    </html>

    Save both pages, then, making sure that the parent page has the focus, Preview In Browser. You should see both paragraphs, with the iframe having the default border. If you only see "Click to test!" you have accidentally previewed the child page (ask me how I know).

    Anyway, if you see both paragraphs, click the obvious one and the other's background color will change to red. Voila! Interdocument communication. You can use other functions as well, as long as you use window.parent.document to establish the context in which it is operating. Tested in the big five (IE, FF, Safari, Chrome, Opera).

    Does that do it for you? No need for all of that baggage and junk FP code. Short sweet, easy to read, and lightweight.

    [EDIT: In the "credit where credit is due" department, while scanning the thread to see if I had missed anything, I noticed that Ron had proposed using the "window.parent.document" syntax as well, but in the context of rewriting the FP javascript code.]

    cheers,
    scott
    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 12:13 AM
    Thursday, February 10, 2011 6:51 AM
  • I was surprised that it worked without having to define that "getElementById" was js, somewhere on the page.

    That's because, unlike Flash, Silverlight, Java®, or other active technologies, every modern browser (desktop—mobile may be another matter) comes with a native javascript parser/interpreter. So, standard (i.e. built-in) functions such as getElementById() are understood when the rendering engine finds them within an appropriate context.

    The proper contest in this case was provided by the fact that the function call was found in an event handler. Stick it into the HTML stream, and it will either be ignored, render as plain text, or create a syntax error, depending upon where it is found.

    Every browser also has its own version of the Document Object Model (DOM), which is what enables javascript to make changes to the document without reloading it. You are literally manipulating the DOM on the client side when you specify an element (with getElementById()) and then change one of its properties.

    As for sources for learning, they are really too abundant to enumerate. I would suggest just starting by googling "html event handlers" and exploring the returned pages. Lots of good stuff out there, and practice makes perfect!  ;-)

    cheers,
    scott


    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 8:20 AM
    Friday, February 11, 2011 5:42 AM
  • Maybe MS wanted us to be so confused when we looked at the code that we would then be so thankful to them beause they were abe to create all the complex code requred to handle a task that mere mortals are not abe to comprehend.

    Nah. Hanlon's Razor (one of the many phrasings) says, "One should not attribute to malice that which may be adequately explained by incompetence." That phrasing is not directly appropriate in this instance, but basically, it's unfair to attribute to Microsoft nefarious intent when the actual goal was to make it easy for the largely untrained and inexperienced users of FrontPage to incorporate dynamic effects into their pages with built-in tools in FP.

    The legacy code in EW is inherited from the last version of FP, which was eight years ago. A lot has happened with javascript in eight years. Mention "object-oriented javascript" or "asynchronous javascript and xml" (AJAX) eight years ago and you would have been lucky if all you got were blank stares.

    [A side note: Javascript has always been object-oriented, in the sense that everything in javascript is an object, the property of an object, or a primitive data type (e.g. integer), and even those can sometimes be treated as objects. However, by object-oriented in this context I mean to refer to programming javascript using object-oriented programming principles such as polymorphism, inheritance, and encapsulation.]

    Also, remember that Microsoft had to write this stuff to be as bullet-proof as possible, and as easy as possible to implement by unknowledgeable users working solely through a GUI. Take our example:

    "window.parent.document.getElementById('testPara').style.backgroundColor = 'red';"

    Now, that is simple, straightforward javascript. But, it IS javascript, and writing something like that would have been beyond the capabilities of many of the target users of FP, a large number of which could not write simple HTML or CSS, much less javascript. Making such functionality available through a point-and-click GUI made the code necessarily more complex than it would have had to be if you or I were rolling our own.

    Even so, it is still old, obsolete code, and with the advances in almost all fields, browser implementations, editing tools, javascript interpreters, etc. in the last eight years, it is no longer necessary nor desirable to continue to use it.

    R.I.P., FrontPage behaviors. You were there for those that needed you when they needed you. Time to retire to the ranch now...

    cheers,
    scott


    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 8:23 AM
    Friday, February 11, 2011 6:14 AM

All replies

  • I am unfamiliar with this property or its use with frames (which, as an aside, are generally bad to use).

    My guess is that you are going to need to use FindControl which can get a little complicated depending on where the control is, and I would suggest you take this question to the asp.net forum at http://forums.asp.net/



    ClarkNK, A.K.A. HomePage Doctor
    HomePageDoctor.com -- Expression Web database tutorials
    Ownertrades.com -- Created with FP, Access, Bots and Wizards
    LawOfAllTheLand.org -- Created with Expression, VWDExress, SQL Express, and ASP.NET.
    Arvixe -- My favored web host
    Tuesday, February 8, 2011 1:22 PM
  • "Is there a way to code the elements id in the changeprop function to tell EW which page the element to be changed, is on?"

    Yes - if you are willing to rewrite the JavaScript used by the behaviour.

    The solution involves finding the element in the parent page using something like (not tested)

    window.parent.document.getelementById("elementId")

    in the iframe page.


    Ron Symonds
    Microsoft MVP (Expression Web)

    www.rxs-enterprises.org/fp
    Tuesday, February 8, 2011 2:18 PM
  • Hey thanks a bunch Ron. 

    That makes perfectly good sense, changing the getelementById function. I looked at the EW JS code. I'm not real versed in JS, although I have modified a few simple pieces of JS before. But the way EW writes it's FP_ JS code, it's pretty hard for me to follow it.

    My Onclick command calls the FP_changeProp function, which then calls the FP_getObjectById function but it's not obvious to me how to make the change you suggested inside this function.

    Can anyone help out and suggest how to make the code change.  Here's the standard FP JS code that was generated by EW, that I am using:

    <script type="text/javascript">
    <!--
    function FP_changeProp() {//v1.0
     var args=arguments,d=document,i,j,id=args[0],o=FP_getObjectByID(id),s,ao,v,x;
     d.$cpe=new Array(); if(o) for(i=2; i<args.length; i+=2) { v=args[i+1]; s="o";
     ao=args[i].split("."); for(j=0; j<ao.length; j++) { s+="."+ao[j]; if(null==eval(s)) {
      s=null; break; } } x=new Object; x.o=o; x.n=new Array(); x.v=new Array();
     x.n[x.n.length]=s; eval("x.v[x.v.length]="+s); d.$cpe[d.$cpe.length]=x;
     if(s) eval(s+"=v"); }
    }

    function FP_getObjectByID(id,o) {//v1.0
     var c,el,els,f,m,n; if(!o)o=document; if(o.getElementById) el=o.getElementById(id);
     else if(o.layers) c=o.layers; else if(o.all) el=o.all[id]; if(el) return el;
     if(o.id==id || o.name==id) return o; if(o.childNodes) c=o.childNodes; if(c)
     for(n=0; n<c.length; n++) { el=FP_getObjectByID(id,c[n]); if(el) return el; }
     f=o.forms; if(f) for(n=0; n<f.length; n++) { els=f[n].elements;
     for(m=0; m<els.length; m++){ el=FP_getObjectByID(id,els[n]); if(el) return el; } }
     return null;
    }
    // -->
    </script>

    Thanks


    Don Dean
    Thursday, February 10, 2011 5:01 AM
  • I wrote a fairly long reply recommending avoiding FP's obsolete old junk javascript behaviors, then decided to hel with it and went and found a reference. Check out this page for a discussion for several ways to do it with concise javascript or with jQuery. Basically, you establish the context with window.parent.document, using either javascript or the framework.

    If you're loading the jQuery library anyway, using jQuery would then allow you to use its excellent accessors to find, and to change the CSS for (or remove and add classes to change appearance of), any element in the parent document. You can do it with javascript, too, but as long as you're loading jQuery, might as well use it.

    Or, you could define a function on the parent page that changes a property or the class of the passed argument in a defined way, then call the function from the iframe, passing in the id of the element to change as the argument.

    Basically, the FP behaviors are designed to do one thing, one way. If you want to do it differently, you'll have to get your hands dirty in a little coding. Out of curiosity, why are you using an iframe, anyway? They do have their uses, when their content is something that you don't care about being indexed by the SEs (video players, maps, etc.), but from the sound of it you may want this content indexed. If so, just use a div with a set height and overflow:auto. You'll get the same effect as an iframe, but the contents will be all on one page and you won't have to worry about document contexts, or the search engines overlooking important content. Just sayin'...

    cheers,
    scott


    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    Thursday, February 10, 2011 5:42 AM
  • Hey, thanks for your input paladyn. 

    Glad to hear that I'm not the only one who is not impressed with the EW FP_ js.  (I saw your first reply.)

    I looked at your link and see that it concerns Jquery.  I'm not at all familiar with Jquery so will have to do some study to see if this will work for me.  Hopefully that won't take a long time.

    In response to your question as to what exactly am I trying to do:
    I'm starting a photography business and setting up a website for it.  I plan on getting with a local framing company so when my customers look at their pictures on my site, they will also be able to view it in a frame, and decide if they want to get it framed.

    I anticipate the number of frame options will be large, over 100, so I didn't want to include this list on the customer's page, thus thought of using an inline frame so they could scroll through the list. 

    I plan on creating a table with a picture of each frame in the cells of one of the columns, and also include prices and other info in additional columns.  I'd like the customer to be able to click on a picture of the frame that they like (in the inline frame) and then have that picture placed inside a table on the main page that will show their photo, the frame they picked and also the mat color they picked.

    I could do this very easily if I included all of these tables on the main page, but it would make an extremely larg page.  I'm not versed in databases, so tables (inline) seemed like the easy way to set this up without having to learn SQL.

    Thanks.


    Don Dean
    Thursday, February 10, 2011 6:09 AM

  • OK, I now see your objective, and it makes perfect sense for what you have in mind. You should note, however, that while using an iframe does cut down on the parent page weight, the total page weight is higher, and the load time is actually increased by the additional HTTP requests involved. Just a thought.

    Anyway, got a case of "Idon'twannagotobed" tonight. so I worked up a simple test case for you using plain old javascript. You'll paste the first code below into a new page (I called mine iframe-parent-access-parent.html) that will, as you might expect, be the parent page.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Iframe Parent</title>
    </head>

    <body>
    <p id="testPara">This is the test paragraph</p>
    <iframe name="Iframe1" src="iframe-parent-access-child.html">
                    Your browser does not support inline frames or is currently configured not to display inline frames.
                </iframe>
    </body>

    </html>

    Now for the child (content) page (I called it iframe-parent-access-child.html for obvious reasons), paste this into another new page.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Language" content="en-us" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Iframe</title>
    </head>

    <body>

       <p onclick="window.parent.document.getElementById('testPara').style.backgroundColor = 'red';">Click to test!</p>

    </body>

    </html>

    Save both pages, then, making sure that the parent page has the focus, Preview In Browser. You should see both paragraphs, with the iframe having the default border. If you only see "Click to test!" you have accidentally previewed the child page (ask me how I know).

    Anyway, if you see both paragraphs, click the obvious one and the other's background color will change to red. Voila! Interdocument communication. You can use other functions as well, as long as you use window.parent.document to establish the context in which it is operating. Tested in the big five (IE, FF, Safari, Chrome, Opera).

    Does that do it for you? No need for all of that baggage and junk FP code. Short sweet, easy to read, and lightweight.

    [EDIT: In the "credit where credit is due" department, while scanning the thread to see if I had missed anything, I noticed that Ron had proposed using the "window.parent.document" syntax as well, but in the context of rewriting the FP javascript code.]

    cheers,
    scott
    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 12:13 AM
    Thursday, February 10, 2011 6:51 AM
  • "Glad to hear that I'm not the only one who is not impressed with the EW FP_ js."

    Just a note:  I don't think you're supposed to be impressed with it.  :)

    That's old legacy code from FrontPage, for backward compatibility.  I don't think it's intended to be an illustration of the best way to do things now.  ["Interactive Buttons", anyone?]

    Thursday, February 10, 2011 2:30 PM
  • Scott, that's fantastic!

    Just like you said: "Short sweet, easy to read, and lightweight." Exacty what I needed.

    Once I got your code to work, I switched out the "backgroundColor" with "backgroundImage" so I could copy an image into the destination paragraph.  It took me awhile to get all the quote marks, parens and slashes right, but once I did, Wallah! It worked like a charm!

    I was surprised that it worked without having to define that "getElementById" was js, somewhere on the page.

    How was this possible?
    Can you recommend a web page where I can find more code examples like this for simple event handling?

    Thanks a bunch.
    You're a genius!


    Don Dean
    Friday, February 11, 2011 12:14 AM
  • Maybe MS wanted us to be so confused when we looked at the code that we would then be so thankful to them beause they were abe to create all the complex code requred to handle a task that mere mortals are not abe to comprehend.


    Don Dean
    Friday, February 11, 2011 12:26 AM
  • I was surprised that it worked without having to define that "getElementById" was js, somewhere on the page.

    That's because, unlike Flash, Silverlight, Java®, or other active technologies, every modern browser (desktop—mobile may be another matter) comes with a native javascript parser/interpreter. So, standard (i.e. built-in) functions such as getElementById() are understood when the rendering engine finds them within an appropriate context.

    The proper contest in this case was provided by the fact that the function call was found in an event handler. Stick it into the HTML stream, and it will either be ignored, render as plain text, or create a syntax error, depending upon where it is found.

    Every browser also has its own version of the Document Object Model (DOM), which is what enables javascript to make changes to the document without reloading it. You are literally manipulating the DOM on the client side when you specify an element (with getElementById()) and then change one of its properties.

    As for sources for learning, they are really too abundant to enumerate. I would suggest just starting by googling "html event handlers" and exploring the returned pages. Lots of good stuff out there, and practice makes perfect!  ;-)

    cheers,
    scott


    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 8:20 AM
    Friday, February 11, 2011 5:42 AM
  • Maybe MS wanted us to be so confused when we looked at the code that we would then be so thankful to them beause they were abe to create all the complex code requred to handle a task that mere mortals are not abe to comprehend.

    Nah. Hanlon's Razor (one of the many phrasings) says, "One should not attribute to malice that which may be adequately explained by incompetence." That phrasing is not directly appropriate in this instance, but basically, it's unfair to attribute to Microsoft nefarious intent when the actual goal was to make it easy for the largely untrained and inexperienced users of FrontPage to incorporate dynamic effects into their pages with built-in tools in FP.

    The legacy code in EW is inherited from the last version of FP, which was eight years ago. A lot has happened with javascript in eight years. Mention "object-oriented javascript" or "asynchronous javascript and xml" (AJAX) eight years ago and you would have been lucky if all you got were blank stares.

    [A side note: Javascript has always been object-oriented, in the sense that everything in javascript is an object, the property of an object, or a primitive data type (e.g. integer), and even those can sometimes be treated as objects. However, by object-oriented in this context I mean to refer to programming javascript using object-oriented programming principles such as polymorphism, inheritance, and encapsulation.]

    Also, remember that Microsoft had to write this stuff to be as bullet-proof as possible, and as easy as possible to implement by unknowledgeable users working solely through a GUI. Take our example:

    "window.parent.document.getElementById('testPara').style.backgroundColor = 'red';"

    Now, that is simple, straightforward javascript. But, it IS javascript, and writing something like that would have been beyond the capabilities of many of the target users of FP, a large number of which could not write simple HTML or CSS, much less javascript. Making such functionality available through a point-and-click GUI made the code necessarily more complex than it would have had to be if you or I were rolling our own.

    Even so, it is still old, obsolete code, and with the advances in almost all fields, browser implementations, editing tools, javascript interpreters, etc. in the last eight years, it is no longer necessary nor desirable to continue to use it.

    R.I.P., FrontPage behaviors. You were there for those that needed you when they needed you. Time to retire to the ranch now...

    cheers,
    scott


    Please remember to "Mark as Answer" the responses that resolved your issue. It is common courtesy to recognize those who have helped you, and it also makes it easier for visitors to find the resolution later.
    • Marked as answer by Don Dean Friday, February 11, 2011 8:23 AM
    Friday, February 11, 2011 6:14 AM
  • Some more good information.

    Thanks Scott


    Don Dean
    Friday, February 11, 2011 8:22 AM
  • Very informative Scott, although I was speaking tongue-in-cheek about MS's intentions.

    Thanks for all your input.

    You're on my 'good' list now.  [:-)


    Don Dean
    Friday, February 11, 2011 8:28 AM