![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
|
|
#1 |
|
Newbie
|
Problem adding/removing rows to a form.
I'm using some javascript that has been pieced together from several different resources to add additional fields to a form as needed. These fields can also be taken away. The problem I'm having is when fields have been removed from the list and then are added back.
See example: http://blasterstudios.com/dev/crossroads/ Ideally, I'd like my [+] function (addParent) to first, check to see if there are any hidden <tr> tags on the page. If so, I want them to unhide, one at a time, in order of number. In this case, they'll already be on the page in the right order, so the first one it comes to will be the one it needs to unhide. It should continue to do this until all hidden rows are unhidden. Then if there are no more hidden rows on the page, then it needs to add a new row. As you can see in the example, it stops unhiding rows after 1 row and it won't add anymore. If you do not want to look at the source of the page above, here's the code: javascript: function removeParent(id,show){
if (el = document.getElementById(id)) {
if (null==show) show = el.style.display=='none';
el.style.display = (show ? '' : 'none');
}
}
var x = 2;
var rowArray = new Array();
var allrows = document.getElementsByTagName("tr");
function getParentId(){
for (var i = 0; i < allrows.length; i++) {
if (allrows[i].getAttribute('id') != null && allrows[i].getAttribute('id').match('parentRow'+'*')) {
var rowid = allrows[i].getAttribute('id');
if(document.getElementById(rowid).style.display == 'none'){
rowArray[rowArray.length] = rowid;
}
}
}
}
function addParent () {
getParentId();
if(rowArray.length != 0){
if (el = document.getElementById(rowArray[0])) {
var show = "1";
if (null==show) show = el.style.display=='none';
el.style.display = (show ? '' : 'none');
}
} else {
var theTable = document.getElementById('parentTable');
var newtr=document.createElement('tr');
newtr.id = "parentRow" + x;
var newtd1 = document.createElement('td');
newtd1.align = 'right';
newtd1.innerHTML ='\nParent/Guardian '+x+': <input name="parentName'+x+'" type="text" id="parentName'+x+'" style="width:220px;" /> Relationship:\n<select name="parentTitle'+x+'" id="parentTitle'+x+'">\n<option selected="selected" disabled="disabled">-- Choose One --</option>\n<option value="Mother">Mother</option>\n<option value="Father">Father</option>\n<option value="Legal Guardian">Legal Guardian</option>\n<option value="Step-Mother">Step-Mother</option>\n<option value="Step-Father">Step-Father</option>\n<option value="Grandmother">Grandmother</option>\n<option value="Grandfather">Grandfather</option>\n</select>';
var newtd2=document.createElement('td');
newtd2.innerHTML = '\n<a onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage(\'Image'+x+'\',\'\',\'img/minus_over.jpg\',1)" onclick="removeParent(\'parentRow'+x+'\');"><img src="img/minus.jpg" name="Image'+x+'" width="23" height="22" border="0" id="Image'+x+'" alt="Remove Parent/Guardian" title="Remove Parent/Guardian" style="margin-top:1px; cursor:pointer; margin-left:13px;" /></a>';
newtr.appendChild(newtd1);
newtr.appendChild(newtd2);
theTable.tBodies[0].appendChild(newtr);
/* show = null;
rowAarray = []; */
x++;
}
}<table width="630" border="0" cellspacing="2" cellpadding="3"> <tbody> <tr> <td width="145" align="right" valign="middle">Your Name:</td> <td width="436" align="left" valign="middle"><input name="parentName" type="text" id="parentName" style="width:220px;" /> Relationship: <select id="parentTitle" name="parentTitle"> <option selected="selected" disabled="disabled">-- Choose One --</option> <option value="Mother">Mother</option> <option value="Father">Father</option> <option value="Legal Guardian">Legal Guardian</option> <option value="Step-Mother">Step-Mother</option> <option value="Step-Father">Step-Father</option> <option value="Grandmother">Grandmother</option> <option value="Grandfather">Grandfather</option> </select></td> <td width="23" align="left" valign="middle"><a onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('Image','','img/plus_over.jpg',1)" onclick="addParent();"><img src="img/plus.jpg" name="Image" width="23" height="22" border="0" id="Image" alt="Add Parent/Guardian" title="Add Parent/Guardian" style="margin-top:1px; cursor:pointer;" /></a></td> </tr> <tr> <td colspan="3" align="right" valign="middle"> <table id="parentTable" width="600" cellspacing="0" cellpadding="0" align="right"> <tbody align="right" style="background-color:#EEEEEE;"></tbody> </table></td> </tr> <tr> <td align="right" valign="middle"> </td> <td align="left" valign="middle"><input type="submit" name="Submit" value="Submit Registration" style="width:180px;" /></td> <td align="left" valign="middle"> </td> </tr> </tbody> </table> </form>[/html] |
|
|
|
|
|
#2 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
I don't understand your post, I guess. I went to your page and clicked the "+". I quit after unhiding/adding 23 rows. This is in the case of selecting a value from the drop-down, first. If a value isn't selected, you probably SHOULDN'T add but one row. When that's filled out, then you can add an additional row.
Aside from that, I see no necessity to ever "add" rows (as opposed to merely unhiding). Surely you know what a rational maximum would be. Put all those there, hidden. When they're gone, they're gone. Open ended capabilities handed to the client are often a Bad Thang. Further, when the "Your Name" field is the only one displayed, the "Relationship" widget sounds/looks silly. Perhaps you should change it to "Add Relationship." It should also be moved so that it is aligned with another relationship, if one is created, nothing if one is not. Again, the relationship of a person to him/herself is generally taken for granted. I also don't understand why you begin with "Parent/Guardian 2". Whatever happened to good 'ol No. One? Lastly, and off the point, I want to commend you on an excellent initial post on the forum and offer you a hearty welcome. That's not facetious, I'm serious. I nearly had a stroke because you did it so well.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#3 | |||||
|
Newbie
|
Quote:
I understand you tested this form in the way you did, however, the point where it stops working is say if you: Add 3 additional fields. Then remove the 3 fields by using the minus button. Now try to add the 3 fields back on there. That is the problem. Also, say if you remove do the same action except for 1 field, rather than 3, after you add the 1 back (Parent/Guardian 2), it doesn't add anymore fields. Now you mentioned not allowing new rows to be added until the values for the 2 fields on that row are filled and that is a good point. I will definitely implement that onto this form. Quote:
Quote:
Quote:
Quote:
I appreciate you lookin into this for me. Thanks for any help given! ![]() |
|||||
|
|
|
|
|
#4 |
|
Newbie
|
Ok, i have fixed this issue, finally!
Now i want to validate this form. I need to factor in the visible field names dynamically and check their values. i'm having trouble doing this... |
|
|
|
|
|
#5 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Check the visibility attribute and only validate those that are seen. If you're asking HOW to validate, that's a different question.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#6 |
|
SEXY SHOELESS GOD OF WAR!
![]() Join Date: Jun 2005
Location: Wet west coast of Canada
Posts: 1,193
Rep Power: 5
![]() |
Have you considered doing this sort of thing server-side? If you're talking strictly presentation, it's fine to do it client-side, but certain things should be done server-side if possible. Validation is one of those things; while preliminary validation is often done client-side, full validation needs to be done server-side to keep things secure. Plus, some tasks are easier to do programmatically (such as creating repetitive elements, like items in a drop-down list).
I expect that there are facilities for you to do server-side scripting, provided you have the necessary access to the server. Even if it doesn't support JSP, ASP, PHP, or the like, you can always fall back to CGI and writing your programs in C. ![]()
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
|
|
|
|
|
#7 |
|
Newbie
|
Well, I do intend on doing Server side validation, however the reason I want to do client side validation is so they can't add 1000 rows real quickly. Here are the details:
I have setup a few functions to add fields to an already existing form. The only problem I face is that the user can add as many forms as they want. That's not so much a problem itself, but I'd like to make it a little more difficult for them to add a whole bunch at one time. In order to do that, I want to check all visible form fields on the page and pop up a message if there are blank inputs. See example: http://www.blasterstudios.com/dev/crossroads/ Basically onclick of a image calls a function addParent(); inside that function at the right spot, i am using return validateParents(); Here is the validateParents() function: var allrows = document.getElementsByTagName("tr");
var validRows = new Array();
function validateParents(){
for (var i = 0; i < allrows.length; i++) {
if (allrows[i].getAttribute('id') != null && allrows[i].getAttribute('id').match('parentRow'+'*')) {
var therow = allrows[i].getAttribute('id');
if(document.getElementById(therow).style.display != 'none' || document.getElementById(therow).style.display == ''){
validRows[validRows.length] = therow;
}
}
}
for (var i = 0; i < validRows.length; i++) {
var fieldno = validRows[i].replace("parentRow","");
var input = validRows[i].replace("parentRow","parentName");
var combo = validRows[i].replace("parentRow","parentTitle");
if(document.registerNew.+input+.value == "" || document.registerNew.+combo+.value == "0"){
var error = "yes";
}
}
if (error == "yes"){
alert("Please fill in all parent names and relationships before adding more rows");
return false;
} else {
return true;
}
}1. it puts all <TR> elements of the page in an array (allrows). 2. it checks the allrows array for rows where the display is set to '' or not set to 'none'. put those values in an array (validRows). I have tested it up to this point and it works. The next part is what I can't get to work. 3. Loop through all elements inside the validRows array to check if the values of the form objects are empty. 4. If it finds one that's empty, set the variable "error" to yes. 5. once it's done, check the error variable and see if it's equal to "yes", and if so, do the alert and stop the function addParent(); 6. if it's not "yes" then continue on with addParent(); I think the problem is that I'm not sure how to insert those variables (input and combo) into the form validation. There may be more wrong, but I'm pretty sure that much is not right. |
|
|
|
|
|
#8 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Yeah, you should do both. It's more convenient for the client if mistakes are caught without having to make request/response round-trips to the server. As lectric says, though, revalidation should always be done again on the server. Incidentally, the new view of your page leads me to understand it, now. I thought that initial blank was the STUDENT'S name on the other page, which raised the question about parent 2 being the first parent. Looks much better.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#9 |
|
Newbie
|
THanks. so basically, i think my problem resides on putting a variable into the statement: document.myform.variable.value
I think if i use .variable. it uses it's literal value rather than the value of that variable and it's looking for some input on the page named "input" or "combo". so, how do i do that? |
|
|
|
|
|
#10 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
"document.registerNew" isn't a string, it's an object. You can't just append a string and expect it to work. I can't see everything, but if it's a collection, use the [input] syntax.
Without going through your code in detail, I'm compelled to say it looks as if you're straining at a gnat. If I were doing it, I'd probably make a unique, dynamic id for each element. The click would pass the id to the function where it could be used directly. On the other hand, you wouldn't even need the id if just passing "this" was sufficient for uniqueness. "onclick='validate (this);' or "onclick='validate (this.id);' Then you just use "this.value" or "thisObj = document.getElementById (id);" followed by "thisObj.value", depending on how you approach it. I also don't know why you are having to resort to this: "document.getElementById(therow).style.display == ''". You should be setting that attribute in advance so it's not ''.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|