getting all the elements of a form

L

lawrence

If I'm pretty sure there is just one form on the page, can i do this?

var myForm = document.forms[0];

If I'm not sure about the form, is it safer to do this?

if (document.forms[0]) {
var myForm = document.forms[0];
// more code here........
}

Can I then get the elements array like this?

var myElements = myForm.elements;


?????????????



<script type="text/javascript">

function openInNewWindowString(windowText) {
window.open(windowText, 'Show_Form_Submission_To_User',
'toolbar=yes,width=200,height=400,directories=no,status=yes,scrollbars=yes,resizable=yes,menubar=yes');
docWindow.focus();
return false;
}

function postFormSubmissionToNewWindow() {
var elementsArrayLength = document.forms[0].length;
var whatIsBeingSubmitted = '<h1>You just wrote:</h1>';

for (i=0; i < elementsArrayLength; i++) {
whatIsBeingSubmitted += document.forms[0].elements;
whatIsBeingSubmitted += '<hr>';
}

openInNewWindowString(whatIsBeingSubmitted);
}

</script>
 
R

RobG

lawrence said:
If I'm pretty sure there is just one form on the page, can i do this?

You need to be certain as your code will return a reference to the
first form if it exists.
var myForm = document.forms[0];
Yes.


If I'm not sure about the form, is it safer to do this?

if (document.forms[0]) {
var myForm = document.forms[0];
// more code here........
}

Yes, but it's safer to test that the users browser supports
document.forms before trying to use it:

if (document.forms && document.forms[0]) {
...
} else {
// do something else
// or degrade gracefully
}
Can I then get the elements array like this?

var myElements = myForm.elements;

Yes. In regard to:
function postFormSubmissionToNewWindow() {
var elementsArrayLength = document.forms[0].length;

Whilst this line works, it is probably better to address the elements
collection directly using:

document.forms[0].elements.length

However, you don't need this variable at all if you modify the
following line:
for (i=0; i < elementsArrayLength; i++) {

to:

for (i=0; i < elementsArray.length; i++) {

[...]
 
R

Randy Webb

RobG said:
lawrence said:
If I'm pretty sure there is just one form on the page, can i do this?


You need to be certain as your code will return a reference to the
first form if it exists.
var myForm = document.forms[0];

Yes.


If I'm not sure about the form, is it safer to do this?

if (document.forms[0]) {
var myForm = document.forms[0];
// more code here........
}

Yes, but it's safer to test that the users browser supports
document.forms before trying to use it:

if (document.forms && document.forms[0]) {
...
} else {
// do something else
// or degrade gracefully
}

Is there a browser/UA that does not support document.forms and fails on
this test:

if (document.forms[0])

?
 
R

RobG

Randy said:
RobG wrote: [...]
Yes, but it's safer to test that the users browser supports
document.forms before trying to use it:

if (document.forms && document.forms[0]) {
...
} else {
// do something else
// or degrade gracefully
}


Is there a browser/UA that does not support document.forms and fails on
this test:

if (document.forms[0])

My idea was that if a browser does not support document.forms, then
asking it to evaluate document.forms[0] may return some spurious value
whereas it should gracefully handle document.forms even if it doesn't
understand it.

Or have I totally lost the plot?

Cheers, Rob.
 
F

Fred Oz

RobG wrote:
[...]
for (i=0; i < elementsArray.length; i++) {

The OP may want to change that to:

for (var i=0; i < elementsArray.length; i++) {

unless i really does need to be global.

Fred.
 
G

Grant Wagner

RobG said:
Randy said:
RobG wrote: [...]
Yes, but it's safer to test that the users browser supports
document.forms before trying to use it:

if (document.forms && document.forms[0]) {
...
} else {
// do something else
// or degrade gracefully
}


Is there a browser/UA that does not support document.forms and fails on
this test:

if (document.forms[0])

My idea was that if a browser does not support document.forms, then
asking it to evaluate document.forms[0] may return some spurious value
whereas it should gracefully handle document.forms even if it doesn't
understand it.

If a user agent does not understand document.forms in client-side JavaScript,
then there is no way to handle it at all. You can degrade gracefully and not
attempt to do anything if you can't access the DOM elements you need to
access:

var f = document.forms;
if (f) {
f = f['yourFormName'];
}
if (f) {
f = f.elements;
}
if (f) {
if (f['yourInputName']) {
alert(f['yourInputName'].value);
}
}

Alternatively:

var f;
if ((f = document.forms) &&
(f = f['yourFormName']) &&
(f = f.elements)) {

if (f['yourInputName']) {
alert(f['yourInputName'].value);
}
}
 
L

lawrence

Fred Oz said:
RobG wrote:
[...]
for (i=0; i < elementsArray.length; i++) {

The OP may want to change that to:

for (var i=0; i < elementsArray.length; i++) {

unless i really does need to be global.

Sorry for the idiot question, but why is it global when it is defined
inside a function? Javascript's scope rules confuse me. How do I make
it local?
 
M

MyndPhlyp

lawrence said:
Fred Oz <[email protected]> wrote in message
RobG wrote:
[...]
for (i=0; i < elementsArray.length; i++) {

The OP may want to change that to:

for (var i=0; i < elementsArray.length; i++) {

unless i really does need to be global.

Sorry for the idiot question, but why is it global when it is defined
inside a function? Javascript's scope rules confuse me. How do I make
it local?

<script>
var i = 0; // global to the document

function myFunction()
{
var j = 0; // global to the function but not the document

for (var k = 0; k < myThing.length; k++) // global to the for loop but
not the function or document
{
<do some for loop stuff>
{
var l = 0; // local to the code block
}
}
}
</script>

Where you define the variable determines how global or local it is.
 
G

Grant Wagner

lawrence said:
Fred Oz said:
RobG wrote:
[...]
for (i=0; i < elementsArray.length; i++) {

The OP may want to change that to:

for (var i=0; i < elementsArray.length; i++) {

unless i really does need to be global.

Sorry for the idiot question, but why is it global when it is defined
inside a function? Javascript's scope rules confuse me. How do I make
it local?

<url: http://docs.sun.com/source/816-6409-10/ident.htm#1009822 />

As I understand it, variables in JavaScript are properties of an object. If you declare the variable with the "var"
keyword, it is a property of the immediate parent object (not code block). If you neglect to include the "var" keyword, it
becomes a property of the default global object.

var a = 1;
function test1() {
a = 5; // property of global object
}
test1();
alert(a); // 5

var a = 1;
function test2() {
var a = 5; // property of object referenced by 'test2'
}
test2();
alert(a); // 1
 
L

Lee

MyndPhlyp said:
<script>
var i = 0; // global to the document

function myFunction()
{
var j = 0; // global to the function but not the document

for (var k = 0; k < myThing.length; k++) // global to the for loop but
not the function or document
{
<do some for loop stuff>
{
var l = 0; // local to the code block
}
}
}
</script>

Where you define the variable determines how global or local it is.

Your k and l will actually be local to the function,
not the loop or block as in many other languages.
 
M

Michael Winter

[snip]
Sorry for the idiot question, but why is it global when it is defined
inside a function? Javascript's scope rules confuse me.

The scope rules are similar to other languages, with one major exception:
there's no block scope.

At a conceptual level, there are three levels of scope: global, object,
and local.

1) Global variables and functions can be accessed by any script within a
document. You declare global variable with

var identifier;

outside any function. Similarly, defining a function outside any other
function

function myFunction() {
}

will cause myFunction to be global. Finally, if you assign a value to a
previously undefined identifier

unique = value;

it is created global. This is what happened with 'i' in your code. It
wasn't defined anywhere, so it would become global.

2) By "object" scope, I'm refering to the properties of an object. I
shouldn't need to explain that any further.

3) Local variables are made local through use of the var keyword. When it
is used within a function, that variable is local to that function.

function myFunction() {
var myVariable;
}

/* myVariable doesn't exist here. */

The details of variable scope - what goes on "under the hood" - is really
quite different, but I'll leave that and allow you to digest the
explanation above.
How do I make it local?

Fred did in his post: declare the variable using the var keyword within a
function.

Mike
 
R

Richard Cornford

MyndPhlyp said:
lawrence wrote:
<script>
var i = 0; // global to the document

function myFunction()
{
var j = 0; // global to the function but not the document

for (var k = 0; k < myThing.length; k++) // global to the
for loop but not the function or document

That isn't true. Languages such as Java are block scoped but
javascript/ECMAScript is not. All variables declared within a function
using the - var - keyword are scoped to the (whole) function (including
any inner functions it may have).

Where you define the variable determines how global or local
it is.

True, but in javascript that scopeing is lexical and at function
intervals.

Richard.
 
L

lawrence

I've implemented the function which you can see below, and now when I
hit post on a form, I've started gettting this error in the new
window, and nothing input on the first page:
Not Found
The requested URL /<h1>You just wrote:</h1>[object
HTMLInputElement]<hr>[object HTMLInputElement]<hr>[object
HTMLInputElement]<hr>[object HTMLInputElement]<hr> was not found on
this server.
Additionally, a 404 Not Found error was encountered while trying to
use an ErrorDocument to handle the request.

Is this because of the javascript, or should I look somewhere else for
the problem? Does the javascript somehow suck the info out of the form
when the form is input? That was not my intention. I want all the form
info to be input to my PHP script. I only wanted to show the user what
they'd just input, using Javascript.





If I'm pretty sure there is just one form on the page, can i do this?

var myForm = document.forms[0];

If I'm not sure about the form, is it safer to do this?

if (document.forms[0]) {
var myForm = document.forms[0];
// more code here........
}

Can I then get the elements array like this?

var myElements = myForm.elements;


?????????????



<script type="text/javascript">

function openInNewWindowString(windowText) {
window.open(windowText, 'Show_Form_Submission_To_User',
'toolbar=yes,width=200,height=400,directories=no,status=yes,scrollbars=yes,resizable=yes,menubar=yes');
docWindow.focus();
return false;
}

function postFormSubmissionToNewWindow() {
var elementsArrayLength = document.forms[0].length;
var whatIsBeingSubmitted = '<h1>You just wrote:</h1>';

for (i=0; i < elementsArrayLength; i++) {
whatIsBeingSubmitted += document.forms[0].elements;
whatIsBeingSubmitted += '<hr>';
}

openInNewWindowString(whatIsBeingSubmitted);
}

</script>
 
M

Michael Winter

[snip]
Is this because of the javascript,

Yes, specifically

window.open(windowText,

The first argument to window.open is *always* a URL. What the browser is
attempting is to open a network resource using the string you generate.

Obviously, this isn't your intent. What you need to do is use the
javascript: scheme. This will instruct the browser to evaluate the
following text as if it were Javascript. You then should pass a string
literal which the browser will display.

function openInNewWindowString(windowText) {
window.open('javascript:"'
+ windowText.replace(/\"/g, '\\"') + '"',
'userSubmission',
'width=200,height=400,status,scrollbars,resizable,toolbar');

Notice that I alter the string. If double quotes were present in the
string, it would produce a syntax error. Replacing " with \" removes that
problem. Also notice the slightly shorter, but equivalent, feature string.

[snip]

Here's a replacement:

var elem = document.forms[0].elements,
temp = ['<h1>You just wrote:<\/h1>'];

for(var i = 0, n = elem.length; i < n; ++i) {
temp[temp.length] = elem.name;
temp[temp.length] = ': ';
temp[temp.length] = elem.value;
temp[temp.length] = '<hr>';
}
openInNewWindowString(temp.join(''));

There are two major changes here:

1) The items are added to an array, then concatenated at the end.

The idea is that the native code that executes the join method is faster
than doing a large number of += concatenations.

2) I've output the names of each element, followed by their values.

If you look at the error message you posted, you'll see things like
[object HTMLInputElement]. That is what an INPUT element produces when you
call its toString method. Not very useful, is it.

Just outputting the names and values is a very simplistic approach, but
fine if you just have some INPUT (text) controls. If you start
incorporating the presence of SELECT elements with the multiple attribute
set, or disabled controls, you'll have to do a lot more work.

Hope that helps,
Mike


In future, please don't top-post. Even to your own messages.
 
L

lawrence

Michael Winter said:
Just outputting the names and values is a very simplistic approach, but
fine if you just have some INPUT (text) controls. If you start
incorporating the presence of SELECT elements with the multiple attribute
set, or disabled controls, you'll have to do a lot more work.

Thank you. I've been thinking about some of the complaints that
Jonathan Delacour had about the state of web writing tools:
http://weblog.delacour.net/archives/2004/07/my_kingdom_for_a_web_editing_tool.php.

As he points out, this is a problem for the makers of web browsers to
solve. It can't be solved with PHP or Javascript. However, a few of
the worst problems can be slightly ameliorated with Javascript. One
problem that trips people up is when they write a long entry (in a
textarea in a form on a page that will then be submitted to a PHP,
Perl, or Python script) then hit the submit button, only to lose all
their work because while they were writing they either lost their
internet connection or their session timed out. I know I've lost work
this way. At a minimum, I've been thinking, the browser can take all
the form data and replicate it somewhere, perhaps in another window,
so that all your data won't get lost if you hit the submit and it
turns out you no longer have an internet connection.



Yes, specifically

window.open(windowText,

The first argument to window.open is *always* a URL. What the browser is
attempting is to open a network resource using the string you generate.

Obviously, this isn't your intent. What you need to do is use the
javascript: scheme. This will instruct the browser to evaluate the
following text as if it were Javascript. You then should pass a string
literal which the browser will display.

I'll implement this. Does the form data on the parent page still get
submitted to the server in the normal way?
 
L

lawrence

Michael Winter said:
Here's a replacement:

var elem = document.forms[0].elements,
temp = ['<h1>You just wrote:<\/h1>'];

for(var i = 0, n = elem.length; i < n; ++i) {
temp[temp.length] = elem.name;
temp[temp.length] = ': ';
temp[temp.length] = elem.value;
temp[temp.length] = '<hr>';
}
openInNewWindowString(temp.join(''));


So, in this line:

temp = ['<h1>You just wrote:<\/h1>'];

you are creating the variable temp as a global variable because you
are not using the 'var' keyword? And it is automatically an array
because of the brackets that you use? Could I also do this?

temp[] = '<h1>You just wrote:<\/h1>';

Does that work the same? That is how I might put something into a
non-associative array in PHP and I'm used to that syntax. Putting
something in brackets like you've done makes me think its the key of
an associative array, though clearly that isn't your intent.

You don't define the method join() so I'll assume it is a built-in
method that all arrays possess.

Finally, this:

temp[temp.length]

You use temp.length to make sure that the string you are building up
gets put into the same row, and that that row is incremented each time
through the loop. You don't use the variable i because there is no
guarantee that the value of i equals the length of temp??????
 
L

lawrence

Michael Winter said:
function openInNewWindowString(windowText) {
window.open('javascript:"'
+ windowText.replace(/\"/g, '\\"') + '"',
'userSubmission',
'width=200,height=400,status,scrollbars,resizable,toolbar');

No luck yet. This was in a print "" block in PHP, and I kept getting
parse errors because of all the quote marks. It was trouble trying to
escape them correctly. To make things easy on myself, I redid it like
this, which was easier to escape:

function openInNewWindowString(windowText) {

var windowString = '';
windowString += 'javascript:';
windowString += windowText.replace(/\"/g, '\\\"');

window.open(windowString, 'userSubmission',
'width=200,height=400,status,scrollbars,resizable,toolbar');
docWindow.focus();
return false;
}



But this opens a window without content. The page seems to be
endlessly loading, but never loads. I no longer get a 404 message, but
now I get nothing at all.
 
L

lawrence

Michael Winter said:
[snip]
Is this because of the javascript,

Yes, specifically

window.open(windowText,

The first argument to window.open is *always* a URL. What the browser is
attempting is to open a network resource using the string you generate.

Obviously, this isn't your intent. What you need to do is use the
javascript: scheme. This will instruct the browser to evaluate the
following text as if it were Javascript. You then should pass a string
literal which the browser will display.

function openInNewWindowString(windowText) {
window.open('javascript:"'
+ windowText.replace(/\"/g, '\\"') + '"',
'userSubmission',
'width=200,height=400,status,scrollbars,resizable,toolbar');

Notice that I alter the string. If double quotes were present in the
string, it would produce a syntax error. Replacing " with \" removes that
problem. Also notice the slightly shorter, but equivalent, feature string.

I keep doing variations trying to find something that will work. In
the meantime, FireFox is giving me these error messages:


Error: document.getElementById("optionalDiv") has no properties
Source File: http://www.krubner.com/mcControlPanel.php?controlPanelCbId=1882&arrangement=editweblogPagesForm
Line: 2808


Error: docWindow is not defined
Source File: http://www.krubner.com/mcControlPanel.php?controlPanelCbId=1882&arrangement=editweblogPagesForm
Line: 4151


Security Error: Content at
http://www.krubner.com/mcControlPanel.php?controlPanelCbId=1882&arrangement=editweblogPagesForm
may not load data from about:blank.
 
M

Michael Winter

I'll try to answer all your posts at once.



[snip]
At a minimum, I've been thinking, the browser can take all
the form data and replicate it somewhere, perhaps in another window,
so that all your data won't get lost if you hit the submit and it
turns out you no longer have an internet connection.

Some browsers allow you to go back in your history to submitted forms, and
keep the submitted data. You probably can't re-submit as the session id
will have changed, but you could copy your entries. Out of habit now, I
copy the data before submitting so I can re-submit immediately.

[snip]
I'll implement this. Does the form data on the parent page still get
submitted to the server in the normal way?

It should, provided you don't cancel the submission with "return false;".


[snip]
var elem = document.forms[0].elements,
temp = ['<h1>You just wrote:<\/h1>'];
[snip]

So, in this line:

temp = ['<h1>You just wrote:<\/h1>'];

you are creating the variable temp as a global variable because you are
not using the 'var' keyword?

Not quite. Look closer on the line prior. You'll see that it ends with a
comma, not a semicolon. The line you refer to is a *continuation* of the
var statement so temp is local.
And it is automatically an array because of the brackets that you use?
Exactly.

Could I also do this?

temp[] = '<h1>You just wrote:<\/h1>';

Does that work the same?

No. It's a syntax error.

[snip]
You don't define the method join() so I'll assume it is a built-in
method that all arrays possess.

Indeed. It concatenates all elements of the array, separating them with
the given argument (type-converted to a string). As I used an empty
string, it's a direct concatenation.
Finally, this:

temp[temp.length]

You use temp.length to make sure that the string you are building up
gets put into the same row,

No. Quite the opposite.

As you know, arrays are zero-order, so a length of 2 implies that elements
0 and 1 exist.

Now think. If I assign to element array.length I'll be assigning to
element 2. That is, I'll be appending a new element. That's what happens
with the temp array; a large number of append operations. The reason for
this is that it should be quicker than string concatenation. All the
implementation need do is insert references into a linked list, rather
than allocate memory for the two strings, copy the characters, delete the
original strings, and assign the new string to an identifier.

[snip]



[snip]
No luck yet. This was in a print "" block in PHP, and I kept getting
parse errors because of all the quote marks. It was trouble trying to
escape them correctly. To make things easy on myself, I redid it like
this, which was easier to escape:

function openInNewWindowString(windowText) {

var windowString = '';
windowString += 'javascript:';
windowString += windowText.replace(/\"/g, '\\\"');

However, you missed the outer quotes. The variable, windowString, must end
up as either

javascript:"..." or javascript:'...'

Your code generates

javascript:...

By the way, please don't use tabs for indentation. Use spaces instead.



[snip]
I keep doing variations trying to find something that will work. In the
meantime, FireFox is giving me these error messages:

Hopefully the previous suggestions will help with some of your problems.
Error: document.getElementById("optionalDiv") has no properties

You haven't shown any code related to that, so I couldn't say for certain.
However, the sensible guess is that there's no element with the id,
optionalDiv.
Error: docWindow is not defined

In your original post, you'll see (abridged):

window.open(...);
docWindow.focus();

Notice that you didn't save the window reference. You probably wanted

var docWindow = window.open(...);
docWindow.focus();
Security Error: Content at may not load data from about:blank.


Couldn't tell you. I've never seen that error before.

Hope that helps,
Mike[/QUOTE]
 

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

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top