dynamic element created not POSTed - php

I create an HTML select element dynamically after a user choice is made from another select element. However the PHP script for inspecting the form does not recognise the new element and is indicating it null:
Here is snippets:
some.js:
if(document.getElementById(firstselect).value=='somvalue'){
document.getElementById(gamsDiv).removeChild(gamsElem);
gamsElem = document.createElement("select");
gamsElem.id = "FacilityGamsId";
gamsElem.name = "FacilityGamsId";
gamsElem.setAttribute("onChange", "updateHidden(this);makeUpdateRequest(arguments[0],this)");
opt = document.createElement("option");
opt.text="Select one ";
opt.value=0;
gamsElem.options.add(opt);
.....some other stuff
.....
document.getElementById(gamsDiv).appendChild(gamsElem);
}
the php script:
if($_POST){
var_dump($_POST['FacilityGamsId'];
}
result: null
Is there any reason why the server post action does not recognise ANY of my dynamic HTML elements from js script. If I examine/inspect the newly created elements, the name and id are exactly same.
Any Help is high appreciated ;) . Thanks

It's not added to the form stored in the DOM of the browser.
This guy was trying to do the same: dynamic element created not POSTed
A solution would be to build the dynamic form server-side -- if it really needs to be client-side, I think you need to manipulate the form (stored in document.forms) in addition to the DOM.

Here:
gamsElem.options.add(opt);
add is a method of the select element interface, not options (which is an HTMLElement Collection and doesn't have an add method). So:
gamsElem.add(opt);
should fix the issue.
Note that gamsElem.add(opt); does not work in Mozilla firefox 6 so I reverted to my old code of gamsElem.options.add(opt).
And:
gamsElem.setAttribute("onChange",
"updateHidden(this);makeUpdateRequest(arguments[0],this)");
would be better as:
gamsElem.onchange = function() {
updateHidden(this);
makeUpdateRequest(arguments[0], this);
};
though I have no idea what arguments[0] should reference.
Here is how this would be done normally (though the button would call a function rather than have a slab of inline code, I've done it that way for convenience only):
<form action="">
<div id="div0">
<select id="sel0" name="sel0">
<option>option 0
</select>
<input type="submit">
</div>
</form>
<button onclick="
var div = document.getElementById('div0');
var sel = document.getElementById('sel0');
div.removeChild(sel);
sel = document.createElement('select');
sel.id = 'sel1';
sel.name = 'sel1';
sel.onchange = function(){alert(this.value);};
sel.options[0] = new Option('Select one', '0');
sel.options[1] = new Option('Select two', '1');
div.appendChild(sel);
">Replace select</button>
A second option is needed to get the onchange listener to fire.
If you want to replace one element with another, create the new element then just replace the old one:
<button onclick="
var oldSel = document.getElementById('sel0');
var sel = document.createElement('select');
sel.id = 'sel1';
sel.name = 'sel1';
sel.onchange = function(){alert(this.value);};
sel.options[0] = new Option('Select one', '0');
sel.options[1] = new Option('Select two', '1');
oldSel.parentNode.replaceChild(sel, oldSel);
">Replace select</button>
Or you can just replace the options (set the select's options.length to zero and just add the new ones).

You have to add a new element into your FORM tag

Run this code after the DOM is ready, preferably $.ready() in jquery.
and also put the quotes aroun div name ("gamsDiv")

Related

Need to access <input> data from a <form>, that has been appended with Javascript

I have an admin page where I add and delete table rows on the fly.
The page comes loaded with the existent data in the database (mostly consisting in a sku_code and 5 different prices) but when I add rows on the fly, and fill them with the corresponding skus and prices, I want to save them as well in the database.
The problem is that what I do on the client-side with Javascript (add table rows on the fly) with innerHTML = '<input type="text"> is not accesible via $_POST variables of the main <form>
So basically i add via Javascript 's so i can fill them and save them as well in the database. But the $_POST values are empty.
Javascript code works fine. I have no clue where should i start debugging.
here's some Javascript code i'm using
function insert_record(){
var my_table = document.getElementById('my_table')
var tr = my_table.insertRow(my_table.rows.length-1)
//id-ul curent, numar toate row-urile - 1 (care este butonul OK)
var c_id = my_table.rows.length-2
tr.id = 'row_' + c_id + ''
var tr_td_1 = tr.insertCell(0)
tr_td_1.className = 'text2'
tr_td_1.align = 'center'
tr_td_1.innerHTML = 'SKU'
var tr_td_2 = tr.insertCell(1)
tr_td_2.className = 'text3'
tr_td_2.width = '63'
tr_td_2.innerHTML = '<input name="sku_' + c_id + '" type="text" id="sku_' + c_id + '" size="33" value="">'
....this addes a inside the table just before the last which contains the submit button, after which there's the
You need to assign a label to element. Then you can grab it in next page.
Instead of innerHTML = <input type="text"> try to use
<script>
function addElement(tag_type, target, parameters) {
//Create element
var newElement = document.createElement(tag_type);
//Add parameters
if (typeof parameters != 'undefined') {
for (parameter_name in parameters) {
newElement.setAttribute(parameter_name, parameters[parameter_name]);
}
}
//Append element to target
document.getElementById(target).appendChild(newElement);
}
</script>
You can call this function below either click of even or manually addElement('INPUT','targetTag',{id:'my_input_tag', name:'my_input_tag', type:'text', size:'5'});
you should give the name attribute. if you are worried about the unlimited numbers of fields just go for the array of the input variables,
like this
<input type="text" name="field1[]">
Now you can access them in post like this:
$_POST['field1'] //this is an array of fields
EDIT:
First thing is that you should use some library like jquery which eases the work.
I suggest you make sure your all your fields are inside the form and that you have named all of them instead of trying ajax or functions like #shail suggested.
In my opinion they are not solving the problem, just avoiding it.

<input></input> in innerHTML not working

I created a dropdown list with javascript and I populate it getting data from a MySQL database.
The problem that I have is that I can't place the dropdown list in the innerHTML code.
This is what I wrote to create the dropdown list with JS:
var mySpan = document.getElementById('myDiv');
var myLine = document.getElementById('testcat');
myLine.value++;
// Create select
var selection = document.createElement('select');
selection.setAttribute('name',"category[]");
mySpan.appendChild(selection);
// Create Option
createSelectOption(selection);
// Create the container
var ni = document.getElementById('myDiv');
ni.setAttribute('style', 'width:790px;');
...........
...........
Then I create other things and to create the HTML code, I use:
newdiv.innerHTML = '<div class="table">.........</div>';
ni.appendChild(newdiv);
This is the part of HTML:
// test dropdown list
<input name="testcat" id="testcat" type="hidden" value="0" />
<div id="myDiv"></div>
I tested my dropdown list as you can see in the code above, and it works if I declare <input name="testcat" id="testcat" type="hidden" value="0" /> in the HTML (I mean in the <body></body>), but if I use the same code in the innerHTML, FireBug tells me: "myLine is null; myLine.value++;".
Any help?
You can't assign an element with an ID using innerHTML as text - the ID won't register on the DOM. You need to first create the element, assign it the ID and then put that element in the DOM.
You might find this easier using jQuery:
var input = document.createElement("input");
input.id="testcat";
input.innerHTML = "testcat" ;
$('somediv').appendChild(input);
this is what I did in my old code:
var selectcat = document.createElement("select");
selectcat.name = "category[]";
selectcat.options[0] = new Option("","");
selectcat.options[1] = new Option("cat1","cat1");
selectcat.options[2] = new Option("cat2","cat2");
..........
..........
selectcat.options[12] = new Option("cat1","cat12");
And the used:
newdiv.innerHTML = '<div class="table"><ul><li><select name="category[]"><option value=""></option><option value="cat1">cat1</option><option value="cat2">cat2</option></select></li></ul></div>';
But now I have to get the values from a MySQL database.
So I created this function:
function createSelectOption(element)
{
var objSelect = ele;
var Item = new Option("", "");
objSelect.options[objSelect.length] = Item;
<?
while($categ = mysql_fetch_array($resultf_categ))
{
?>
var Item = new Option("<?=$categ["cat_name"];?>", "<?=$categ["cat_name"];?>");
objSelect.options[objSelect.length] = Item;
<?
}
?>
}
But still don't understand how can I use directly in my innerHTML.
Sorry for the stupid questions, but I am really stucked here.

Dynamically set input values in HTML with non-specific names

Long time lurker, first time poster.
I have a page that can dynamically (with Javascript / jQuery) add key => value pair inputs to a form. These fields need to be returned to PHP as an array for processing, so the keys are all named "complete_fields[]" and the values are all named "complete_values[]". Now here is my problem. If I fill in some inputs then want to add another key => value pair, I can click on a button and the Javascript will work its magic. However, because the HTML "value=" part is not filled out, the inputs I have already filled out are erased by the Javascript. So my question is this: How can I dynamically set the HTML value of the input with JS, even though all the inputs are named the same? If this is not possible, how can I add to the end of a div without erasing all the rest of the HTML?
Here is the Javascript add input code:
function addCompleteField() {
var oldhtml = $("#complete_fields").html();
var newrow = '<tr><td><input type="text" name="complete_fields[]" > => <input type="text" name="complete_values[]" ></td></tr>';
$("#complete_fields").html(oldhtml+newrow);
}
Rather than mucking around with HTML, just clone the elements using jQuery's clone method:
function addCompleteField() {
var table = $('#complete_fields'),
lastRow = table.find('tr').last(),
newRow = lastRow.clone(true);
newRow.find('input').val(''); // blank the new row's input elements
newRow.appendTo(table);
}

Create form dynamically in table

Using some code to create a form dynamically which I got here: http://www.trans4mind.com/personal_development/JavaScript2/createSelectDynamically.htm
This works great. However I have a regular html table I generate with html/php to get data out of a DB. I want to replace that data with a form so when users click the edit button the original entry is replaced with a form (either textbox or pull down menu). The user makes a selection and the new table comes back with the appropriate edit.
So for example one part of the data has this in the table:
<td><?php echo $result[0] ?></td>
Using the link about to create a form dynamically I change this to:
<td id="paraID"><form id="form1" name="form1" method="post" action enctype="text/plain" alt=""><?php echo $result[0] ?></form></td>
Also note the onclick event for the edit button:
This is hard to explain but hoping someone can help me with this interaction. I need some way to say:
if (user clicks edit button)
then
replace html table with form for each entry (for example, the table returns a name called foo and a textbox will appear with foo in it but now they can edit to change the name).
If you can start out with an id for the td then it will make things easier. Then you will need an edit button somewhere. Notice: It might be nice to replace "result_0" with the name for the value/field:
<td id="result_0_parent"><?php echo $result[0] ?><input type="button" onClick="editField('result_0','select')" value="Edit" /></td>
Then in your javascript you will have the editField function defined so that it sets the content of the td to be the dynamic form. Looking at makeForm function in the example javascript, you see this happening with appendChild(myform); The function editField will be like the makeForm function except you will pass in the field_id and field_type as parameters:
function editField(field_id, field_type)
I suggest you change the line that defines mypara to define mytd or better yet, field_parent instead since in your case it will not be a paragraph element, but a td (or possibly some other type of element):
field_parent = document.getElementById(field_id+"_parent");
The example code create a select (dropdown), but I am guessing you want to create other field input types so I recommended having field_type as a second parameter to the function. This means that it would make more sense for your implementation to use myfield instead of myselect and then use the field_type parameter to decide what myfield will be.
Replace the line in the makeForm / editField function:
myselect.setAttribute("id","selectID");
with
myfield.setAttribute("id",field_id);
One more thing: To set the initial value of the input field to be the displayed content, you will need to copy the "innerHTML" of the "parent" element. So place something like this right after defining field_parent:
initial_value = field_parent.innerHTML;
and I think you can figure out the rest. If not, I can elaborate a little more.
This works great. However I have a regular html table I generate with
html/php to get data out of a DB. I want to replace that data with a
form so when users click the edit button the original entry is
replaced with a form (either textbox or pull down menu). The user
makes a selection and the new table comes back with the appropriate
edit.
This is a script that allows with a double click on values to edit them and has a button to send them back. Maybe it would be of some help to use it (or use parts of it).
<?PHP
if(count($_POST)>0)
{
echo 'You gave:<br><per>';
print_r($_POST);
echo '<a href=http://localhost/temp/run.php>Start over</a>';
exit;
}
?>
<html>
<head>
<script type="text/javascript">
/**formEditor Class
*/
function formEditorCls( )
{
/**
Constructor simulator
*/
this.lastFieldEditedId = null;
/** Change span with input box, hide the eddit button and store theses IDS
*/
this.edit=
function (field)
{
//if there was a field edited previously
if(this.lastFieldEditedId != null)
this.save();
//get the inner element of the div, it can be span or input text
var childElem = document.getElementById(field).getElementsByTagName('*')[0];
//then replace the span element with a input element
document.getElementById(field).innerHTML="<input type=text name=n_"+field+
" id=id_"+field+" value="+childElem.innerText+">";
//store what was the last field edited
this.lastFieldEditedId =field;
}//func
this.save=
function ()
{
dbq="\"";sq='\'';
//get the last value
var lastValue = document.getElementById(this.lastFieldEditedId).
getElementsByTagName('*')[0].value;
//store it as span
document.getElementById(this.lastFieldEditedId).innerHTML="<span ondblclick="+dbq+
"formEditor.edit("+sq+this.lastFieldEditedId+sq+");"+dbq+" >"+lastValue+"</span>" ;
//now must reset the class field attribute
this.lastFieldEditedId=null;
}//func
this.submit=
function (path)
{
this.save();//if ay field was edited put new values in span elements
var form = document.createElement("form");//create a new form
form.setAttribute("method", "post");
form.setAttribute("action", path);
var myDiv = document.getElementById( "fieldsDiv" );//get the div that contains the fields
var inputArr = myDiv.getElementsByTagName( "SPAN" );//get all span elements in an array
//for each span element
for (var i = 0; i < inputArr.length; i++)
{
var hiddenField = document.createElement("input");//create an input elemet
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", i);
hiddenField.setAttribute("value", inputArr[i].innerText);
form.appendChild(hiddenField);//append the input element
}
document.body.appendChild(form);//append the form
form.submit();//submit the form
}//func
}//class
formEditor = new formEditorCls( );
</script>
</head>
<body onclick="rt();">
Double click any value to change it..<br><br>
<div id="fieldsDiv">
Name:<font id="nameField">
<span ondblclick="formEditor.edit('nameField');" >Mark</span>
</font><br>
Surname:<font id="surnameField" >
<span ondblclick="formEditor.edit('surnameField');">Smith</span>
</font><br>
</div>
<input type=submit name="submit"
onclick="formEditor.submit('http://localhost/temp/run.php');" value="Submit">
</body>
</html>

Form is removed from AJAX response

I'm trying to add a table row with ajax/jquery that has a form element in it. Everything works just fine if I set it without the ajax, but somehow everything inside the <form> tag is just completely lost.
I'm not sure where I'm losing the form (jquery's .html() is effectively the same as innerHTML right? If that's the case I suspect that's where I'm losing it).
Anyway, here's some code:
var worow = document.getElementById('worow_' + row);
var wotable = document.getElementById('tbl_workorders');
// add a new row to the table underneath our existing row.
var newrow = wotable.insertRow(worow.rowIndex+1);
var x = newrow.insertCell(0);
// set up the row a little bit
x.colSpan = 13;
x.style.padding = '10px';
x.style.backgroundColor = '#ccc';
x.align = "center";
x.innerHTML = '<img src="/images/loading.gif" />';
// a little ajax cuz we're cool that way
$.post("getwotrans.php",
{
workorder: row
},
function(response)
{
// set the value of the row = response object from the AJAX
$(x).html(response);
});
And in getwotrans.php: (paraphrased)
<table>
<thead><tr><td>blahblah</td></tr></thead>
<tbody><form><tr><td><input></td></tr></form></tbody>
</table>
So what happens is I'll run the javascript function to add the row, and the row is added fine and I see the table headers, but the 'form' inside the tbody is just not there.
I had some simliar problem. I used a hidden form and javascript to copy the values of the row clicked to the hidden form elements and then submit the form via javascript. Maybe that's an idea.
a form cannot be a child element of tbody
What happens when you put the form outside of the table?
<form><table>
<thead><tr><td>blahblah</td></tr></thead>
<tbody><tr><td><input></td></tr></tbody>
</table></form>
Just curious if this will fix the issue or not? It is odd that this would happen without something equally odd to fix it!

Categories