Quite frequently, I need an input form with a variable number of
records/rows --- as many as the visitor wants to enter (which is not
known before hand).

Please check the following example (tested with Firefox):
http://www.yaakovnet.net/AutoForm/input.html

As soon as the visitor selects an option from the select box, a new
input row is appended --- allowing unlimited input.  The visitor can
also delete a record by selecting the option '---' from the select
box.

I would like to improve my JavaScript and turn it into a generally
usable jQuery module (unless such feature already exists and the work
is not necessary).  As I am new to jQuery, I request the guidance of
experienced jQuery programmers how to do it "the right way".

Of course, I am a programmer --- I can follow your hints, read
documentation, implement code and test it.  Here I am just asking for
guidance.  In particular, pointing out which of the many available
jQuery features are usable in this project will be very helpful.

Here is a description of how I implemented the current version --- I
am happy for any feedback (in particular criticism).

=== 1.  Getting started ===

The document contains an empty table with id="searchinput".
The body tag has an event onload="init_searchinput();"

The function init_searchinput() creates the two initial input rows by
calling the add_row() function with the appropriate HTML text of the
rows:

function init_searchinput() {
  add_row('<tr><td_align=""center>... /// pre-formatted html text ///
</td></tr>');
  add_row('<tr><td_align=""center>... /// pre-formatted html text ///
</td></tr>');
')


The function add_row selects the searchinput table, adds a row to the
end and inserts the provided HTML:

function add_row(str) {
  var row=document.getElementById('searchinput').insertRow(-1);
  var id=++id_max;
  row.innerHTML=str.replace(/#id#/g,id);
}

Note1: This is working but bad design: It would be much better to
start with a YAML list of the initial values and to build the input
elements from this data.  But I don't yet know how to build tables and
input fields step by step in JavaScript.  Hence, I used the innerHTML
feature. Any advice on building table rows and input fields in
JavaScript will greatly be appreciated.

Note2: I did make some experiments with building the input fields in
JavaScript ---- but it did not work: Even though HTML output *looked*
ok --- but the input fields were not connected to the input form: I
entered numbers and clicked on the "submit" button ---- but the data
was not sent to the server.  I don't know why it did not work.

=== 2. Adding rows automatically ===

The select box in each row has an event:
onchange=changed_selection(this): this function will add or remove
rows as needed:

function changed_selection(x) {
  var y=x.options[0]; var t=y.text; y.text="---";
  if(x.options[x.selectedIndex].text=="---") {delete_row(x);}
  if(t=="?"){add_row(new_row);}
}

The first option (x.options[0]) is "?" in the last row and "---" in
all other rows.  When you change the selection in the last row, the
function changed_selection(x) noticed the value "?", changes it to
"---" and adds a new row to the input form.  As it happens, in the new
row, x.options[0] is "?" --- so you always get a new row when you
change the selection in the bottom row.

=== 3. Deleting rows ===

If you change the selection to "---" (which is in the same place where
the "?" originally was), the delete_row(x) function deletes the
current row:

function delete_row(x) { var y=x;
  while(x){if(x.deleteRow){
    x.deleteRow(y.rowIndex);return;} x=(y=x).parentNode
  }
}

This function does some DOM traversing --- it should definitely use
the appropriate jQuery methods instead of my hand-baked loop.
Basically, we move up the DOM tree from the current input form until
we find a parent x that has a deleteRow method.  Once we found that
parent x, the previous step y refers to the table row that we want to
delete.  We get it's rowIndex and delete it.

This code works on Firefox ---- but I am not sure that it's portable.
Again, any guidance on how to do this properly will be greatly
appreciated.

=== Moving on from here ===

Please point me to jQuery features (or more appropriate JavaScript
features) to achieve the same results as the current code (portable).
I would be quite happy to understand how I can build the input forms
and table rows without pre-formatted innerHTML.

Once the core functionality works properly, I will convert this to a
more standard jQery interface.  Any suggestions about usable options
are appreciated.

Thanks,

Yaakov


Reply via email to