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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Processing forms....

Status
Not open for further replies.

gbaughma

IS-IT--Management
Staff member
Nov 21, 2003
4,772
US
OK... here's a silly one.

I have a BIG form that gets filled out... and I use this CUTE little routine to write the data into the database....

The routine will step through the fields on the submitted form, using a:

Code:
For Each Field in Request.Form

Well, that's fine and dandy, and works well... however, people are also allowed to EDIT the form later....

The problem is, the For Each Field statement works great, unless they UNCHECK a checkbox; then it doesn't POST the data for that field (letting me know that they unchecked something that was previously checked).

Is there a way to get my form to post ALL the fields, regardless of whether it thinks it should or not?



Just my 2¢
-There once was a man from Peru
Who wanted to write a Haiku
but...

--Greg
 
The only way off hand that I can think to do this is to create hidden input fields that will store the values of each checkbox, and store a 0 or something for a checkbox that is not checked.

Then in your "For Each Field in Request.Form" loop, simply ignore all the checkbox fields (a quick way to do this is to give all the checkbox fields the same name), reference the checkbox fields through the hidden variables.

If a hidden variable = 0, put a null into the database for the corresponding checkbox.

*You will need to use a client side scripting language to put the checkbox values into the hidden inputs.



[monkey][snake] <.
 
  • Thread starter
  • Moderator
  • #3
Well, the issue comes into play with what is submitted with the form....

For example, if you have a form with 5 text boxes (Text1..Text5) and you only fill out Text1, when it posts that data, it will only post Text1.

You could specifically REQUEST Text2 through Text5, but that doesn't help if you're doing a For Each Field in Request.Form, because those form elements aren't posted.

So... the scenario is, I have checkboxes... when checked, the form data posted is something like chkBox1 = "on" BUT... .if you re-populate the form for editing, and you UNCHECK chkBox1, it won't POST the data as chkBox1 = "off" unless you specifically ask for it with a Request.Form...

Perhaps there is a command which will let me loop through ALL form fields on a previous page? Something like For Each Field in Request.EVERY.Form :)

(I know that won't work... but I'm wondering if there's another way... )

I could do it BACKWARDS, and do something like:

Code:
For Each Field in rsObj.Fields

... however, I don't *want* to do it that way, because there are more fields in the database than on the form... so I would get errors if it did a Request.Form(Field) for a field that didn't exist...

... then I'd have to do On Error Resume Next... which is sloppy coding... Bleck.



Just my 2¢
-There once was a man from Peru
Who wanted to write a Haiku
but...

--Greg
 
I understand what you mean by you are only getting fields that contain values in them after a submit.

That's why I stated what I did above.

Example I have 2 checkboxes:
Code:
<input name="thisCheckbox" id="checkboxId1" type="checkbox" value="23" />
<input name="thisCheckbox" id="checkboxId2" type="checkbox" value="1" />

For each checkbox, I have 2 hidden variables, within the <form> tags:
Code:
<input type="hidden" name="hidden1" id="hiddenId1" value="" />
<input type="hidden" name="hidden2" id="hiddenId2" value="" />

Onsubmit of <form> place values from checkbox into hiddens (I will use a javascript function to do this), this can be optimized:
Code:
<script type="text/javascript">
function moveCBValues() {
   if (document.getElementById("checkboxId1").checked) {
      document.getElementById("hiddenId1").value = document.getElementById("checkboxId1").value   
   }
   else {
      document.getElementById("hiddenId1").value = 0;
   }
//Do same with other checkboxes
}

After page submits, do your loop:
Code:
For Each Field in Request.Form
   //filter out the checkboxes, our hidden variables contian the values of them if the checkbox was checked, and 0 if it was not checked
   if Field != "thisCheckbox" then 
      //Do what you need to to prepare to write to a database.

   endIf

We gave all checkboxes the same name "thisCheckbox", ingore them. Depending on how many checkboxes were checked, there will be different amounts of fields with that name in your loop, that is irrelanant though.




[monkey][snake] <.
 
One thing that hasn't been pointed out is that no matter how large your form is, this is a bad idea. It would take me all of 2 minutes to load your page, view source, and then create my own local page that submits whatever I want to your second page. This means that not only can I break things by adding extra fields, but I can also inject any value I want into any of the form fields. Since your basically just grabbing the values out of the Form colleciton and shoving them in a database, this means I have countless opportunities to inject SQL statements into the form field values and eventually deface your site, alter or delete the contents of your database, etc.

Additionally you run into problems such as this one, where you have one hack to get data in the database with minimal code, but now need to add additional hacks on top of that to process checkboxes. And later you will likely need additional hacks to handle editing and so on.

My suggestion would be to go back and actually request the individual fields. Do checks on them to make sure their contents are valid length, type, etc. Replace single quotes with escaped single quotes to negate SQL injection attacks, etc. It is more work right now to do it that way, but it will save you time in the future and make your application more solid.
-T

 
I handle this issue by making my form more data-driven.

I recently built a single-page front-end to a stored procedure. Instead of hard-coding the inputs in the page, I used arrays to define all the properties of all the inputs I wanted to display. In my page I "hardcode" the array values, but they're all in one place, in order, easily modified, and I can create a new input by copying a line, pasting, and changing the values. Bam. A ton of work done in seconds.

When the form is posted, instead of stepping through the request.form, I step back through my array, knowing which values I'm expecting, and what the validation is for each type. Validation occurs programmatically based on the definitions and all my values are known, regardless of what the form actually sent or what fields it left out.

To give more detail, I'll explain how the validation works.

First I define different types:
integer
string:length
notempty
expression:jsevalcode (which supports careful escaping and replacement of form values such as "($inputname)". No client-side values are ever evaluated except as escaped strings. All the actual evalcode comes from the server.)

I have javascript routines which are placed in the client page that do validation on the client all automatically based on these validation types, including how to display an error message and where, and so on. The server-side has its own separate javascript to perform the same validations.

Custom code for this form that is separate from my generic code for these standalone pages is put in special sections I've marked out. I have special "callback functions" for things I may have to do manually during form processing. If there's a validation too complex to handle generically, I put that code in the callback function, and the validation routines call it as the final step.

The point is, I only have to write a validation-method twice: once for client and once for server. Then I reuse it over and over again. I can write a slick, full-featured, validating front-end to a stored procedure that I can with confidence give to end users, all in a relatively short amount of time.

I went into all this detail to give you an idea of what I meant by "data-driven." I think data-driven programming is so powerful. And I think it's exactly what would help you with the thing you are asking about.
 
  • Thread starter
  • Moderator
  • #7
Tarwn:

Well, this is an internal web page for collecting information about critical events... nobody's going to hack it... it's not available to the outside world.

The other part that you don't see is that before it's submitted, it runs through a huge javascript routine to validate the form information, make sure that required fields are there, etc.

ESquared:

I wish I could figure out an easier way to do it... one way, which might be a better idea, is to do a

For each Field in objRS.Fields

... and step through what the *database* is wanting, instead of what the form is passing.



Just my 2¢
-There once was a man from Peru
Who wanted to write a Haiku
but...

--Greg
 
Sometimes there isn't a 1-1 correspondence between the database columns and the form inputs.

The mapping has to be represented somewhere, either in code, or the database, or in some "table-driven" method like arrays or input files.
 
gbaughma

One way to handel this is to delete the record and the reinsert it with the new form values. This way you don't have to worry about the checkboxes. Pull the exiting record and display the data on the form. The them edit it then out (delete) with the old and in with the new (insert)
 
  • Thread starter
  • Moderator
  • #10
Dashley:

Hmmm... worth a thought.

ESquared:

Yeah... I'd need to verify that the form element actually exists, if I'm going to request it based on the database....



Just my 2¢
-There once was a man from Peru
Who wanted to write a Haiku
but...

--Greg
 
I do it all the time. Actuall its a norm for the type of forms I have. I just store the form element name(position) in the DB in a seperate column form the value. When I go back and grab the data since I have the elements name the code knows where to put the value on the form once retrieved. ESquared mentioned it also. Store the element mapping in the DB

Let me know if you need any help

-dan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top