Solved

How to use Javascript to submit page in background that queries database and pulls info to fill in the remaing form?

Posted on 2004-03-29
11
9,839 Views
Last Modified: 2013-12-24
I would like to be able to do this, without refreshing page and without submitting to a new form.

After user fills in color type via radio button, have a JS to query a database and find all matches for the color entered and
return those matches so that remaining form fields are filled in.

I only need this for IE browser (not any of the others).

Is there a quick way to do this?

Thanks In Advance.
Trainmom
0
Comment
Question by:trainmom
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 35

Accepted Solution

by:
mrichmon earned 500 total points
ID: 10706062
Okay this is done in a few steps.

Step 1) include the following file as a javascript file and save as iFrameRPC.js

// ****************BEGIN FILE******************************************
var IFrameObj; // our IFrame object

function callToServer(backgroundURL) {
      if (!document.createElement)
      {// todo :: implement some kind of redirection if browser doesn't support creating of dom object
            return true;
      }
        
      var IFrameDoc;
      var URL =  backgroundURL;
      if (!IFrameObj && document.createElement)
      {// create the IFrame and assign a reference to the object to our global variable IFrameObj.
            // this will only happen the first time callToServer() is called
            try
            {
                  var tempIFrame=document.createElement('iframe');
                  tempIFrame.setAttribute('id','RSIFrame');
                  tempIFrame.style.border='0px';
                  tempIFrame.style.width='0px';
                  tempIFrame.style.height='0px';
                  IFrameObj = document.body.appendChild(tempIFrame);
                  
                  if (document.frames)
                  {// this is for IE5 Mac, because it will only allow access to the document object
                  // of the IFrame if we access it through the document.frames array
                        IFrameObj = document.frames['RSIFrame'];
                  }
            }
            catch(exception)
            {// This is for IE5 PC, which doesn't allow dynamic creation/manipulation of iframe object.
                  // Instead, we'll fake it up by creating our own objects.
                  iframeHTML='\<iframe id="RSIFrame" style="';
                  iframeHTML+='border:0px;';
                  iframeHTML+='width:0px;';
                  iframeHTML+='height:0px;';
                  iframeHTML+='"><\/iframe>';
                  document.body.innerHTML+=iframeHTML;
                  IFrameObj = new Object();
                  IFrameObj.document = new Object();
                  IFrameObj.document.location = new Object();
                  IFrameObj.document.location.iframe = document.getElementById('RSIFrame');
                  IFrameObj.document.location.replace = function(location) {this.iframe.src = location;}
            }
      }            
 
      if (navigator.userAgent.indexOf('Gecko') !=-1 && !IFrameObj.contentDocument)
      {      // we have to give NS6 a fraction of a second
             // to recognize the new IFrame
             setTimeout('callToServer()',10);
             return false;
      }
 
      if (IFrameObj.contentDocument)
      {      // For NS6
            IFrameDoc = IFrameObj.contentDocument;
      }
      else if (IFrameObj.contentWindow)
      {      // For IE5.5 and IE6
            IFrameDoc = IFrameObj.contentWindow.document;
      }
      else if (IFrameObj.document)
      {      // For IE5
             IFrameDoc = IFrameObj.document;
      }
      else
      {
            return true;
      }
 
      IFrameDoc.location.replace(URL);
      return false;
}
//*****************END FILE***********************


(Watch out for some wrapping (due to forum) of above that should be on one line....)

That page always stays the same.

Then on the page that will do the call it will look something like this :


<!--- HTML/CF page with the form the user fills out --->
<html>
<head>
<title>Background Submit Example Page</title>
<script type="text/javascript" language="JavaScript" src="scripts/iframeRPC.js"></script>
<script type="text/javascript" language="JavaScript">
function LookupISBN(i)
{
      var ISBN = eval("document.TextbookAdoptionForm.ISBN_" + i).value;
            
      if (ISBN != "")
      {      // If an ISBN was entered then look it up in our DB
            callToServer("RPC_TextbookLookup.cfm?ISBN=" + escape(ISBN) + "&ID=" + i);
      }
}

function ISBNLookupComplete(ID, Found, Title, Author, Publisher, Edition)
{      
      if(Found)
      {      // ISBN in DB so fill in data
            eval("document.TextbookAdoptionForm.Title_" + ID).value = Title;
            eval("document.TextbookAdoptionForm.Author_" + ID).value = Author;
            eval("document.TextbookAdoptionForm.Publisher_" + ID).value = Publisher;
            eval("document.TextbookAdoptionForm.Edition_" + ID).value = Edition;
      }
      return;
}
</script>
</head>
<body>
<form name="myform" method="post" action="destination.cfm">
      ISBN:<input type="text" name="ISBN_1" id="ISBN_1" onBlur="LookupISBN(#i#);">
      Title:<input type="text" name="Title_1" id="Title_1" size="50" maxlength="60">
      Author:<input type="text" name="Author_1" id="Author_1" size="50" maxlength="60">
      Publisher:<input type="text" name="Publisher_1" id="Publisher_1" size="50" maxlength="60">
      Edition:<input type="text" name="Edition_1" id="Edition_1" size="50" maxlength="60">
etc...
</form>
</body>
</html>

Note that the action of the form is where you want the final form submitted to - not the background submit that will fill in the rest of the fields, but the page that will store the final submitted results (auto filled in fields AND user filled in fields)

Also note that the only field that has the onBlur event (this could also be onChange or onClick, etc) is the ISBN field or in your case the radio buttons.

The javascript include inthe head of the page includes the above iFrame file.
The two functions in the head of the page work as follows:

The LookupISBN function is called on the event such as onBlur.  It does a submit to the page I called RPC_TextbookLookup.cfm which has any variables passed in the URL.  I pass the ISBN and the ID of the field (since I actually have a dymnamic set of fields so that more than one textbook can be done at a time)

The code on the RPC_TextbookLookup.cfm page looks like this :

<cfset CleanISBN = REReplace(Ucase(URL.ISBN), "[^0-9,X,B]", "", "ALL")>
<cfquery datasource="myDSN" name="LookupTextbook">
      SELECT Title, Author, Publisher, Edition
      FROM mytable
      WHERE ISBN = <cfqueryparam cfsqltype="cf_sql_varchar" value="#CleanISBN#">
</cfquery>

<cfif LookupTextbook.RecordCount EQ 0>
      <cfset Found = false><!--- Did not find Textbook; set other fields to blank --->
      <cfset Title = "">
      <cfset Author = "">
      <cfset Publisher = "">
      <cfset Edition = "">
<cfelse>
      <cfset Found = true><!--- Found Textbook; set other fields to DB values --->
      <cfset Title = LookupTextbook.Title>
      <cfset Author = LookupTextbook.Author>
      <cfset Publisher = LookupTextbook.Publisher>
      <cfset Edition = LookupTextbook.Edition>
</cfif>

<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<cfoutput>
<body onLoad="window.parent.ISBNLookupComplete(#URL.ID#, #Found#, '#Title#', '#Author#', '#Publisher#', '#Edition#');">
</body>
</cfoutput>
</html>

SO as soon as this page is called the CF runs and when the page is done loading the Javascript function runs.  The javascript line calls the 2nd function that was in the head of the html or cf page with the form and that populates the fields with the data if it was found.

Let me know if you have any questions and I can explain further.
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 10706191
The iFrameRPC.js file never changes for any pages that you ever want to use theis background submit.

The HTML page simply has your form, a function that gets called on the user action, and the function that fills in the return results.  So the 2 Javascript functions in the head and the form are the only things that need to be modified.

The last CF page - which is really short - only needs to have the query modified to pull your results (notice the parameters get passed via URL - but as this is done in the background the user never sees the URL so it can be as messy as necessary).  Then the call to the last javascript function back on the main page is how you pass back the data.

SO really there are 3 pages involved - but only 2 of those need to be modified.
0
 
LVL 17

Expert Comment

by:anandkp
ID: 10711449
How abt having a cfm page in one of the frame - that is just sized 1x1 pixels.

so once the user fills in the details - this page inside the frame can do the necessary processing for u !
It cld then refresh the other page inside ur frame window to show the relavent matches.

let me know ...

K'Rgds
Anand
0
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 
LVL 35

Expert Comment

by:mrichmon
ID: 10714722
The point was to do a submit WITHOUT refreshing the page.  There are a lot of methods that work if you refresh the page, but this is one of the only ways to do it without refreshing the page.
0
 
LVL 2

Expert Comment

by:n4nazim
ID: 10738920
Hi,

Here is what u can do ...

The page wld consist of two frames.

Left Frame: This would be hidden ( say keep width of this as zero ). This frame will consists of all the processing which is required to display the page. This would not contain ANY HTML interface.

RightFrame: This would purely contain the HTML interface with some division's. When the page is loaded, the Right frame ( only being HTML ) loads very fast giving an idea that the page loaded quicky. U can show the indicator GIF file saying "Processing ... Please wait .." or something like that. When the Left frame processing is finished, it would update the Right frame with proper values.

Hope this is what u require ...
Rgds,
Nazim M
0
 

Author Comment

by:trainmom
ID: 10750203
mrichmon.

Sorry it has taken me so long to test this out, but your explanations were so Great and logical...
However, when I (today) tried to make it work... the first error is in this line

 ISBN:<input type="text" name="ISBN_1" id="ISBN_1" onBlur="LookupISBN(#i#);">

It burps on the # sign.

I removed the # sign... and now I don't exactly know what we are passing with the i variable.
Thanks
Carol
0
 

Author Comment

by:trainmom
ID: 10750221
mrichmon,
one more thing, i set up a test db exactly like yours (ISBN, author, publisher, etc) to test this out
and changed the references
from:
eval("document.TextbookAdoptionForm.Author_" + ID).value = Author;
to
eval("document.myform.Author_" + ID).value = Author;

Can you explan a little more about passing the i variable in this
stagement
ISBN:<input type="text" name="ISBN_1" id="ISBN_1" onBlur="LookupISBN(#i#);">

Thanks.... I know this will work with a little more tweaking....
Carol

0
 

Author Comment

by:trainmom
ID: 10752437
ok, after some sleep, I now  think that the #i# is part of some cflooping and cfoutput functions that you do since you have dynamic fields.

trainmom
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 10757960
Yep  the passing in of #i# lets the javascript know which field to write the results back to since there could be any number of fields with the prefix of "Author_"
0
 
LVL 1

Expert Comment

by:Paulio
ID: 10909914
Well, I'm seeing a lot of code for something that I think might be pretty simple [correct me if I'm wrong]
I think this might be the/a solution:

##### begin html page #####
<html><head><title>test color selection</title></head>
<body>
<!---// iframe were color will be sent to, and form values will be filled in from //--->
<iframe src="about:blank" id="hiddenframe" width=1 height=1 frameborder=1 style="display:none"></iframe>
<!---// script that submits the color via query string to processing page //--->
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
  function fillform(colorvalue){
    document.frames['hiddenframe'].location.replace('fill_colorform.cfm?color='+colorvalue);
  }
//-->
</SCRIPT>
<!---// example form: the onClick fires the js action //--->
<form action="somepage.cfm" name="colorform">
  choose color:<br>
  <input type="radio" name="color" id="color1" value="FF0000" onClick="fillform(this.value)">
    <label for=color1>Red</label><br>
  <input type="radio" name="color" id="color2" value="00FF00" onClick="fillform(this.value)">
    <label for=color2>Green</label><br>
  <input type="radio" name="color" id="color3" value="0000FF" onClick="fillform(this.value)">
    <label for=color3>Blue</label><br>
  Some form values to be filled in:<br>
  <input type=text name=fillme1 size=10><br>
  <input type=text name=fillme2 size=10><br>
</form>
</body></html>
###### end html page ####

### begin coldfusion page 'fill_colorform.cfm' #####
<!---// if a color is passed to this page //--->
<cfif IsDefined("url.color")>
  <!---// you can do some checking for valid hex color... //--->
  <!---// query the DB //--->
  <cfquery name="findcolor" datasource="yourDB">
    SELECT name, description
    FROM colors
    WHERE color = '#url.color#';
  </cfquery>
  <!---// output the results in js, so the (parent) form will be filled
  In this example, I assume there will be only one record found...
  (if more are found, only the last record will fill the form) //--->
  <cfoutput query="findcolor">
    <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
    <!--
      if(!parent){ alert('geen parent'); }
      else if (!parent.document){ alert('geen parent.document'); }
      else if (!parent.document.colorform){ alert('geen parent.document.colorform'); }
      var theform = parent.document.colorform;
      theform.fillme1.value = '#findcolor.name#';
      theform.fillme2.value = '#findcolor.description#';
      // etc.
    //-->
    </SCRIPT>
  </cfoutput>
</cfif>

<!---// if no color is passed to this form, or no records were found, we will clear the form //--->
<cfif NOT IsDefined("url.color") OR findcolor.recordcount EQ 0>
  <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
  <!--
    var theform = parent.document.colorform;
    theform.fillme1.value = '';
    theform.fillme2.value = '';
    // etc.
  //-->
  </SCRIPT>
</cfif>
###### end coldfusion page ######

#### tabel designed to work with example ####
table: colors,
columns: color,name, description (all text)
####

Hope this is the solution you were waiting for...
0
 
LVL 1

Expert Comment

by:Paulio
ID: 10909921
oops...

I left in some checks which shouldn't be there:

In the example cf page, the first js block, leave out these first three sentences:

      if(!parent){ alert('geen parent'); }
      else if (!parent.document){ alert('geen parent.document'); }
      else if (!parent.document.colorform){ alert('geen parent.document.colorform'); }

(Not that they will do harm)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
When it comes to security, close monitoring is a must. According to WhiteHat Security annual report, a substantial number of all web applications are vulnerable always. Monitis offers a new product - fully-featured Website security monitoring and pr…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question