...

View Full Version : Adding a table row with form input?



Jak-S
03-07-2005, 01:14 PM
Hi,

I have the code below that is supposed to add a table row to my table with a form field in. However it dosent work (says there is an error with the "cell.appendChild(textInput); line");.

I have tried an alternative way of creating the INPUT element that you can see in the comments, this works successfully however the style, class, onFocus and onBlur attributes dont seem to have any effect on the newly created input field. (In internet explorer, the commented version works perfectly in FireFox).

I really need this to work in IE as well, and on the Mac version. Can anyone help help me out here? Is there a better way to do it that is more compatible with browsers?

Thanks for your help in advance.

Jack



<script language="javascript">
function addRowToTable(tableId, fieldName)
{
var tbl = document.getElementById(tableId);
var lastRow = tbl.rows.length;
var row = tbl.insertRow(lastRow);
var cell = row.insertCell(0);

textInput = "<input ";
textInput += "type=\"text\" ";
textInput += "name=\"" + tableId + "_" + fieldName + "_new\" ";
textInput += "style=\"width: 125px; border: none; padding: 2px 3px 3px 3px;\" ";
textInput += "class=\"listBoxText\" ";
textInput += "onFocus=\"this.className='listBoxTextHighlight'\" ";
textInput += "onBlur=\"this.className='listBoxText'\"";
textInput += ">";

//var textInput = document.createElement('input');
//textInput.setAttribute('type', 'text');
//textInput.setAttribute('name', tableId + '_' + fieldName + '_new');
//textInput.setAttribute('style', "width: 125px; border: none; padding: 2px 3px 3px 3px;");
//textInput.setAttribute('class', 'listBoxText');
//textInput.setAttribute('onFocus', "this.className='listBoxTextHighlight'");
//textInput.setAttribute('onBlur', "this.className='listBoxText'");

cell.appendChild(textInput);

var lastRow = tbl.rows.length;
var row = tbl.insertRow(lastRow);

var divide = row.insertCell(0);
divide.setAttribute('class', 'listBoxDivide');
}
</script>

glenngv
03-07-2005, 01:26 PM
Event handlers are not normal attributes. For wide browser support, use the old DOM0 syntax in assigning events. When creating textfields elements in IE, name is not set even if you setAttribute it. You need to include the field name in the createElement method.


var textInput;
if (document.all) {
textInput = document.createElement('<input name="' + tableId + '_' + fieldName + '_new' + '">');
}
else {
textInput = document.createElement('input');
textInput.setAttribute('name', tableId + '_' + fieldName + '_new');
}
textInput.setAttribute('type', 'text');
textInput.setAttribute('class', 'listBoxText');
textInput.onfocus = function(){this.className='listBoxTextHighlight'"};
textInput.onblur = function(){this.className='listBoxText'"};

Jak-S
03-07-2005, 01:45 PM
Hi

Thanks for your help, i now have the code below and it works perfectly.

There is one other thing i wanted to do but im not sure how to. I want to set the focus to the newly created text field, i know this is usually done with something like this:

document.productForm.myTextField.focus();

however the name of the field is based on the two variables being parsed into the function, so im not sure what the right syntax would be, something like this perhaps:

document.productForm.tableId + '_' + fieldName + '_new'.focus();

I know thats wrong but how would i do it?

Thanks again,

Jack



<script language="javascript">
function addRowToTable(tableId, fieldName)
{
var tbl = document.getElementById(tableId);
var lastRow = tbl.rows.length;
var row = tbl.insertRow(lastRow);
var cell = row.insertCell(0);

var textInput;
if (document.all) {
textInput = document.createElement('<input type="text" name="' + tableId + '_' + fieldName + '_new' + '" class="listBoxText" style="width: 125px;" onFocus="this.className=\'listBoxTextHighlight\'" onBlur="this.className=\'listBoxText\'">');
}
else {
textInput = document.createElement('input');
textInput.setAttribute('type', 'text');
textInput.setAttribute('name', tableId + '_' + fieldName + '_new');
textInput.setAttribute('style', "width: 125px;");
textInput.setAttribute('class', 'listBoxText');
textInput.setAttribute('onFocus', "this.className='listBoxTextHighlight'");
textInput.setAttribute('onBlur', "this.className='listBoxText'");
}
cell.appendChild(textInput);
}
</script>

glenngv
03-07-2005, 02:02 PM
After appending the text input, try inserting:

textInput.focus();


If that doesn't work, try:

document.productForm.elements[tableId + '_' + fieldName + '_new'].focus();

See my sig on Square Bracket Notation for more info of this technique.

Jak-S
03-07-2005, 02:07 PM
cheers, they both work perfectly.

Thanks for all your help, much appreciated.

Jack

Kor
03-07-2005, 02:12 PM
i now have the code below and it works perfectly.

hm... I wonder if do so...

glenngv has advise you to use DOM0 event handlers appending
textInput.onfocus = function(){this.className='listBoxTextHighlight'"};
textInput.onblur = function(){this.className='listBoxText'"};

and you have post the older variant with setAttribute()
;)

Now, to focus the created one, try:
textInput.onfocus = function(){this.className='listBoxTextHighlight'"};
textInput.onblur = function(){this.className='listBoxText'"};
textInput.focus();

glenngv
03-07-2005, 02:18 PM
and you have post the older variant with setAttribute()
;)

I didn't notice that. :thumbsup:


Now, to focus the created one, try:
textInput.onfocus = function(){this.className='listBoxTextHighlight'"};
textInput.onblur = function(){this.className='listBoxText'"};
textInput.focus();

You can't focus to a newly created element that is not yet appended to something. The field must be visible to set focus to it. My suggestions already worked.

Kor
03-07-2005, 02:20 PM
You can't focus to a newly created element

yeap, sorry, I was not attentive when insert that code line... ;)

Jak-S
03-07-2005, 02:28 PM
Hi, yeah oops, my mistake, i now have this code which still works, and should hopefully be more compatible:



<script language="javascript">
function addRowToTable(tableId, fieldName)
{
var tbl = document.getElementById(tableId);
var lastRow = tbl.rows.length;
var row = tbl.insertRow(lastRow);
var cell = row.insertCell(0);

var textInput;
if (document.all) {
textInput = document.createElement('<input name="' + tableId + '_' + fieldName + '_new' + '">');
}
else {
textInput = document.createElement('input');
textInput.setAttribute('name', tableId + '_' + fieldName + '_new');
}
textInput.setAttribute('type', 'text');
textInput.className = "listBoxText";
textInput.onfocus = function(){this.className='listBoxTextHighlight'};
textInput.onblur = function(){this.className='listBoxText'};
cell.appendChild(textInput);
textInput.focus();
}
</script>

Kor
03-07-2005, 02:34 PM
:thumbsup: Ok, we are glad that it works...

Well, you could be more consequent and use document.createElement to create the row and the cell as well....as long as you did so to create the input... ;)

Jak-S
03-07-2005, 02:42 PM
:thumbsup: Ok, we are glad that it works...

Well, you could be more consequent and use document.createElement to create the row and the cell as well....as long as you did so to create the input... ;)

Yeah but how would I do that? (as you may have guessed im not that good with JS). If i did that, would i then be able to set the ID of the row, and then be able to remove a row based on the ID.

Ive only been able to remove rows based on index (row 1, row 2) e.t.c before, which really wasnt sutiable. If i could do it by id that would be great.

Thanks again for all your help.

Jack

Jak-S
03-07-2005, 03:17 PM
Hi,

Forgetting the remove thing for now. I just tested the code on IE 5.2 for Mac OSX, and it dosent work :( i click the button that runs the new row function and nothing happens. Has anyone got an idea why this is? If it is a problem with the add table row thing i can actually remove the table completly, so long as i can add new text input fields in the right place still.

Cheers,
Jack

Kor
03-07-2005, 05:20 PM
can you tell us your final goal? Add a row? Add and remove another row?

Jak-S
03-07-2005, 06:38 PM
Yeah ok, since originally posting the way i want to do this has kinda changed.

I no loger want to use a table, i was only actually using one column in the end anyway so there is no need for the table, and it also causes some aesthetic problems when i do.

So now i want a list of text inputs with BR tags after to create a list going down the page, these are currently contained in a scrolling DIV which you can scroll down. So basically its like an editable SELECT box. I then want two buttons next to the scrolling div, "Add Colour" and "Remove Colour".

When you click the Add button a new text box is added at the end of the current set, the focus is set to that box and the div is told to scroll all the way to the bottom, this currently works authough i want to get rid of the table.

I then want another button that will allow you to click on a field (so its in focus) and when you click on the button it will remove that field.

Most of this is done already but i need to know how to get rid of the table and still have the fields added in the right place on the page, and also how to remove a field.

Thanks again, you have all been a great help already.

Jack

Jak-S
03-07-2005, 09:19 PM
Hey,

I have muddled my may through and managed to come up with something that works perfectly on the PC versions of FireFox and IE, still need to test it on Mac IE which is usually the main problem.

This dosent use tables and will remove fields as well, its all a bit complicated now but it needs to be because it needs to work with more than one list of form fields.

If someone could look over it for me, give any pointers as to what might need to be changed to make it better that would be great, fingers crossed it will work on Mac IE.

Cheers,

Jack

P.S. Dont worry about the <cfoutput> tags, its server side and they just generate those two lines of JS for the number of sections ive got in the DB.



<cfoutput query="getSections">
var colours_#sections_id#_selected = "";
var sizes_#sections_id#_selected = "";
</cfoutput>

function addFormField(option, section, recordCount)
{
var newFieldName = parseInt(document.productForm.elements[option + '_' + section + '_newCount'].value) + 1;
document.productForm.elements[option + '_' + section + '_newCount'].value = newFieldName;

var textInput;
if (document.all) {
textInput = document.createElement('<input name="' + option + '_' + section + '_' + newFieldName + '_new' + '">');
}
else {
textInput = document.createElement('input');
textInput.setAttribute('name', option + '_' + section + '_' + newFieldName + '_new');
}
textInput.setAttribute('type', 'text');
textInput.setAttribute('id', option + '_' + section + '_' + newFieldName + '_new');
textInput.className = "listBoxText";
textInput.onfocus = function(){this.className='listBoxTextHighlight'; window[option + '_' + section + '_selected'] = option + '_' + section + '_' + newFieldName + '_new';};
textInput.onblur = function(){this.className='listBoxText';};

parentDiv = document.getElementById(option + '_' + section + '_div');
endSpan = document.getElementById(option + '_' + section + '_end');
parentDiv.insertBefore(textInput, endSpan);

document.getElementById(option + '_' + section + '_div').scrollTop = (parseInt(document.productForm.elements[option + '_' + section + '_newCount'].value) + recordCount) * 19;
document.productForm.elements[option + '_' + section + '_' + newFieldName + '_new'].focus();
}
function removeFormField(option, section)
{
if (window[option + '_' + section + '_selected'] != "")
{
parentDiv = document.getElementById(option + '_' + section + '_div');
textInput = document.getElementById(window[option + '_' + section + '_selected']);
parentDiv.removeChild(textInput);
window[option + '_' + section + '_selected'] = "";
}
}

glenngv
03-08-2005, 03:01 AM
This is more of an optimization (I didn't look at the logic) as you keep on repeating concatenating the same strings.


<cfoutput query="getSections">
var colours_#sections_id#_selected = "";
var sizes_#sections_id#_selected = "";
</cfoutput>

function addFormField(option, section, recordCount)
{
var oForm = document.productForm;
var optSec = option + '_' + section + '_';
var optSecNewCount = optSec + 'newCount';
var optSecNewFld = optSec + newFieldName + '_new';
var optSecSelected = optSec + 'selected';
var optSecDiv = optSec + 'div';
var newCount = parseInt(oForm.elements[optSecNewCount].value, 10);
var newFieldName = newCount + 1;
oForm.elements[optSecNewCount].value = newFieldName;

var textInput;
if (document.all) {
textInput = document.createElement('<input name="' + optSecNewFld + '">');
}
else {
textInput = document.createElement('input');
textInput.setAttribute('name', optSecNewFld);
}
textInput.setAttribute('type', 'text');
textInput.setAttribute('id', optSecNewFld);
textInput.className = "listBoxText";
textInput.onfocus = function(){this.className='listBoxTextHighlight'; window[optSecSelected] = optSecNewFld;};
textInput.onblur = function(){this.className='listBoxText';};

var parentDiv = document.getElementById(optSecDiv);
var endSpan = document.getElementById(optSec + 'end');
parentDiv.insertBefore(textInput, endSpan);

parentDiv.scrollTop = (newCount + recordCount) * 19;
oForm.elements[optSecNewFld].focus();
}

function removeFormField(option, section)
{
var optSec = option + '_' + section + '_';
var optSecSelected = optSec + 'selected';
var optSecDiv = optSec + 'div';
if (window[optSecSelected] != "")
{
var parentDiv = document.getElementById(optSecDiv);
var textInput = document.getElementById(window[optSecSelected]);
parentDiv.removeChild(textInput);
window[optSecSelected] = "";
}
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum