Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Javascript fills second field. Info lost if user goes "Back" 1

Status
Not open for further replies.

DuncanKing

Programmer
Jan 14, 2004
32
IE
I have field in a form that is filled depending on the option that a user selects from the previous field.

Eg "Model" is filled with all the Models available if a user selects a particular "Make."
This works well.

Here the code I have:
<select name="Make" onChange="fillSelectFromArray(this.form.Model, ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));">

After the user has filled out the form and clicks "Next" it brings them to a page that lets them review the information entered. If they agree they press "Submit" and the information is entered into the DB. However, if they want to change something and go back to the previous page to change information on the form, the filled information in the second field disappears. Is there a piece of code that will keep the information that was in the "filled field"?

The code I have for "go back" is

<form>
<input type="button" value="Back to Previous Page"
onClick="javascript: history.go(-1)">
</form>

Thanks all...

 
Using server-side code you could persist the data in session variables so they would not be lost when changing pages.

I think that trying to maintain the data for pages they have already visited and left is going to be problematic and inconsistent in different browsers using client-side code.

An alternative to server-side code though would be to have your form and review page be one and the same.
When they fill out the form and click submit call a function that hides the form section and displays the review section, filling in the current form fields values.
If they decide to make a change you just hide the review section and unhide the form section.

The drawback to this of course is that you are using client-side script and if they disable Javascript the form is not going to work. But given your question you are relying on javascript functionality anyway.

Again though, server-side code would be the overall safest way to keep the data available to the browser.




Stamp out, eliminate and abolish redundancy!
 
Thanks for these suggestions.

Do you have any sample code for the function or have suggestions where I might look?

I'm using javaccript because the model info is in a .js file called by the code above.

Thanks
 
Here is a quick and dirty example.
What it does is creates two versions of the page.
The first version is the entry form in the first div, the review version in the second div.
The review version is set to display: none to start with so it does not show up.

When the user fills out the form and clicks Submit it executes the function to first hide the entry form, copy the values entered in the entry form to the fields in the review form and then sets the display to inline for the review form div.
If they select the option in the review form to make changes all it does it turn off the display of the review form and turn on the display of the entry form.
The page never has to reload so it is a lot cleaner for the clients. Of course this relies on Javascript being enabled.

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"[URL unfurl="true"]http://www.w3.org/TR/html4/loose.dtd">[/URL]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Form Test</title>
<SCRIPT type="text/javascript">

function showform()
{
  //Hide the review form
  document.getElementById('reviewForm').style.display = 'none';

  //Show the form
  document.getElementById('myForm').style.display = 'inline';
}

function showreview()
{
  //Hide the form
  document.getElementById('myForm').style.display = 'none';

  //Set the field values from the form to the review form.
  document.getElementById('reviewfirstname').value = document.getElementById('firstname').value;
  document.getElementById('reviewlastname').value = document.getElementById('lastname').value;
  //Show the review form
  document.getElementById('reviewForm').style.display = 'inline';
}
</SCRIPT>
</head>
<body>

<div id="myForm">
<H1>My Form</H1>
  First Name: <input type="text" id="firstname"><br>
  Last Name: <input type="text" id="lastname"><br>
 <input type="button" value="Submit Form" onclick="showreview()">
</div>
<div id="reviewForm" style="display: none;">
<H1>Please Review</H1>
  First Name: <input type="text" id="reviewfirstname" readOnly><br>
  Last Name: <input type="text" id="reviewlastname" readOnly><br>
  <input type="submit" value="Accept Values"> <input type="button" value="Change" onclick="showform()">
</div>
</body>
</html>

Stamp out, eliminate and abolish redundancy!
 
Thanks I'm going with the jc solution.

However, I can't get the jc fill in to work.

I have substituted firstName and lastName with "make" and "model". The "make" field has a dropdown list and "model" options are supposed to be filled in according to the selection made. I can get this and your code to work separately but when combined I can't get the fill in to work.
Any suggestions as to what the problem might be?

I have included the src reference to the jc where the model info is keep between the <head> tags :

<SCRIPT type="text/javascript" language="javascript" src="model.js">
...code...
</script>

..and changed the variable names in the script.

The make code is:
<select name="Make" onChange="fillSelectFromArray(this.form.Model, ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));">

followed by the option values=...

This is the piece of code for the "Model" field.
<select name="Model" size="1" >
<option> </option>
</select>

Do I have to change any the above code?
 

PS

I think the problem is with this statement:

<input type="text" id ="firstname" >

I guess the problem is how to get a dropdown list to accept an input "type" and does the variable attribute name have to be "id" or could it be "name" as in <select name=...>

Thanks
 
I cannot tell much from the code you provided because I cannot see the other functions.
However, I do see that you only have a NAME attribute for the select box. My code uses the DOM getElementById method so it needs to have an ID tag of the appropriate name.

The names of the fields should differ between the entry form and the review form.
The review form should probably just have a text box to show the selected value since at that point they do not have the option of changing the values.

Here is a modified version using two select boxes for the main form and text boxes in the review form.
You should be able to add your code into these for populating the options.
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"[URL unfurl="true"]http://www.w3.org/TR/html4/loose.dtd">[/URL]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Form Test</title>
<SCRIPT type="text/javascript">

function showform()
{
  //Hide the review form
  document.getElementById('reviewForm').style.display = 'none';

  //Show the form
  document.getElementById('myForm').style.display = 'inline';
}

function showreview()
{
  //Hide the form
  document.getElementById('myForm').style.display = 'none';

  //Set the field values from the form to the review form.
  document.getElementById('reviewMake').value = document.getElementById('Make').options[document.getElementById('Make').selectedIndex].value;
  document.getElementById('reviewModel').value = document.getElementById('Model').options[document.getElementById('Model').selectedIndex].value;
  //Show the review form
  document.getElementById('reviewForm').style.display = 'inline';
}
</SCRIPT>
</head>
<body>

<div id="myForm">
<H1>My Form</H1>
  Make: <select name="Make" id="Make">
  <option value="Select One">Select One</option>
  <option value="Option One">Option One</option>
  <option value="Option Two">Option Two</option>
  </select><br>
  Model: <select name="Model" id="Model">
  <option value="Select One">Select One</option>
  <option value="Option One">Option One</option>
  <option value="Option Two">Option Two</option>
  </select><br>

 <input type="button" value="Submit Form" onclick="showreview()">
</div>
<div id="reviewForm" style="display: none;">
<H1>Please Review</H1>
  Make: <input type="text" id="reviewMake" readOnly><br>
  Model: <input type="text" id="reviewModel" readOnly><br>
  <input type="submit" value="Accept Values"> <input type="button" value="Change" onclick="showform()">
</div>
</body>
</html>




Stamp out, eliminate and abolish redundancy!
 
Guess my explanation was in process when you posted again.
Yes, you have to have the ID tag because of the DOM method I use to get the values.
The other difference is the method of retrieving a selected value from a select box as opposed to a text box.

Give the new code a try and see if it works for you.

Stamp out, eliminate and abolish redundancy!
 
Thanks again for this.

Yes, I agree, just text box for review is good.

With the new code, do I have to hard code the Model options in the Model option tags. I have a file called "model.js" with all the model info in it which I call using the src attribute and have that working but does not persist when I press the back button..i.e. the problem e.g.

<SCRIPT type="text/javascript" language="javascript" src="model.js">

The code I have in the Make now looks like this:

<div id="myForm">
<H1>My Form</H1>
Make:
<select name="Make" id= "Make" onChange="fillSelectFromArray(this.form.Model, ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));">
<option="" selected>Select a Make</OPTION>
<option value="Acura">Acura </option>
<option value="Austin">Austin </option>

The code I have for Model is this and they get the values from the file model.js.
Model:
<select name="Model"id="Model" size="1" >
<option></option>
</select>
Note: I substituted this for your model code.

Should your code work with this or are some changes needed?
I'd perfer to do it this way if I can get it to work.
 
Yes, you can modify it with your own options, I just put a few in static so you could see the form work. And the onchange event has no impact on the other code, that only works when you press the appropriate button so it should be good to go, you just rework the two forms to look any way you want them to.


Stamp out, eliminate and abolish redundancy!
 


This does not dynamically fill the second field.

If Ford is selected as the Make, then the Model field should "fill" with all the Ford models. Similarly if BMW is select as the Make, alll the BMW models should fill in the Model fields. The code the follows does not seem to do that.

<div id="myForm">
<H1>My Form</H1>
Make: <select name="Make" id="Make">
<option value="Select One">Select One</option>
<option value="Option One">Option One</option>
<option value="Option Two">Option Two</option>
</select><br>
Model: <select name="Model" id="Model">
<option value="Select One">Select One</option>
<option value="Option One">Option One</option>
<option value="Option Two">Option Two</option>
</select><br>

<input type="button" value="Submit Form" onclick="showreview()">
</div>
 
No, my code is just for handling the entry and review pages. You have to add your code in to do the fills. I thought you already had that part working? You just have to add that bit of your script into my code.


Stamp out, eliminate and abolish redundancy!
 


Yes I have that bit working on its own but when combined with your code it doesn't work. I'll play around with it again later tonight and let you know what happens.

Thanks for all your help.
Duncan
 
Make sure your form name matches. My example had a different name than "form"

You have to change things.
onChange="fillSelectFromArray(this.form.Model, ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));"

Stamp out, eliminate and abolish redundancy!
 

I have tried changing "form" to "myForm" and other combinations and no joy?

Interestingly, if I combine the 2 script statements like this

<SCRIPT type="text/javascript" script LANGUAGE="javascript" src="model.js">

the review form doesn't work. But if I use 2 separate script statements

<script LANGUAGE="javascript" src="model.js"></script>
and your script the review form works.

I would have thought that I could have combined the two as I have included the src attribute for the Model.js in the combined statement.

Both the forms work really well when other "non fill" variables are used and I'd really like to get this working, so if you have other suggestions that I could try I'd appreciate it.

Thanks


 
You would use two different script tags.
<SCRIPT type="text/javascript" src="YOURCODE.js"></script>
<script type="text/javascript" src="MYCODE.js"></script>

Or you put my functions into your own .js file and just use the one script tag.

You really need to post your code for me to be of any further help. It all has to do with the way you are blending the code together and I can't even begin to guess at what is wrong if I can't see it.
It would be good to post the .js code as well.

When I am writing code I always leave the javascript functions IN the main file to make debugging easier. Once everything is working it is easy to take it out and put it in a .js file. Otherwise you are editing two or more files while trying to debug your code. The same goes for any CSS files...


Stamp out, eliminate and abolish redundancy!
 
Note: the file name is form_1.cfm

Here's the code for the form:
Thnaks...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Form Test</title>

<script LANGUAGE="javascript" src="model.js"></script>

<SCRIPT type="text/javascript">

function showform()
{
//Hide the review form
document.getElementById('reviewForm').style.display = 'none';

//Show the form
document.getElementById('myForm').style.display = 'inline';
}

function showreview()
{
//Hide the form
document.getElementById('myForm').style.display = 'none';

//Set the field values from the form to the review form.
document.getElementById('reviewMake').value = document.getElementById('Make').options[document.getElementById('Make').selectedIndex].value;
document.getElementById('reviewModel').value = document.getElementById('Model').options[document.getElementById('Model').selectedIndex].value;
//Show the review form
document.getElementById('reviewForm').style.display = 'inline';
}
</SCRIPT>
</head>
<body>

<div id="myForm">
<H1>My Form</H1>
Make:
<select name="Make" id="Make" "onChange="fillSelectFromArray(this.myForm.Model , ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));">
<option ="" selected>Select a Make</option>
<option value="Acura">Acura </option>
<option value="Alfa Romeo">Alfa Romeo </option>
...
<option value="Volvo">Volvo</option>
</select>
<br>
Model:
<select name="Model" id= "Model"size="1" >
<option>&nbspp;&nbsp;&nbsp;&nbsp;&nbsp;</option> </select>                                                    

<input type="button" value="Submit Form" onclick="showreview()">
</div>

<div id="reviewForm" style="display: none;">
<H1>Please Review</H1>
Make: <input type="text" id="reviewMake" readOnly><br>
Model: <input type="text" id="reviewModel" readOnly><br>
<input type="submit" value="Accept Values"> <input type="button" value="Change" onclick="showform()">
</div>

</body>
</html>


The code for the model.js file is:

modelinfo = new Array(
<!---1-Acura--->
new Array(
new Array("1.6 EL", "1.6 EL"),
new Array("1.6 GL", "1.6 GL"),
new Array("1.7 EL", "1.7 EL"),
new Array("TL", "TL"),
new Array("TSX", "TSX"),
new Array("Vigor", "Vigor")
),


<!---3-Alfo Romeo--->
new Array(
new Array("145", "145"),
new Array("146", "146"),
new Array("147", "147"),
new Array("Spider", "Spider")
),

...

<!--61-Volvo--->
new Array(
new Array("Volvo-1", "Volvo-1"),
new Array("Volvo-3", "Volvo-2"),
new Array("Volvo-3", "Volvo-3")
)

);

function fillSelectFromArray(selectCtrl, itemArray, goodPrompt, badPrompt, defaultItem) {
var i, j;
var prompt;


// empty existing items
for (i = selectCtrl.options.length; i >= 0; i--) {
selectCtrl.options = null;
}
prompt = (itemArray != null) ? goodPrompt : badPrompt;
if (prompt == null) {
j = 0;
} else {
selectCtrl.options[0] = new Option(prompt);
j = 1;
}


if (itemArray != null) {
// add new items
for (i = 0; i < itemArray.length; i++) {
selectCtrl.options[j] = new Option(itemArray[0]);
if (itemArray[1] != null) {
selectCtrl.options[j].value = itemArray[1];
}
j++;
}
// select first item (prompt) for sub list
selectCtrl.options[0].selected = true;
}
}
 
There were a number of minor problems.
1st, you do not have a FORM tag so when you were referencing this.myForm.Model you were refering to the DIV tag named myForm. I added in the form tag named selectForm.

Also, you cannot use this. in the onchange event because you are refering to a different object while this. refers to the current one. I changed it to just selectForm.Model. You could use Model since there is only one form on the page anyway but it is a good habit to get into.

There was an extra quote preceding your onchange event which was also choking the script.
There were also a number of spacing issues where you do not put a space in between parameters in your tags. You should watch for those. They may or may not affect you NOW but they will later as the code get's more strict.

Here is a revised copy that is working for me.
NOTE: In your array for Volvo you set the value for Volvo-3 with the option text of Volvo-2 so you end up with two Volvo-3's in your dropdown.
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"[URL unfurl="true"]http://www.w3.org/TR/html4/loose.dtd">[/URL]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Form Test</title>

<script LANGUAGE="javascript" src="C:\Documents and Settings\mm36191\Desktop\model.js"></script>

<SCRIPT type="text/javascript">

function showform()
{
  //Hide the review form
  document.getElementById('reviewForm').style.display = 'none';

  //Show the form
  document.getElementById('myForm').style.display = 'inline';
}

function showreview()
{
  //Hide the form
  document.getElementById('myForm').style.display = 'none';

  //Set the field values from the form to the review form.
  document.getElementById('reviewMake').value = document.getElementById('Make').options[document.getElementById('Make').selectedIndex].value;
  document.getElementById('reviewModel').value = document.getElementById('Model').options[document.getElementById('Model').selectedIndex].value;
  //Show the review form
  document.getElementById('reviewForm').style.display = 'inline';
}
</SCRIPT>
</head>
<body>
<form name="selectForm" id="selectForm">
<div id="myForm">
<H1>My Form</H1>
  Make:   
 <select name="Make" id="Make" onChange="fillSelectFromArray(Model, ((this.selectedIndex == -1) ? null : modelinfo[this.selectedIndex-1]));">
        <option ="" selected>Select a Make</option>
    <option value="Acura">Acura </option>
        <option value="Alfa Romeo">Alfa Romeo </option>
        ...
        <option value="Volvo">Volvo</option>
          </select>    
        <br>
   Model:
     <select name="Model" id="Model" size="1">        
      <option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>     </select>                                                     
  
 <input type="button" value="Submit Form" onclick="showreview()">
  </div>

<div id="reviewForm" style="display: none;">
<H1>Please Review</H1>
  Make: <input type="text" id="reviewMake" readOnly><br>
  Model: <input type="text" id="reviewModel" readOnly><br>
  <input type="submit" value="Accept Values"> <input type="button" value="Change" onclick="showform()">
</div>
</form>
</body>
</html>

Stamp out, eliminate and abolish redundancy!
 


Brilliant...Brilliant ....Brilliant

This works! Thank you very much.

...and thanks for the useful comments

Duncan
 
I sort of skimmed the above and kind of have a feel for the solution given and obviously you're very satisfied, but I thought I might bring up a different solution that might save you a few steps re-coding.

The issue was that when the user hit the 'Go Back' button you created, the values he/she might have entered in the form fields on the previous page were no longer there, yes?

Solution: change the functionality of the 'Go Back' button so that, instead of using the go.history(-1) function, it re-directed itself (i.e., it looks like it's going back, but really it's going forward):

Code:
onclick='document.location="firstUrl.html?param1=<%=val1%>&param2=<%=val2%>&param3=<%=val3%>"';

Obviously, this assumes you're using JSP, but there are other ways to make sure that your parameter values are saved and used in the redirect to the first page.

Your first page would have to be re-coded a little bit to check for parameters sent to it and default the values of the fields-of-interest to these values if they were.

Does that make sense?

Dave


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O Time, Strength, Cash, and Patience! [infinity]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top