How to check that a form has been changed

T

Taras_96

Hi everyone,

How do you detect that a form element has been changed? This thread:

http://groups.google.com/group/comp...ed+OR+changed)&rnum=28&hl=en#125a82c9be127790

suggests that you attach onChange event handlers to every form element,
and when the handler fires you update a global 'isChanged' variable.
This technique seems to be a bit messy to me (I have many form
elements), I was thinking about storing the original form object in a
javascript variable when the body loads (in the bodie's onLoad event
handler), and upons submission, doing a javascript equality comparison
with the current form object. If nothing has changed, then the two
objects should be equal, right?

if(oldObject == document.getElementById('form'))
{
alert('has changed!');
}

Would this work?

Cheers

Taras
 
E

Evertjan.

Taras_96 wrote on 30 apr 2006 in comp.lang.javascript:
How do you detect that a form element has been changed? This thread: [..]
if(oldObject == document.getElementById('form'))

never ID a form by "form", btw
{
alert('has changed!');
}

Would this work?

Did you check?
 
R

Randy Webb

Lasse Reichstein Nielsen said the following on 4/30/2006 5:43 AM:
Can you show a case where it fails? I can't see any problem with it.

It's one of those "Best Practices" things. Easy to confuse document.form
and document.forms
 
R

RobG

Taras_96 said:
Hi everyone,

How do you detect that a form element has been changed?

It depends on what you mean by 'changed'. Do you mean if any control
has a value that differs from its default value? Or does 'changed'
include where a user changes to some other value, then back to the default?

This thread:

http://groups.google.com/group/comp...ed+OR+changed)&rnum=28&hl=en#125a82c9be127790

suggests that you attach onChange event handlers to every form element,
and when the handler fires you update a global 'isChanged' variable.

An alternative is to go through all the form controls and test if their
current value is the same as their default value. Where it isn't,
they've been changed.

How you do the test depends on the type of element. Inputs of type
"text", "file" or "password" have a defaultValue attribute that is their
default value, so you can test their current value against that.

For select elements, test if the selected option's 'defaultSelected'
attribute is 'true'. For radio buttons and checkboxes, test their
'defaultChecked' attribute.

Another scheme is to always have the first control of any group selected
(select, radios), no checkboxes selected and no value in text controls.
Then you can test against logic rather than values.

Another option is to use onload to create an object that stores the
names or ids of form controls and their values, then you can check
against that when the form is submitted.

This technique seems to be a bit messy to me (I have many form
elements), I was thinking about storing the original form object in a
javascript variable when the body loads (in the bodie's onLoad event
handler),

How to you expect to achieve that?

and upons submission, doing a javascript equality comparison
with the current form object. If nothing has changed, then the two
objects should be equal, right?

In JavaScript, objects are only equal to themselves (I wish I had a
reference for that statement but I don't). There is no way to copy an
objectA to create a new objectB so that :

objectA == objectB

returns true; it will always return false. The statement will only be
true if objectA and objectB are references to the same object.

if(oldObject == document.getElementById('form'))
{
alert('has changed!');
}

Would this work?

No - that is, it will not reliably test whether the form has been
changed or not.
 
T

Thomas 'PointedEars' Lahn

Taras_96 said:
How do you detect that a form element has been changed? This thread:

http://groups.google.com/group/comp...ed+OR+changed)&rnum=28&hl=en#125a82c9be127790

suggests that you attach onChange event handlers to every form element,
and when the handler fires you update a global 'isChanged' variable.
This technique seems to be a bit messy to me (I have many form
elements), [...]

If we lived a perfect world, that would not be necessary. The `change'
event is specified to bubble by default, so you can handle that event on
the `form' element or any other parent element (even though it does not
have the corresponding attribute).

<URL:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-htmlevents>

Try

document.forms[0].onchange = function() { alert(42); };

or

document.forms[0].addEventListener(
'change', function() { alert(42); }, false);

in Geckos, Operas and KHTML-based browsers. When you change a form control
(of the first form in the document, and focus another element after that),
you should see a message box showing "42".

However unfortunately, there is also IE, where it does not bubble, and where
therefore you cannot handle the event easily:

<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/events/onchange.asp>


PointedEars, with a fitting random signature
 
M

Matt Kruse

RobG said:
An alternative is to go through all the form controls and test if
their current value is the same as their default value. Where it
isn't, they've been changed.
How you do the test depends on the type of element. Inputs of type
"text", "file" or "password" have a defaultValue attribute that is
their default value, so you can test their current value against that.

This is the approach taken in my functions at
http://www.mattkruse.com/javascript/validations/source.html

I provide an isChanged() function that takes a reference to any input
control and returns true or false. It relies on generalized getInputValue()
and getInputDefaultValue() functions which work for any input type and are
also useful on their own.

There is also isFormModified() which loops through all form controls and
calls isChanged() on each and also provides a few additional features.
 
R

Randy Webb

Matt Kruse said the following on 4/30/2006 5:11 PM:
Depending on your definition of "changed", that may not be entirely true
though. The simplest example would be a Select element. User chooses an
option, changes his mind, changes it back to the original choice. Was it
changed?
This is the approach taken in my functions at
http://www.mattkruse.com/javascript/validations/source.html

I provide an isChanged() function that takes a reference to any input
control and returns true or false. It relies on generalized getInputValue()
and getInputDefaultValue() functions which work for any input type and are
also useful on their own.
There is also isFormModified() which loops through all form controls and
calls isChanged() on each and also provides a few additional features.

You may want to rethink it depending on what "changed" is supposed to
mean. Whether it has been changed or its value has been changed.
 
M

Matt Kruse

Randy said:
Depending on your definition of "changed", that may not be entirely
true though. The simplest example would be a Select element. User
chooses an option, changes his mind, changes it back to the original
choice. Was it changed?

I guess you could play with the meaning of "changed". But in most cases, and
what I coded for, I think the developer is wondering if the form will submit
anything different than it would have when it was first loaded. To check if
any changes need to be saved to a database, for example, before navigating
away from a screen.

There is no way to detect at form-submittal time if a user changed a select
element, then changed it back. If you want that kind of fine-level control,
then you need to look at the onChange of each element and set some global
flag. But I don't see the value in this on a global form level. I can only
think of realistic cases where you'd want to handle it on a per-field basis.
 
E

Evertjan.

Matt Kruse wrote on 01 mei 2006 in comp.lang.javascript:
I guess you could play with the meaning of "changed". But in most
cases, and what I coded for, I think the developer is wondering if the
form will submit anything different than it would have when it was
first loaded. To check if any changes need to be saved to a database,
for example, before navigating away from a screen.

There is no way to detect at form-submittal time if a user changed a
select element, then changed it back. If you want that kind of
fine-level control, then you need to look at the onChange of each
element and set some global flag. But I don't see the value in this on
a global form level. I can only think of realistic cases where you'd
want to handle it on a per-field basis.

Won't this do [on a perfield loop onSubmit()]?

if (myInput.value!=myInput.defaultValue) ...
 
R

Randy Webb

Matt Kruse said the following on 4/30/2006 11:16 PM:
I guess you could play with the meaning of "changed". But in most cases, and
what I coded for, I think the developer is wondering if the form will submit
anything different than it would have when it was first loaded. To check if
any changes need to be saved to a database, for example, before navigating
away from a screen.

Very true.
There is no way to detect at form-submittal time if a user changed a select
element, then changed it back.

Sure there is, you use the onchange of the select element to change a
global variable.
If you want that kind of fine-level control, then you need to look at the
onChange of each element and set some global flag.

Yes, that is the only way.
But I don't see the value in this on a global form level. I can only
think of realistic cases where you'd want to handle it on a per-field basis.

I don't see any value in it either. It was more of a mental exercise
than anything else :)
 
M

Matt Kruse

Evertjan. said:
Won't this do [on a perfield loop onSubmit()]?
if (myInput.value!=myInput.defaultValue) ...

No, because that won't handle checkboxes, select lists, or radio button
groups.
 
E

Evertjan.

Matt Kruse wrote on 01 mei 2006 in comp.lang.javascript:
Evertjan. said:
Won't this do [on a perfield loop onSubmit()]?
if (myInput.value!=myInput.defaultValue) ...

No, because that won't handle checkboxes, select lists, or radio button
groups.

Forgetting getElementById() for the moment, Matt,
one could set such default "by hand",
easily done by serverside code:


<input id=c1 type=checkbox defaultChecked=true checked>

<button
onclick='alert((c1.checked==c1.defaultChecked)?"same":"changed")'>
test 1</button>

<br><br>

<input id=c2 type=checkbox defaultChecked=false>

<button
onclick='alert((c2.checked==c2.defaultChecked)?"same":"changed")'>
test 2</button>
 
M

Matt Kruse

Evertjan. said:
Forgetting getElementById() for the moment, Matt,
one could set such default "by hand",
easily done by serverside code:
<input id=c1 type=checkbox defaultChecked=true checked>

I don't get the point.
The element still doesn't have a "defaultValue" property which you said
could be used generically for all elements.

There is no need to set the defaultChecked value manually anyway - its value
is set by the browser. Why would you need to add an (invalid) attribute into
the html?
 
E

Evertjan.

Matt Kruse wrote on 01 mei 2006 in comp.lang.javascript:
I don't get the point.
The element still doesn't have a "defaultValue" property which you
said could be used generically for all elements.

I didn't "say", but asked, and you said "no", I thought.
There is no need to set the defaultChecked value manually anyway - its
value is set by the browser. Why would you need to add an (invalid)
attribute into the html?

"defaultChecked" exists?
I did not know that, so what is the problem?

That they should be detected seperately?

That does not seem to be a problem, when you ID the different types of
<input> cleverly.
 
M

Matt Kruse

Evertjan. said:
"defaultChecked" exists?
I did not know that, so what is the problem?

Maybe there is a miscommunication, here :)
That they should be detected seperately?
That does not seem to be a problem, when you ID the different types of
<input> cleverly.

That is exactly what my code does - identify each type, and use the
appropriate method to determine if it has changed, using defaultValue,
defaultSelected, etc.

Your post earlier:
Won't this do [on a perfield loop onSubmit()]?
if (myInput.value!=myInput.defaultValue) ...

was what I was responding to originally, pointing out that "defaultValue"
doesn't exist for all element types, so some must be treated differently.
 
M

Michael Winter

Matt Kruse wrote on 01 mei 2006 in comp.lang.javascript:
[snip]
There is no need to set the defaultChecked value manually anyway - its
value is set by the browser. Why would you need to add an (invalid)
attribute into the html?

"defaultChecked" exists?

No. That's why Matt wrote, "an (invalid) attribute", where 'invalid' is
significant.

The checked and value attributes correspond to the defaultChecked and
defaultValue properties, respectively. Initially, these values are
copied to the checked and value properties, which represent the current
state of the form control.


I think Matt's follow-up covers the rest.

Mike
 
E

Evertjan.

Michael Winter wrote on 01 mei 2006 in comp.lang.javascript:
Matt Kruse wrote on 01 mei 2006 in comp.lang.javascript:
[snip]
There is no need to set the defaultChecked value manually anyway - its
value is set by the browser. Why would you need to add an (invalid)
attribute into the html?

"defaultChecked" exists?

No. That's why Matt wrote, "an (invalid) attribute", where 'invalid' is
significant.

The checked and value attributes correspond to the defaultChecked and
defaultValue properties, respectively. Initially, these values are
copied to the checked and value properties, which represent the current
state of the form control.


I think Matt's follow-up covers the rest.

I see here:
<http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/defau
ltchecked.asp>
that it exists, also W3C approved, and told that I thought that Matt
implied it did not, what is cleared up now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top