I am having a HTML table with 5 rows (say) which is being displayed on the webpage. The first column of the table is RowID (which is unique for each row) and the last column of each row is a [X] button (which on click will remove the row). The whole table is in a <div> element with id="cartmain"
<div id="cartmain">
<table>
<tr>
<td>....</td>
<td>....</td>
<td> [X] </td>
</tr>
..
..
</table>
</div>
This is how I am removing the row:
STEP1: When user clicks on [X] button, an XMLHTTPRequest function will send message to a PHP code with unique id of each row. During the time PHP code is removing the row, DIV element shows "Loading..."
document.getElementById("cartmain").innerHTML = "Loading..."
STEP2: PHP code will delete the row from table (and from database) and will return the remaining table.
<?php
//removing row from database/table...
//send the remaining table back to the XMLHTTPRequest function...
echo "<table>";
echo "<tr><td>...</td>
<td>...</td>
<td> [X] </td>";
echo "</tr>";
...
...
...
echo "</table>";
?>
This remaining table received from the PHP code is then shown in the DIV element by using the below line:
document.getElementById("cartmain").innerHTML = removeitem.responseText;
My Problem:
Suppose I have table with 5 rows. When I click on the Remove button, the row is removed successfully and table is then displayed with 4 remaining rows. Here comes the problem: When I want to remove another row from the table: Nothing is Happening. In other words, if I again click on [X] of some row then nothing happens. The XMLHTTPRequest function is not called. In ideal case, it should have called the XMLHTTPRequest function again with that unique RowID and table should then be displayed with remaining 3 rows.
IMPORTANT NOTE: When I refresh the page, then I am able to remove another row. But this time also, I can remove only one row. For removing one more, I have to refresh the page again.
Is anyone able to identify the problem here? Please help.
NOTE: My table actually is a Shopping Cart which contains a product in each row. [X] button actually signifies "removing the item" from the cart.
Here is the JavaScript code:
function removeitem(itemid)
{
alert("The item to be removed is: "+itemid);
if(window.XMLHttpRequest)
{
removeitem = new XMLHttpRequest();
}
else
{
removeitem=new ActiveXObject("Microsoft.XMLHTTP");
}
removeitem.onreadystatechange=function()
{
if (removeitem.readyState==4 && removeitem.status==200)
{
document.getElementById("cartmain").innerHTML=removeitem.responseText;
}
else if(removeitem.readyState < 4)
{
document.getElementById("cartmain").innerHTML="Loading...";
}
}
var linktoexecute = "cart.php?option=5&itemid="+itemid; //option =5 signifies that I want to remove the item with ITEMID.
removeitem.open("GET",linktoexecute,true);
removeitem.send();
}
The function removeitem shows an alert "The item to be removed is: 123" for the first time but does not shows second time. When I am checking in Firebug console, the following error is coming second time:
removeitem is not a function
Please help!!
All my Javascript functions are in a separate file (sc.js) for which I am using <script type="text/javascript" src="js/sc.js"></script> in the HEAD tag of my page.
My viewpoint: So finally I think the question comes to a simple point: If a webpage is requesting some HTML from a PHP page using XMLHTTPRequest -- and if that HTML (sent by PHP) contains some button which is calling a Javascript function -- then what will happen in this situation[?]. Now since I am able to remove the row for the first time, I think it is false to say that above situation will not work. It is just that the code that came from PHP and the Javascript which has already been loaded are not aware of each others presence when I click the button second time.
Inside the removeitem function, you're overwriting removeitem by a XMLHttpRequest object. Hence the later error removeitem is not a function.
To fix this, either prefix removeitem by var (recommended), or use another variable name, or both.
Recommended code:
function removeitem(itemid) {
alert("The item to be removed is: "+itemid);
var removeitem = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
removeitem.onreadystatechange = function() {
if (removeitem.readyState == 4 && removeitem.status == 200) {
document.getElementById("cartmain").innerHTML = removeitem.responseText;
} else if(removeitem.readyState < 4) {
document.getElementById("cartmain").innerHTML="Loading...";
}
}
var linktoexecute = "cart.php?option=5&itemid="+itemid; //option =5 signifies that I want to remove the item with ITEMID.
removeitem.open("GET", linktoexecute, true);
removeitem.send();
}
Adding var before removeitem fixes the problem, because the variable is locally defined. When var is omitted, a new value will be attached to the closest parent declaration (the function, in this case).
var removeitem = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
The previous line is short for:
var removeitem;
if (window.XMLHttpRequest) {
removeitem = new XMLHttpRequest();
} else {
removeitem = new ActiveXObject("Microsoft.XMLHTTP");
}
it doesn't look like you're escaping your double quotes like #Rob W has stated. I generally use single quotes when using php to write out HTML. I find this to be a good practice in my opinion.
The only other thing I can think of is that maybe your function isn't outside AJAX response text. Just check Firebug or view source of what's being rendered after the first response returned.
I hope this helps.
Why you load all table html every click? You can send only true or false when deleting and after you can remove TR element with jQuery.
Removing TR:
In your removeitem function, after ajax response, just call $(this).parents("tr").remove();
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.
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?
I'm having a problem with my infinite scrolling. As I scroll down, it loads the next items fine but it keeps sending those items. I've been using this jquery to give it a unique id because I have ordered the items with mysql with an algorithm:
$("#image-list li").each(function(index) {
$(this).attr('id', index);
});
and inorder to label the newly given items from an external php file, I have to use this code in the file as well.
To send the information about the items given, I've been using this jquery:
function last_db_item_function()
{
var ID=$(".db-item:last").attr("id");
$('div#last-db-item-loader').html('<img src="loading.gif" height="30px" />');
$.post("index.php?action=get&last_db_item="+ID,
function(data){
if (data != "") {
$(".db-item:last").after(data);
}
$('div#last-db-item-loader').empty();
});
};
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
last_db_item_function();
}
});
but the problem is that it does not seem to work. Which I mean it doesn't not gather that last item id from the newly parsed php file. To parse the php I've been doing this:
$last_db_item = $_GET['last_db_item'];
$action = $_GET['action'];
if($action != "get")
{
.... Code Here....
}else{
include ('secondimages.php');
}
So my question is, why does this seem to go on forever?
It looks like you're never assigning a new ID to the new elements when you append them to the list. The first snippet you have either needs to be called after every new element is added, or similar code needs to be applied to that one element when you add it (unless it's coming back in the php, at which point we'd need to know more about what you're returning)
I am making a web page which will allow users to input and view data for different dates, and to change the date, there are two buttons, one of which will display the previous day, and one which will show the next day. I know that I can do this by submitting forms and reloading the page every time they press one of these buttons, but I would rather use javascript and not have to submit a form, but I am having troubles getting it to work. Currently, I have the two buttons, and the date stored in a PHP variable, as shown in my code below:
<script>
function init() {
<? $nutrDate = $this->parseDate(date('m/d/Y')); ?>
}
function nutrPrevDay() {
<? $nutrDate = mktime(0, 0, 0, date('m',$nutrDate), date('d',$nutrDate)-1, date('Y',$nutrDate)); ?>
alert("<? echo(date("m/d/y", $nutrDate)) ?>");
}
function nutrNextDay() {
<? $nutrDate = mktime(0, 0, 0, date('m',$nutrDate), date('d',$nutrDate)+1, date('Y',$nutrDate)); ?>
}
window.onload = init;
</script>
<p style="text-align:center; font-size:14px; color:#03F">
<button onclick="nutrPrevDay()" style="width:200px" >< Show Previous Day</button>
<? echo(date('m/d/Y', $nutrDate)) ?>
<button onclick="nutrNextDay()" style="width:200px">Show Next Day ></button>
</p>
I have the alert in the nutrPrevDay() only as debugging. What happens is when I click on the button, the alert shows that the day is correctly decreased (for example from May 17 to May 16), but only decreases one day, and not one day for every click. Also, I do not know how to make the text on the page (created by the line ) change to display the new date after a button is clicked.
So here are my questions:
1) Is it possible to dynamically change data (such as text, and in the future, SQL queries) on a page using javascript without having to reload a page when clicking on a button?
2) If possible, how can I make those changes?
3) How can I fix this so that it will increment and decrement through dates every time a button is clicked?
Q1:
Yes, it is possible, AJAX is probably what you're looking for.
Q2:
Well, first of all you have to learn that JavaScript works at client side while PHP works at server side. With that in mind, you can't expect that php scripts are executed when you click a button just because you wrote them inside javascript functions.
The most you can do is print something from a PHP script into a JavaScript script. And your script fails in that, except for the alert part. Example:
<script>
function javascriptFunction(){
// This php script, will be executed when you call your page, however $nutrDate is an assigned php variable, javascript will never know about it;
<?php $foo = 'bar'; ?>
// This will give you a javascript error because $foo is a string
var foo = <?php echo $foo; ?>;
// This is the code which will do the expected, notice the quotes.
var foo = '<?php echo $foo; ?>';
// If you have a single quote inside $foo, it will break javascript
<?php $foo = "ba'r";
var foo = '<?php echo $foo; ?>';
}
</script>
Q3:
The idea is to make an AJAX request every time your buttons click event is triggered... This is the same as saying, when you click a button, you call a javascript function which will make a request to some other page and get something from it if the request is successful. Here the example:
<script>
var current = <? echo time(); ?>;
function requestSomething(action){
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
// readyState info: http://www.devguru.com/technologies/xmldom/quickref/httpRequest_readyState.html
if (xmlhttp.readyState==4 && xmlhttp.status==200){
// this is where we tell where the result will appear
document.getElementById("current").innerHTML=xmlhttp.responseText;
current = xmlhttp.responseText;
}
}
xmlhttp.open("GET","somescript.php?action="+action+'&curday='+current,true);
xmlhttp.send();
}
</script>
<p style="text-align:center; font-size:14px; color:#03F">
<button onclick="requestSomething('decrease')" style="width:200px" >< Show Previous Day</button>
<!-- this is where the result will appear -->
<span id="current"></span>
<button onclick="requestSomething('increase')" style="width:200px">Show Next Day ></button>
</p>
Now, at your somescript.php file,
<?php
if(isset($_GET['action'])){
if($_GET['action'] == 'increase'){
// your increasing day logic here
} elseif ($_GET['action'] == 'decrease'){
// decreasing logic here
} else {
// whatever...
}
}
?>
Note: This is almost written from scratch and with some copy/past from here and there, and didn't check if the code actually works... It is just a guideline...
Hope it helps.
You don't need Ajax for this. There is very little you can do with PHP that you can't do with Javascript - you should only use Ajax when you absolutely need to communicate with the server (ex: need something from the database, etc.). Even if you may be using Ajax a later point you shouldn't use it everywhere, especially when a simple script may be able to solve your problems.
As it so happens Javascript has a number of built-in date functions that are every bit as powerful as PHP's.... and if they don't do what you need out of the box you can easily write your own.
http://www.w3schools.com/jsref/jsref_obj_date.asp
Keep it simple.
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!