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!
Related
Im probably overlooking something very obvious but at this point i surrender and need help.
Here is my situation. When my page loads, in a while loops, PHP generates a table with data from my server. Each table row has a name column, phone, etc. One of the columns is an icon that when clicked allows the user to view a popup with notes on this particular lead. Easy stuff.
The icons in each row have the same class name and their ID's are unique.
I have an AJAX request that should be pulling the notes data from the server and displaying it in the popup when the user clicks on the relative icon. I am trying to use $('.class').click(this).attr('id'); to set a variable in my AJAX request with the id that needs to be submitted to my PHP script.
PROBLEM: The AJAX request and return seems to be working fine but no matter which row icon I click on it only displays the data that belongs to the first row, or the first instance with the class name 'homelead' Example: I click on row 1 icon and i get a popup with row 1's notes, GREAT!. I click on any other row and it only shows the 1st rows data, :(. I have confirmed that the ID's associated with each row icon are correct by doing a simple click.(this).(id) and alerting the id belonging to the row icon. All is correct, just can't seem to get the JS variable to update with the correct ID.
Im confused why this is. Any help would be appreciated. Here is my current code.
HTML:
<td>
<img class="homelead" id="<?php echo $leadsfetch['unit_id'];?>"
onclick="ajax_unitnotes();" src="images/list-view.png">
</td>
<?php echo "</tr>"; } ?>
AJAX request:
function ajax_unitnotes(){
var hr = new XMLHttpRequest();
var url = "PHP/getnotes.php";
// this variable should update with clicked rows id before submitting to PHP script
var unitidnotes = $('.homelead').click(this).attr('id');
var vars = "unitidnotes="+unitidnotes;
hr.open("POST", url, true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("unitnotes").innerHTML = return_data;
}
}
hr.send(vars);
document.getElementById("unitnotes").innerHTML = "processing...";
}
As you are using an onclick trigger in the tag itself - which is usually un common when using jQuery. You can do this:
<img class="homelead" id="<?php echo $leadsfetch['unit_id'];?>"
onclick="ajax_unitnotes($(this));" src="images/list-view.png">
And the in your function
function ajax_unitnotes(e){
var unitidnotes = e.attr('id');
}
Your current code
var unitidnotes = $('.homelead').click(this).attr('id');
Actually does not know what it the this object you are trying to access.
Better yet you can use a jQuery event, remove the onclick from the img tag and have an event like this:
$('.homelead').click(function(){
id = $(this).attr('id');
});
You could pass the clicked object this to the function trigged by "onclick":
onclick="ajax_unitnotes(this);"
That will make the DOM object you clicked on available inside the JS function.
You need to change the function signature accordingly:
function ajax_unitnotes(clickedElement){
and then you can alter this
var unitidnotes = $('.homelead').click(this).attr('id');
to
var unitidnotes = clickedElement.id;
This will give you the value of $leadsfetch['unit_id'] = img id.
My english isn't very good but i will try explain my problem. I have a form in php with dynamically added rows (after clicking button the row is added). If form is fill properly, after submitting, the pdf is generated. In other case the form must be corrected and the values of earlier filled fields should be remebered. It's work for simple field but for dynamically added rows it's not work.
I set variable $_POST['whichRow'] to send it after each loop iteration, from function generateAddedRows() to function addRows2(). Unfortunetly it doesn' work, the variable $_POST['whichRow'] in function addRows2() return NULL.
This function is running if the form was filled wrong. It's create the earlier dynamically added rows:
$_POST['whichRow'] = 1;
function generateAddedRows(){
$_POST['whichRow']++;
while($personsArrayLength>1){
echo '
<script>
$(document).ready(function(){
var i = 2;
var rowTemplate2 = jQuery.format($("#template2").html());
addRow2();
function addRow2(){
var ii = i++;
$("#app_here2").append(rowTemplate2(ii));
$("#delete_" + ii).click(function(){
$("#row_" + ii).remove();
});
}
});
</script>
';
$personsArrayLength--;
$myValue++;
}
}
This function create a dynamcally added rows. I try to get the $_POST['value'] as value of each row:
function addRows2(){
global $personsError_css;
$personsArray = $_POST['persons'];
$html = '<table id="template2" align="right" style="display:none; ">
<tr id="row_{0}">
<td><input type="text" name="persons[]" value="'.$personsArray[$_POST['whichRow']].'"></td>
<td><img src="/../_img/row_del.png" id="delete_{0}" alt="usun"></td>
</tr>
</table>
.
.
.
</table>';
return $html;
}
I insert here some screens to better understand this problem.
This is form before validating. Each field is filled:
This is form after validating. The form was filled wrongly so it should be corrected. The earlier entering values should be remembered but as you can see it's not:
I hope so you understand my problem. Can you help me?
I see some different possible problems here:
Are you sure that $_POST['persons'] contains everything properly?
If you are going to call a function, you have to define it first:
<script>
$(document).ready(function(){
/* CODE */
function addRow2(){
/* CODE */
});
addRow2();
});
</script>
Your code is a little messy. Be careful with those function names. You are using the same name for javascript and PHP functions.
I think it's not a good idea to use a $_POST variable to store data on demand. The POST request is who creates the POST variables, I don't even know what happens if you modify them in execution time. That scenario is perfect for a global variable.
I'm hoping I'm on the right track here....
I have some elements on my page (tables).. that are dynamically generated based on the results of querying a DB.... (I add inside of a container DIV)..
inside these tables are some text..and a handful of checkboxes... each table is the same (outside of the value of the text fields)..
When a user clicks on a checkbox.. I add an element to another container DIV off to the side.
If a user un-checks the checkbox.. it removes the element from the container DIV on the side. On each 'click' event..... I am also either adding or removing the 'selections' from an ARRAY (and also updating this array to my PHP SESSION)..
When the user is done.. they click a button and go to another page.. where this SESSION array is grabbed and reviews/summarizes their 'choices'..
*there is no FORM tags.. checkboxes are free-form in the tables (not wrapped in any FORM tags..so there is NO general POST action to grab everything.. hence the use of an array/SESSION)
If the user goes BACK to the original 'selection page' (with the tables/checkboxes)..
I am re-populating the PAGE (both re-checking any checkboxes...and re-populating the elements in the container DIV to the side.. all based on the SESSION data)
In each checkbox.. I am adding a little PHP function to write in checked="checked" or not.. when the checkboxes instantiate)
like so:
<label><input id="articlesnaming" name="Articles Naming Expert" type="checkbox" value="0.00" <?=sessionCheck($row["id"] ."-A","Articles Naming Expert") ?> onclick=""/> Articles Naming Expert</label>
FYI: on the function being called:
function sessionCheck($recordID, $checkBoxID){
if(isset($_SESSION['userPicks']) && count($_SESSION['userPicks']) != 0){
for($r = 0; $r< count($_SESSION['userPicks']); $r++){
if($_SESSION['userPicks'][$r]['recordid'] == $recordID){
for($z=0; $z < count($_SESSION['userPicks'][$r]['itemsordered']); $z++){
if($_SESSION['userPicks'][$r]['itemsordered'][$z]['name'] == $checkBoxID){
return 'checked="checked"';
}else if($z == (count($_SESSION['userPicks'][$r]['itemsordered']) - 1)){
return "";
}
}
}else if($r == (count($_SESSION['userPicks']) - 1)){
return "";
}
}
}else{
return "";
}
}
Everything up to this point works fine...
Its when I go to dynamically build/add (append) those elements in the container DIV on the side... where problems happen.
I am getting them added just fine and when a user RE-VISITS the page.. previous checkboxes they had selected were/are checked again... -and-.. the elements ARE in the container DIV to the side of the stage/screen)...
PROBLEM: When I un-check one of the checkboxes, it DOES NOT remove the element in the container DIV on the side? I have to re-click the checkbox..(which adds a duplicate).. then I can un-check it.. but it only removes the NEW one..
Everything seems to work fine until a refresh/re-visit of the page (and I have to automatically populate the checkboxes and the elements in the container DIV on the side).. then the checkboxes stop behaving/interacting with the elements that were adding through another function (still same ID's...paths..from what I can tell)....and -not- added through an initial checkbox event/action..
I am grasping at straws here.... it is perhaps because I'm using a PHP function to set the checkboxes on refresh? and it maybe doesn't know its current state? (although the visual state of the checkbox is accurate/correct)
Any ideas are appreciated.
Code used to set/un-set checkboxes & add/remove elements from the side container DIV :
<script>
//var to hold current check box clicked
var targetCheckbox;
//var to hold cumulative total
var totalPrice = 0;
//array to keep track of user picks from returned record results
//try to get SESSION array (if available/set) from PHP into jQuery using json_encode()
<?php if(isset($_SESSION['userPicks'])){ ?>
//overwrite jQuery userPicks MAIN array
var userPicks = <?php echo json_encode($tempArray) ?>;
<? }else{ ?>
//create new jQuery userPicks MAIN array, and populate through user clicks/interaction
var userPicks = [];
<? } ?>
$(document).ready(function() {
//check to see if seesion and populate checks and side column from previous picks
//if existing session, loop through and populate the CHOICES column
if(userPicks.length > 0){
console.log("SESSION EXISTS, POPULATE CHOICES COLUMN FROM ARRAY");
for(i=0; i<userPicks.length; i++){
//build up sub array data first then append at one time.
var subArrayLength = userPicks[i].itemsordered.length;
var subArray = '';
for(s=0; s<subArrayLength; s++){
subArray += '<li id="' + userPicks[i].orderid + userPicks[i].checkboxid + '">' + userPicks[i].itemsordered[s].name + '</li>';
}
$("#choicesWrapper #itemList").append('<div class="recordChoices"><h5>CASE NAME: '+userPicks[i].casename+'</h5><ul id="'+userPicks[i].recordid+'">'+subArray+'</ul></div>');
}
}
//onClick event
$('.orderOptions').on('click', 'input:checkbox', function () {
//routine when checkbox is checked
if ($(this).is(":checked")) {
$(this).prop("checked", true);
console.log("checked");
//console.log('doesnt exist..create it');
$("#choicesWrapper #itemList").append('<div class="recordChoices"><h5>CASE NAME: '+caseName+'</h5><ul id="'+resultsID+'"><li id="'+orderID+targetCheckbox+'">'+itemOrdered+'</li></ul></div>');
}else{
$(this).prop("checked", false);
console.log("un-checked");
//remove the option from right column (li element)
console.log("REMOVE TARGET: #choicesWrapper #itemList #"+resultsID+" "+orderID+targetCheckbox);
$("#choicesWrapper #itemList #"+resultsID+" #"+orderID+targetCheckbox).remove();
//check if no more children and remove parent/title (record container/div)
if ($("#choicesWrapper #itemList #"+resultsID+" li").length > 0) {
//console.log("Still has children...do nothing");
}else{
//console.log("No Children...");
$("#choicesWrapper #itemList #"+resultsID).parent().remove();
}
}
}
}
</script>
Oddly enough, when things are 'auto-populated' from the SESSION data (like on refresh or re-visiting the page) and when things 'break', unchecking the checkboxes doesn't remove things, but when I uncheck the very last checkbox in a group, it does remove the parent (so that parent removal code/routine is being executed...but not then child )
I'm thinking this is a pathing issue? (I believe I am creating things with exactly the same ID's/classes...etc).
Definitely worth the +1 if you answer! :)
The only other thing I can think of is.. HOW the userPicks array gets created.. initial visit to page, I just create an empty JS/jQuery array and wait to push/populate it when a user clicks a checkbox (code above for onClick stuff).
But when a user visits the page (refresh or re-visit) and -HAS- (previous) SESSION data still available.... then I grab the PHP SESSION array.. and pass it to jQuery using json_encode()...
Do I need to add/delete from that array differently than I do if I created normally?
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);
}
Alright... this seems complicated for me..
I don't know if it is.
filename: add_types.js
I have some data, which i create into mysql db (is for a back-end system).
through jquery/ json. It work fine.
var last_id = data.last_id;
var fck_editor = data.fck_editor;
var new_data = '<div id="input_highlight'+last_id+'"><strong style="font-size:14px;">Overskrift:</strong> <br />';
new_data += '<input type="text" name="overskrift[]" /><br />';
new_data += '<input type="hidden" name="tekst_id[]" value="'+data.last_id+'" />';
new_data += fck_editor;
new_data += '<img src="/gfx/admin/icons/delete.png" alt="" />Slet';
new_data += '</div><div id="loader'+last_id+'"></div><br />';
$(div_id).append(new_data);
Now I just need to update it (in the same file where it gets outputed)
rejser.php
my data goes out here in a div
<div id="add_here" class="add_here_bg"></div>
I want the ouput from add_types.js to be updated in db when i submit another form in the rejser.php file.
pls inform me, if my question is understandable.
You could use a regular jQuery AJAX-request, which submits the contents of your div to a server-side script:
var content = $('#add_here').html();
$.get(url_of_script, content);
And then have the script add it to the DB. Are you familiar with using PHP/MySQL to do this?
If you want to update this stuff when a form is submitted, try attaching an event listener to the onSubmit event of the form.
Edit:
So, first add the onSubmit attribute to your form:
<form onSubmit="return formSubmit(event);">
Now, you'll have to define this function somewhere - really doesn't matter where you do it, though the <head> section of your page is recommended. External file is, of course, also possible.
function formSubmit(event) {
var content = $('#add_here').html();
// this callback will make sure the form is submitted after having completed the other request
var callback = function() { event.target.submit() };
$.get(url_of_script, content, callback);
// Now, cancel the default event, the callback will take care of the submit afterwards
event.stopPropagation();
}
Haven't tested it, but something like this is supposed to work. Let me know if you need some more help.