Run Function for a Specific Form on Parent Page When Readonly Field Gets New Value from Popup, or When Popup Closes

My parent page has dozens of separate forms (each row of an html table is its own form; one form per row). When any pre-populated data is changed, an onKeyUp event in that form field triggers an AJAX function to instantly update the server data for that specific form/row. Then an onChange event fires an alert ('Edits were saved').  That all works great.
     The problem is, some fields are readonly; they don't have an onKeyUp event because their data is changed only by selecting something from a popup.
    I can't use an onChange event, either, because no onChange event is triggered when a textbox gets a different value sent from a popup.
   The onFocus won't work, because I'm using a mouse click or onFocus event to trigger the popup function. So either of those events would be too soon, before the data comes back from the popup.
   I tried onBlur, but it keeps firing over and over again.

So maybe what I need is some code that will just detect that the popup was popped from that specific form, and the close event of the popup will trigger the AJAX function for that specific form on the parent page.

The code snippet shows a couple of examples of rows / forms (one uses a function that raises a popup window that contains a selectbox, and the other uses a function that raises a date-picker).


For regular fields where they can type to change the data, I just use:    
     onKeUp="ajaxFunction(this.form);" onChange="alert('Saved edits');"

What code would detect the change made in  readonly  fields (by bringing in data from the popup, or by the closing of the popup) and trigger the AJAX function as coming from the correct form (this.form)?

I'm trying to call this function from the popup function in the parent, to check if the child has been closed (and, if so, run the AJAX function), but this is not working; it is not detecting when the window is closed:

function testmywindow() {
 if (!pops[cnt].closed) {
  window.status="Child still open";
 } else {
 window.status="Child Closed.";
 ajaxFunction();
 alert('Edits were saved');
 }
}
<script type="text/javascript">
var currentField = new Array();
var pops = new Array();
var cnt = 0;
 
function windowopen(fld) {
  currentField[cnt]=fld;
 
 pops[cnt]=window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");
 
setInterval("testmywindow();",500);
 
  cnt++;
}
 
function testmywindow() {
 if (!pops[cnt].closed) {
  window.status="Child still open";
 } else {
 window.status="Child Closed.";
 ajaxFunction();
 alert('Edits were saved');
 }
}
</script>
 
// JS popup function is called using (this.form), like this:
 
<tr>
<form name="frm_1" id="frm_1">
<td><input READONLY type="text" name="book" id="book" value="Animals" onClick="windowopen(document.frm_1.book); return false" onChange="ajaxFunction(this.form); alert('Saved edits');"></td>
<td> . . . [other <td>'s and fields] . . . </td>
</form>
</tr>
 
// ---------------------------------------
// also calling popup date-picker calendars, like this:
 
<tr>
<form name="frm_2" id="frm_2">
<td> . . . [other <td>'s and fields] . . . </td>
<td><input READONLY type="text" name="date" id="date" value="01-31-08" onClick="show_calendar('frm_2.date', '', '', '', 100, 240);" onChange="ajaxFunction(this.form); alert('Saved edits');"></td>
</form>
</tr>

Open in new window

FrankTechAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Michel PlungjanIT ExpertCommented:

function testmywindow() {
 if (!pops[cnt].closed) {
  window.status="Child still open";
 } else {
 window.status="Child Closed.";
  if (currentField[cnt].defaultValue==currentField[cnt].value) return;
 ajaxFunction();
 alert('Edits were saved');
 }
}

0
FrankTechAuthor Commented:
mplungjan,
   Thanks, but that is not working, either.  The alert never fires.

I also tried this in my popup function, and it fires an alert when the window is opened, but does nothing when it is closed:

 var newwindow= window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");

if (newwindow) {
 window.alert('still open');
 } else {
 window.alert('closed window');
 }


Then I moved that into a function, and it never alerted at all, not even when the window first opened.  Like this:

function windowopen(fld) {
 . . . .
  var newwindow= window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");

setInterval("testmywindow2();",500);
}


function  testmywindow2
function testmywindow2() {
if (newwindow) {
 window.alert('still open');
 } else {
 window.alert('closed window');
 }
}

That function apparently never fired.  Why not?  


Or is there any way to put some inline code into my readonly textbox, like this:

  if (this.value!==this.defaultValue) {ajaxFunction(); alert('Edits were saved');}

    There would have to be some even to trigger that comparison, right? But it seems like there is no event that can work when the value has been changed only by receiving a new value from a popup.  What to do?
0
FrankTechAuthor Commented:
Can we do something like this?  But how to pass the  currentField[cnt]  to it?

IN CHILD:
     <body onUnload="opener.tellParent()">

IN PARENT:

function tellParent() {
 alert('Child closed');
   if (currentField[cnt].defaultValue==currentField[cnt].value) return;
 ajaxFunction();
 alert('Edits were saved');
}
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

FrankTechAuthor Commented:
This is what I have currently, and the alert comes up when the child window is closed (but the next part never fires:

   if (currentField[cnt].value!==currentField[cnt].defaultValue) {
     ajaxFunction();
     alert('Edits were saved');
   }

I think it's because the    currentField[cnt]   is not getting passed from the child into this parent function.
    The Child has:  <body onUnload="opener.tellParent(opener.currentField[cnt]);">

    How can I pass the   opener.currentField   into the parent function ?
<script type="text/javascript">
var currentField = new Array(); // make global
var pops = new Array();
var cnt = 0;
function windowopen(fld) {
  currentField[cnt]=fld;
 pops[cnt]= window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");
 
  cnt++;
}
 
function tellParent() {
 alert('window closed');
   if (currentField[cnt].value!==currentField[cnt].defaultValue) {
     ajaxFunction();
     alert('Edits were saved');
   }
}
</script>

Open in new window

0
FrankTechAuthor Commented:
And the ajaxFunction expects a form object:

 function ajaxFunction(frmObj) {

 var ID = frmObj.ID.value;

. . . etc.
}

Even if I could get  opener.currentField   from the child, passed into the parent function, how would I get the  frmObject ?
0
Michel PlungjanIT ExpertCommented:
This should not need to look at what happens when the window closes:
In any case you need to clear the interval

function setField(fld,cnt) {
  this.fld=fld
  this.tId = setInterval("testmywindow("+cnt+");",500);
}
function windowopen(fld) {
  currentField[cnt]=new setField(fld,cnt);
 pops[cnt]=window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");
   cnt++;
}
 
function testmywindow(cnt) { // pass the correct cnt and not the incremented
  if (currentField[cnt].fld.value!==currentField[cnt].fld.defaultValue) return;
  clearInterval(currentField[cnt].tId)
  ajaxFunction(currentField[cnt].fld.form);
}

0
FrankTechAuthor Commented:
mplungjan,
    That is not working for me. It is not even copying the selected value from the child page into the parent page's textarea. And it is not firing any alert or ajaxFunction.
    Maybe I made a mistake in putting the functions into the script?  Here's the whole script so you can see if I did something wrong:
<script type="text/javascript">
var currentField = new Array(); // make global
var pops = new Array();
var cnt = 0;
function setField(fld,cnt) {
  this.fld=fld
  this.tId = setInterval("testmywindow("+cnt+");",500);
}
function windowopen(fld) {
  currentField[cnt]=new setField(fld,cnt);
 pops[cnt]=window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");
   cnt++;
}
 
function testmywindow(cnt) { // pass the correct cnt and not the incremented
  if (currentField[cnt].fld.value!==currentField[cnt].fld.defaultValue) return;
  clearInterval(currentField[cnt].tId)
  ajaxFunction(currentField[cnt].fld.form);
}
</script>

Open in new window

0
FrankTechAuthor Commented:
Isn't it possible to simply pass the  opener.currentField   from the child to the   tellParent function in the parent?

The Child has:  <body onUnload="opener.tellParent(opener.currentField[cnt]);">

But I can't get it into the function.  When I tried putting  function tellParent(currentField[cnt])  it stopped giving the   alert('window closed').  Is there any way to pass the value into the parent function, and then tell the ajaxFunction which form it came from? (Because the  ajaxFunction expects a   frmObj  as its argument.)
 
function tellParent() {
 alert('window closed');
   if (currentField[cnt].value!==currentField[cnt].defaultValue) {
     ajaxFunction();
     alert('Edits were saved');
   }
}
0
FrankTechAuthor Commented:
The regular type-in fields  pass the  frmObj  to the ajaxFunction like this:
      onKeUp="ajaxFunction(this.form);"

The  readonly fields are opened by clicking on them. How can we pass (this.form) into the   windowopen  function for the readonly fields, along with the  "currentField" -- because the ajaxFunction (called from within the windowopen function) will need to get the frmObj  from  this.form .
0
Michel PlungjanIT ExpertCommented:
Sorry I had a major typo

 if (currentField[cnt].fld.value!==currentField[cnt].fld.defaultValue) return;


should of course be

 if (currentField[cnt].fld.value==currentField[cnt].fld.defaultValue) return;

0
FrankTechAuthor Commented:
OK, but even with that change, it still won't work.  The value coming from the Child is not getting copied into the Parent's textfield.   And no alert or ajaxFunction is triggered - maybe because the field's value is not changing.

What could be preventing the Child from pasting its value into the parent's form field? Maybe it's losing track of which field to put it in?

Exactly what line of this code actually pastes the value into the parent's textfield?

Here's the whole script that I'm using, just in case you might spot some other typo:
<script type="text/javascript">
 var currentField = new Array(); // make global
 var pops = new Array();
 var cnt = 0;
 
function setField(fld,cnt) {
  this.fld=fld
  this.tId = setInterval("testmywindow("+cnt+");",500);
}
 
function windowopen(fld) {
  currentField[cnt]=new setField(fld,cnt);
 pops[cnt]=window.open("child.php?"+cnt,"mywindow","width=430,height=460,scrollbars=no,status=no;left=40,top=40");
   cnt++;
}
 
function testmywindow(cnt) { // pass the correct cnt and not the incremented
  if (currentField[cnt].fld.value==currentField[cnt].fld.defaultValue) return;
     alert('in conditional after popup close');
  clearInterval(currentField[cnt].tId)
  ajaxFunction(currentField[cnt].fld.form);
}
</script>

Open in new window

0
Michel PlungjanIT ExpertCommented:
where is the code from the child???

You need to do

opener.currentField[location.search.substring(1)].value='somevalue'

assuming you have child.php?3 for the field accessed the fourth time the window was popped
0
FrankTechAuthor Commented:
The Child has that kind of string in it.

     Anyway, I have posted a simplified example ( http://216.92.58.65/parent.htm ), which shows I have found a way to make the parent form run a function that compares the field value to the default value when the Child closes.

    If you play around with the different input fields, you'll see that all are firing the ajaxFunction and the Price field is passing the  frmObj  to the ajaxFunction properly.
    But the Title field is not passing a frmObj to the ajaxFunction.  That's the part that I need to fix now.

    Is there a way to pass the frmObj to the Child window, and back into the tellParent function? If we can do that, I think the problem is solved.
  Please see the example at:
http://216.92.58.65/parent.htm
0
FrankTechAuthor Commented:
Well, I take part of that back. It maybe it is not really comparing the new value to the default value. But the rest of it seems to work like I said.
0
FrankTechAuthor Commented:
mplungjan,
    Any further ideas?  There must be some way to make it work.
0
Michel PlungjanIT ExpertCommented:
Iwill take a look. I am in CET so I was not online
0
Michel PlungjanIT ExpertCommented:

function tellParent(fld) {
   alert('window closed for field'+fld);
   if (fld.value!==fld.defaultValue) {
     ajaxFunction(fld.form);
   }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
FrankTechAuthor Commented:
OK. That seems to work fine now. I appreciate your expert assistance. Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.