Link to home
Start Free TrialLog in
Avatar of scrathcyboy
scrathcyboyFlag for United States of America

asked on

Synchronize checkboxes state and SPAN display between 2 windows, parent / child

I am trying to synchronize the checkbox state between two windows, it is proving difficult -

(1) main window has dozens of forms, each within its own DIV.  
(2) child popup window is data copied from just one DIV of main window.

When popup opens, it inherit checkbox state correct.  But change in checkbox in either main window or popup needs to synchronize to other window.  Main window JS routine is this, and Form follows -

function Add(ckbx,frm,spName) {
  var on = ckbx.checked;
  var el = document.getElementById(spName);
  if (el) el.style.display = (on)?"block":"none";
}

<DIV id="agr"> Details here <FORM name="agr"> <INPUT type="checkbox" id="agr1" value="no" onclick="Add(this,this.form.name,'agr2')"><SPAN id="agr2" style="display:none">Added</SPAN></FORM></DIV>

This same JS code and form data copy to popup, but I add these lines to popup JS to change parent -

  var pon = window.opener.document.forms[frm].ckbx.checked;
  var pel = window.opener.document.getElementById(spName);
  if (pel) pel.style.display = (on)?"block":"none";

They dont work, neither checkbox nor span in the parent.  I tried without 'window' and then without 'document' in path, no difference.  I realize name in 'frm' relates to the local form, but I cant address parent form (one of many on page) without using just a name (name is the same in both windows).

Also, I need to change the popup when parent checkbox and span changes.  Same problem but in reverse.  Could check in parent -  if (win.frm.name) then synchronize popup (form name is same as popup win name).

You see this is all issue with "remote" addressing of objects when you only have the name of the object to work with, as I said in previous questions, this is main battle with JS addressing methods.  Help?
 
Avatar of Zyloch
Zyloch
Flag of United States of America image

Suppose you have something like this:

var myWin = window.open('yourPopup.html');

Then, you would do:

onclick="Add(myWin, this, 'agr2');"

and:

function Add(win, ckbx, spName)
{
    win.document.forms[ckbx.form.name].elements[ckbx.name].checked = ckbx.checked;
    var el = document.getElementById(spName);
    if (el) el.style.display = (ckbx.checked) ? "block" : "none";
}

Then, in your popup, have:

function Add(ckbx, spName)
{
    window.opener.document.forms[ckbx.form.name].elements[ckbx.name].checked = ckbx.checked;
    var pel = window.opener.document.getElementById(spName);
    if (pel) pel.style.display = (ckbx.checked) ? "block" : "none";
}

and you would call in popup form:

onclick="Add(this, 'agr2');"
Avatar of scrathcyboy

ASKER

The onclicks must be the same, as main data is copied to popup window.
Then just merely have this:

function Add(myWin ckbx, spName)

as the header for your function in the popup and create a dummy myWin variable in the popup window.

Then, you can call, just like in the parent page with:

onclick="Add(myWin, this, 'agr2');"
just working on popup for now, I added the 3 lines you gave above to the popups JS code, and still same as my code, page 'hangs" with no refresh, and parent not updated.  If I remove those 3 lines, Js routine works fine, adds item to cart, but no change in parent either.

Something in those 3 lines of the Add() for popup is not working to complete JS and act on parent page.
You pass "this" to the function, that means it is a checkbox OBBJECT
so

  var pon = window.opener.document.forms[frm].ckbx.checked;

will not work unless the checkbox is called ckbx (but it isn't)

You want

  var pon = window.opener.document.forms[frm].elements[ckbx.name].checked;
or actually if your function had passed the checkbox object you did not need to change the function:
 just do ckbx.checked

However I suggest you change your code to not confuse you
frm is a name and ckbx is an object, either pass names or pass objects

Popup window is not passed any objects in parent form, at it stands -- just the names in the parent form are identical to those in the popup form, since the popup form is a copy of the parent main page form.

I have tried what you said, it doesn't work.  With 3 lines below, JS hangs, page never shows completely loaded, and the adding to the cart doesn't work.  If not a problem here, then in the routine that opens the popup window to begin with, perhaps it needs to pass the objects of parent form to child popup?

   var pon = window.opener.document.forms[frm].elements[ckbx.name].checked;
   var pel = window.opener.document.getElementById(spName);
   if (pel) pel.style.display = (ckbx.checked) ? "block":"none";

Those not working.  In case you want to see the popup code, here it is, I think it can be made shorter and probably improved, since it is only 1 line to open an html page, this is a lot of code to add a DIV.  BTW, the JS include and CSS include are needed to get the span right and do the functions above --

<script language="JavaScript">

function showPopUp(divName)
{
     var features = "height=350,width=350,scrollbars=yes,status=no,menubar=no,location=no";
     var pgName = "cntPage" + divName;
     var win = window.open('', pgName, features);
     var elem = document.getElementById(divName);
if (elem.innerHTML)
     {
          win.document.write(elem.innerHTML);
          win.document.write("<LINK REL='stylesheet' HREF='default.css' TYPE='text/css'>");
          win.document.write("<script src='showOrdered.js' type='text/javascript'></script\>");
          win.document.bgColor = "#F8F6F4";
     }     else
     {
          if (!document.all && typeof HTMLElement != "undefined")
          {
               win.document.write(parseHTML(elem.innerHTML));
               win.document.write("<LINK REL='stylesheet' HREF='default.css' TYPE='text/css'>");
               win.document.write("<script src='showOrdered.js' type='text/javascript'></script\>");
               win.document.bgColor = "#F8F6F4";
               win.document.close();
          }
     }
     win.focus();
}

function parseHTML(str)
{
     str = str.replace("/<br>/gi","\n");
     str = str.replace("</[^]+>/g", "");
     return str;
}

</script>
Pass the checkbox and this will work:

parent:

function Add(ckbx,spName) {
  var on = ckbx.checked;
  var el = document.getElementById(spName);
  if (el) el.style.display = (on)?"block":"none";
}

<form name="agr">
<INPUT NAME="agr1" type="checkbox" id="agr1" value="no" onclick="Add(this,'agr2')">
</form>


and this in the popup

function Add(ckbx,spName) {
.
.
.
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName) {
}

assuming the popup ALSO has
<form name="agr">
<INPUT NAME="agr1" type="checkbox" id="agr1" value="no" onclick="Add(this,'agr2')">
</form>

Michel
Sorry we posted at the same time

I would also write
 win.document.write("<script src='showOrdered.js' type='text/javascript'></script\>");

like this
 win.document.write("<script src='showOrdered.js' type='text/javascript'><\/script>");
but I know some browsers will not like dynamically written imports in a new window

Here is a shorter version


function showPopUp(divName) {
     var features = "height=350,width=350,scrollbars=yes,status=no,menubar=no,location=no";
     var pgName = "cntPage" + divName;
     var win = window.open('', pgName, features);
     var elem = document.getElementById(divName);
     var hasProblem = (!document.all && typeof HTMLElement != "undefined")
     win.document.write("<LINK REL='stylesheet' HREF='default.css' TYPE='text/css'>");
     win.document.write("<script src='showOrdered.js' type='text/javascript'></script\>");
     win.document.write((hasProblem)?parseHTML(elem.innerHTML):elem.innerHTML;
     win.document.bgColor = "#F8F6F4";
     win.document.close(); // Should be done always
     win.focus();
}

Michel
Yes, both forms are identical, it is a copy.

What comes after this?
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName) {

The Add function in popup will have same first 3 lines to handle its own popup display, but the line above is only part of what is needed, no?  One to get/change state of checkbox in parent to match popup, then other 1/2 lines needs to sync the Span Name in the parent to the same as in the popup.  Shouldn't it be more like -

  var parentOn = window.opener.document.forms[ckbx.form.name].elements[ckbx.name].checked;
  var parentEl =   window.opener.document.getElementById(spName);
  if (parentEl) parentEl.style.display = (parentOn)?"block":"none";

That's just a guess at what should match the changes in popup, both checkbox state and SPAN state need to be the same.

will check here in morning, very late now... thanks
typo

.
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName) {

should be

.
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName);

and that oneliner was to replace
  var parentOn = window.opener.document.forms[ckbx.form.name].elements[ckbx.name].checked;
  var parentEl =   window.opener.document.getElementById(spName);
  if (parentEl) parentEl.style.display = (parentOn)?"block":"none";

but I see I missed to check the box so the popup code should probably be


function Add(ckbx,spName) {
  window.opener.document.forms[ckbx.form.name].elements[ckbx.name].checked = ckbx.checked
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName);
}
Great, the checkbox is working, the popup checkbox now syncs the checkbox in the main form.  The on/off of the span text in the main form is not working yet, so second line not right.  "Add" is only a JS function, it is not the span or form name.  Are you calling the Add() function in your last line?
Also, Michel, your popup rewrite, which is much nicer than the one I had, is fine in EE but not opening in Mozilla/FF.  I fixed a missing ")" and changed the JS filename, here is the latest, maybe tiny error?

function showPopUp(divName) {
     var features = "height=350,width=350,scrollbars=yes,status=no,menubar=no,location=no";
     var pgName = "cntPage" + divName;
     var win = window.open('', pgName, features);
     var elem = document.getElementById(divName);
     var hasProblem = (!document.all && typeof HTMLElement != "undefined");
     win.document.write("<TITLE>" + divName + " Information</TITLE>");
     win.document.write("<LINK REL='stylesheet' HREF='default.css' TYPE='text/css'>");
     win.document.write("<script src='add.js' type='text/javascript'></script\>");
     win.document.write((hasProblem)?parseHTML(elem.innerHTML):elem.innerHTML);
     win.document.bgColor = "#F8F6F4";
     win.document.close(); // Should be done always
     win.focus();
}
Yes, sorry about the missing )
Do you have a popup blocker active in FF?
Look in the javascript console to see if you have a
"win" has no properties

then try

function showPopUp(divName) {
     var features = "height=350,width=350,scrollbars=yes,status=no,menubar=no,location=no";
     var pgName = "cntPage" + divName;
     var win = window.open('', pgName, features);
     if (!win) {
        alert('Please allow popups for this site')
         return
     }
     var elem = document.getElementById(divName);
     var hasProblem = (!document.all && typeof HTMLElement != "undefined");
     win.document.write("<TITLE>" + divName + " Information</TITLE>");
     win.document.write("<LINK REL='stylesheet' HREF='default.css' TYPE='text/css'>");
     win.document.write("<script src='add.js' type='text/javascript'></script\>");
     win.document.write((hasProblem)?parseHTML(elem.innerHTML):elem.innerHTML);
     win.document.bgColor = "#F8F6F4";
     win.document.close(); // Should be done always
     win.focus();
}

what does the code look like that calls the showPopUp()
?
very basic - <A href="#"onclick="showPopUp('sweet');return false;">Sweet</A>

I disabled popups, but it was working in other code before you rewrote, even with popup blocker on.  I can always go back to earlier code for testing, that is not so important as solving main hurdles -

Main issues are:  
(1) popup is now changing the checkbox state of the parent page, very happy to get it working !!
(2) need to do reverse now, have main page change checkbox state of popup IF it is opened, and
(3) still need to toggle display of span - "block":"none" - of main from popup, and viceversa.

Working code for popup is now  (only display toggle of span in parent (last line not working) --

function Add(ckbx,frm,spName,price) {
  var on = ckbx.checked;
  var el = document.getElementById(spName);
  if (el) el.style.display = (on)?"block":"none";

  window.opener.document.forms[ckbx.form.name].elements[ckbx.name].checked = ckbx.checked
  window.opener.Add(document.forms[ckbx.form.name].elements[ckbx.name],spName);
}

Working code for main parent page is --

function Add(ckbx,frm,spName,price) {
  var on = ckbx.checked;
  var el = document.getElementById(spName);
  if (el) el.style.display = (on)?"block":"none";
}

this is not doing anything to popup yet, need to get last two lines of popup code working in reverse.

something like ?  - if win['frm'] then ....  -- BTW, frm name is same as DIV name, once again, only a name, not an object.  Can easily drop passing the form name, thought it would help but evidently not?

Still not sure why "Add" is in that last line of popup code, are you calling function on main page?  Add() is only a function, not DIV, not form, or checkbox name.
ASKER CERTIFIED SOLUTION
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks for great help and input, time to close Q and give points, I try to work it through from here.
Good night :)