I'm new to PHP and Ajax. I am trying to create a table of object data where I can select the displayed data based on a <select><option>... form.
I have a PHTML template which looks like the following:
<?php
$content = "";
// creates data selector
$content .= "
<form id = select_data>
<select id = data_selection>
<option value = data1>Data 1</option>
<option value = data2>Data 2</option>
<option value = data3>Data 3</option>
<option value = data4>Data 4</option>
</select>
<input id = selected_data type=submit />
</form>";
// creates table header
$content .= "
<tr>
<th>Data</th>
</tr>";
$array_ids = array(1, 2, 3); // etc, array of object id's
foreach ($array_ids as $array_id) {
$object = // instantiate object by array_id, pseudocode
$object_data = $object->getData('default-data'); // get default data to display
// create table item for each object
$content .= "
<tr>
<td><p>$object_data</p></td>
</tr>";
}
print $content;
?>
This prints out the table content, loads objects by their id, then gets and displays default data within the <p> tag.
And then I have some Javascript which looks like the following:
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).ready(function(){
$('#select_data').on('submit', function(e){ // get selected data type
e.preventDefault();
var data_selected = $("#data_selection :selected").val(); // create var to pass to ajax
$.ajax({
type: "POST",
url: 'post.php',
data: {data_selected: data_selected},
success: function(data){
$("p").html(data); // replace all <p> tag content with data
}
});
});
});
</script>
This Javascript gets the selected data type, creates a variable out of it to pass on to the ajax which then calls post.php, which looks like the following:
<?php
$attribute = false;
if (isset($_POST['data_selected'])){
$data = $_POST['data_selected']; // assigns variable out of ajax data
$object = //instantiate object, again pseudocode
$object_data = $object->getData($data); // get new data to replace into the ```<p>``` tag
echo $object_data;
}
?>
The problem is that the Javascript that I have changes every single <p> tag to the last data iterated by the foreach loop because each <p> tag is not uniquely identified and the Ajax does not update the data based on a unique identifier, such as maybe the $array_id. Which brings me to my attempted solution.
I tried to identify each <p> tag with the following:
<td><p id = $array_id>$object_data</p></td>
And then creating a new Javascript variable out of the array ID:
var p_tag_id = <?php echo $array_id; ?>;
And finally making the Ajax success function target element ID's based on var p_tag_id:
$("#" + p_tag_id).html(data);
While this does not change all the <p> tags like previously, it only changes the final <p> tag and leaves all instances before it unchanged because the Javascript is not iterating over each <p> tag, or because the foreach loop does not call the Javascript as a function for each $array_id.
How can I rewrite this code so that the Ajax updates the data of each table item uniquely instead of updating them all with the same data? Is there a better way to approach this problem?
You need a way to identify the table row containing the <p> tag you wish to update, and perhaps the value attribute of the SELECT element could help.
You can get the number of the clicked option from your data_selected variable by using slice to strip-off the last character (i.e. the number):
var num = data_selected.slice(-1) - 1;
(Subtract 1 because the table rows are zero-indexed)
Then, in the AJAX code block's success function:
$('table tr').each(function(i,v){
if (i == num){
$(v).find('td').find('p').html(data);
}
});
The above grabs all the table rows (as a collection) and loops through them one-by-one. In the function, i is the index number of the row and v is the row itself. Index numbers begin at zero, which is why you earlier subtracted 1 from the (for eg) data3 [3] value, leaving num == 2. When you find the right row number, use .find() to find the <td> in that row, and then the <p> in that <td> and Bob's yer uncle.
I haven't tested the above code so there could be bugs in the example, but off-the-cuff this approach should work.
I figured out a solution. I assigned the $array_id to each <p> tag after all in order to identify them uniquely:
<td><p id = $array_id>$object_data</p></td>
Then I looped over all the <p> tags and assigned the $array_id of this <p> tag to a variable like so:
$("p").each(function() {
var array_id = $(this).attr("id");
And finally I made the Ajax success target elements based on their ID:
$("#" + array_id ).html(data);
Here is the full Javascript code for anybody who is interested. Hopefully this helps someone else out!
<script>
$(document).ready(function(){
$('#select_data').on('submit', function(e){
e.preventDefault();
var data_selected = $("#data_selection :selected").val();
$("p").each(function() {
var array_id = $(this).attr("id");
$.ajax({
type: "POST",
url: 'post.php',
data: {data_selected: data_selected, array_id: array_id},
success: function(data){
$("#" + array_id).html(data);
}
});
});
});
});
</script>
Related
I have fetched the values(card details) from an array and put them in an html table, I have also added the delete button for deleting the particular card.
I am deleting this through ajax. When i click on the delete button of the first row, it works perfect but when i click on the other delete buttons from 2nd or 3rd row, there is no action.
Please suggest the correct path to sort out this problem.
Thanks in advance
Here is my code
<tr>
<td><?php echo $val['last4'];?></td>
<td><?php echo $val['exp_month'];?></td>
<td><?php echo $val['exp_year'];?></td>
<td><button id = "del">Delete</button></td>
</tr>
Ajax part
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
$('#del').click(function() {
//var a=document.getElementById("").value;
var val0 = $('#id').val();
var val01 = $('#cust').val();
var fade = document.getElementById("fade");
var show = function(){
fade.style.display = "block";
}
show();
$.ajax({
type: 'POST',
url: 'mywebsite.com/deleting.php',
data: { card_id: val0,cust_id: val01 },
success: function(response) {
fade.style.display = "none";
// alert(response);
mystring = response.replace(/^\s+|\s+$/g, "");
$('#result11').html(mystring);
}
});
});
</script>
You have the same id on your buttons. Id's must be unique within the html document and can not be shared between multiple elements. Read more about the html id attribute
Change the button to use a class instead:
<td><button class="del">Delete</button></td>
Then change your jQuery to bind to that class instead:
$('.del').click(function(e) {
// Since we're using ajax for this, stop the default behaviour of the button
e.preventDefault();
// Get the value from the clicked button
var val0 = $(this).val();
I also added the event e in the function call, and stopped the default behaviour of the button (which is to submit the form) when it's clicked.
You need to give delete buttons a class and bind event on that class not with id. Then on bind function select values from that row elements and then pass them to Ajax.
I need a dynamic form which is supposed to work like this:
When user press "ADD" button, appear a new ..<.div> DOM to select a package.
Depending on the package, the row must change color (by adding/removing some classes).
But I can't get it working. Here is my HTML:
<button onclick='addDay();'>
<div class='content'>
</div>
My Javascript:
//FUNCTION 1: LOAD AJAX CONTENT
function addDay()
{
baseUrl = $('input#helper-base-url').val();
//Set caching to false
$.ajaxSetup ({
cache: true
});
//Set loading image and input, show loading bar
var ajaxLoad = "<div class='loading'><img src='"+baseUrl+"assets/images/loading.gif' alt='Loading...' /></div>";
var jsonUrl = baseUrl+"car/add_day/"+count;
$("div#loading").html(ajaxLoad);
$("div#content").hide();
$.getJSON(
jsonUrl,
{},
function(json)
{
temp = "";
if(json.success==true)
{
temp = json.content;
}
//Display the result
$("div#content").show();
$("div#content").html($("div#content").html()+temp);
$("div#loading").hide();
});
}
//FUNCTION 2: MODIFY AJAX CONTENT
$("#content").on("change", "select.switch", function (e) {
e.preventDefault();
//Get which row is to be changed in background's color
id = this.id;
id = id.substr(6);
//Add class "package1" which change row's background color
row = "row"+id;
row.addClass('package1');
});
My PHP
function add_day($count)
{
$temp = "<div class='row".$count."'>
<select id='switch".$count."' class='switch'>
<option value='1'>Package 1</option>
<option value='2'>Package 2</option>
</select>
</div>";
$result = array(
'success' => true,
'content' => $temp,
);
$json = json_encode($result);
echo $json;
}
PS. The form is not as simple as this but to make the problem solving easier, I remove the details. But I can't seem to change the class on the fly. Do we have a solution or a good work around here?
Edit 1:
Sorry I didn't make myself clear before. I had no problem with getting the id or variable (it was okay, when I alert it the right value comes out - but after I add the class, no color changes is seen). I run it:
a. On button click, load Ajax content.
b. Ajax content (which results contains a ) loaded successfully.
c. FAIL: On change, add class "package1" to the div row. (So, I had no problem with getting the right id or class name. When I alert the variables it gives the right result, BUT the color doesn't change. I can't check whether class is successfully added or not.)
$("#content").on("change", "select.switch", function (e) {
e.preventDefault();
$('.row' + $(this).attr('id').replace('switch', '')).addClass('package1');
});
Assuming that everything else is ok
//Get which row is to be changed in background's color
id = this.id;
id = id.substr(6);
//Add class "package1" which change row's background color
row = "row"+id;
row.addClass('package1');
This is the problem. To get the attibute id you have to do
var id = $(this).attr('id').substr(6);
You have to use $(this) and not this by the way to use all of jQuery functionalities.
Same below
$(row).addClass('package1');
So, full code:
//Get which row is to be changed in background's color
var id = $(this).attr('id').substr(6);
//Add class "package1" which change row's background color
$('.row'+id).addClass('package1');
Changing the class to id solved the problem (using #row0 instead of .row0). Sorry and thank you for your time :)
So, here's the deal. I have an html table that I want to populate. Specificaly the first row is the one that is filled with elements from a mysql database. To be exact, the table is a questionnaire about mobile phones. The first row is the header where the cellphone names are loaded from the database. There is also a select tag that has company names as options in it. I need to trigger an onChange event on the select tag to reload the page and refill the first row with the new names of mobiles from the company that is currently selected in the dropdown list. This is what my select almost looks like:
<select name="select" class="companies" onChange="reloadPageWithNewElements()">
<?php
$sql = "SELECT cname FROM companies;";
$rs = mysql_query($sql);
while($row = mysql_fetch_array($rs)) {
echo "<option value=\"".$row['cname']."\">".$row['cname']."</option>\n ";
}
?>
</select>
So... is there a way to refresh this page with onChange and pass the selected value to the same page again and assign it in a new php variable so i can do the query i need to fill my table?
<?php
//$mobileCompanies = $_GET["selectedValue"];
$sql = "SELECT mname FROM ".$mobileCompanies.";";
$rs = mysql_query($sql);
while ($row = mysql_fetch_array($rs)) {
echo "<td><div class=\"q1\">".$row['mname']."</div></td>";
}
?>
something like this. (The reloadPageWithNewElements() and selectedValue are just an idea for now)
Save the value in a hidden input :
<input type='hidden' value='<?php echo $row['cname'] ?>' id='someId' />
in your JavaScript function use the value from this hidden input field:
function reloadPageWithNewElements() {
var selectedValue = document.getElementById('someId').value;
// refresh page and send value as param
window.location.href = window.location + '?someVal='+ selectedValue;
}
Now again in your PHP file retrieve this value from url for use as:
$someVal = null;
if (isset($_GET['someVal']) {
$someVal = $_GET['someVal'];
}
see if this works!!!
The best option would be using AJAX.
reloadPageWithNewElements() is a function which calls a page of your own site which will return the data you would like to put in your table.
If you are using JQuery, AJAX is very easy to implement:
$.ajax({
url: '/yourPage',
data: { selectedCompany: $('.companies').val() },
success: function(result) {
//delete your tablerows
$(".classOfTable tr").remove();
//put the result in your html table e.g.
$('.classOfTable').append(result);
},
dataType: html
});
The browser will send a request to "/yourPage?selectedCompany=Google" or something
All you have to do is let this page print out only html (maybe even easier is to print only the tablerow (<tr>).
If you have any further questions, please ask.
I would use jQuery to do it.
first You need to add 'id' attribute to every option tag
<option id="option1">
<option id="option2">
and so on...
then with jQuery:
$('<option>').change(function() {
var id=$(this).attr('id');
...save data here (i.e: with ajax $.post(url, { selected_id: id}, callback }
});
Coming from Adobe Flex I am used to having data available in an ArrayCollection and when I want to display the selected item's data I can use something like sourcedata.getItemAt(x) which gives me all the returned data from that index.
Now working in php and javascript I am looking for when a user clicks a row of data (in a table with onClick on the row, to get able to look in my data variable $results, and then populate a text input with the values from that row. My problem is I have no idea how to use javascript to look into the variable that contains all my data and just pull out one row based on either an index or a matching variable (primary key for instance).
Anyone know how to do this. Prefer not firing off a 'read' query to have to bang against the mySQL server again when I can deliver the data in the original pull.
Thanks!
I'd make a large AJAX/JSON request and modify the given data by JavaScript.
The code below is an example of an actual request. The JS is using jQuery, for easier management of JSON results. The container object may be extended with some methods for entering the result object into the table and so forth.
PHP:
$result = array();
$r = mysql_query("SELECT * FROM table WHERE quantifier = 'this_section'");
while($row = mysql_fetch_assoc($r))
$result[$row['id']] = $row;
echo json_encode($result);
JavaScript + jQuery:
container.result = {};
container.doStuff = function () {
// do something with the this.result
console.debug(this.result[0]);
}
// asynchronus request
$.ajax({
url: url,
dataType: 'json',
data: data,
success: function(result){
container.result = result;
}
});
This is a good question! AJAXy stuff is so simple in concept but when you're working with vanilla code there are so many holes that seem impossible to fill.
The first thing you need to do is identify each row in the table in your HTML. Here's a simple way to do it:
<tr class="tablerow" id="row-<?= $row->id ">
<td><input type="text" class="rowinput" /></td>
</tr>
I also gave the row a non-unique class of tablerow. Now to give them some actions! I'm using jQuery here, which will do all of the heavy lifting for us.
<script type="text/javascript">
$(function(){
$('.tablerow').click(function(){
var row_id = $(this).attr('id').replace('row-','');
$.getJSON('script.php', {id: row_id}, function(rs){
if (rs.id && rs.data) {
$('#row-' + rs.id).find('.rowinput').val(rs.data);
}
});
});
});
</script>
Then in script.php you'll want to do something like this:
$id = (int) $_GET['id'];
$rs = mysql_query("SELECT data FROM table WHERE id = '$id' LIMIT 1");
if ($rs && mysql_num_rows($rs)) {
print json_encode(mysql_fetch_array($rs, MYSQL_ASSOC));
}
Maybe you can give each row a radio button. You can use JavaScript to trigger an action on selections in the radio button group. Later, when everything is working, you can hide the actual radio button using CSS and make the entire row a label which means that a click on the row will effectively click the radio button. This way, it will also be accessible, since there is an action input element, you are just hiding it.
I'd simply store the DB field name in the td element (well... a slightly different field name as there's no reason to expose production DB field names to anyone to cares to view the page source) and then extract it with using the dataset properties.
Alternatively, you could just set a class attribute instead.
Your PHP would look something like:
<tr>
<td data-name="<?=echo "FavoriteColor"?>"></td>
</tr>
or
<tr>
<td class="<?=echo "FavoriteColor"?>"></td>
</tr>
The javascript would look a little like:
var Test;
if (!Test) {
Test = {
};
}
(function () {
Test.trClick = function (e) {
var tdCollection,
i,
field = 'FavoriteColor',
div = document.createElement('div');
tdCollection = this.getElementsByTagName('td');
div.innerText = function () {
var data;
for (i = 0; i < tdCollection.length; i += 1) {
if (tdCollection[i].dataset['name'] === field) { // or tdCollection[i].className.indexOf(field) > -1
data = tdCollection[i].innerText;
return data;
}
}
}();
document.body.appendChild(div);
};
Test.addClicker = function () {
var table = document.getElementById('myQueryRenderedAsTable'),
i;
for (i = 0; i < table.tBodies[0].children.length; i += 1) {
table.tBodies[0].children[i].onclick = Test.trClick;
}
};
Test.addClicker();
}());
Working fiddle with dataset: http://jsfiddle.net/R5eVa/1/
Working fiddle with class: http://jsfiddle.net/R5eVa/2/
I am doing an AJAX request with Jquery and PHP what I am doing is looping through an array and producing a table, each loop a new is created and an id is given to it, when they click the read me link the ajax and some more content is returned, on clicking read more I want the associated table row to be removed from the table is this possible, you can see my attempt so far below.
<div id="new" class="tabdiv">
<table>
<?php
$colours = array("#f9f9f9", "#f3f3f3"); $count = 0;
if(isset($newSuggestions)) {
foreach($newSuggestions as $row) {
if($row['commentRead'] == 0) {
?>
<tr id="<?=$row['thoughtId'];?>" bgcolor="<?php echo $colours[$count++ % count($colours)];?>">
<?php
echo "<td>".substr($row['thought'], 0,50)."...</td>";
echo "<td class='read'><a href='".base_url()."thought/readSuggestion/".$row['thoughtId']."' class='readMore'>Read More</a>";
echo "</tr>";
}
}
} else {
echo "You have no new suggestions";
}
?>
</table>
$('a.readMore').click(function(){
$('#readMore').fadeIn(500);
var url = $('a.readMore').attr('href');
$.ajax({
url : url,
type : "POST",
success : function(html) {
$('#readMore').html(html)
},
complete : function() {
$('tr').remove()
}
});
return false;
});
You can get the id of the row like this:
$(this).parent().parent().attr("id")
$(this) wraps the a element, the first parent gets the td and the next one the tr. Call this inside the click callback. Make sure that the id starts with a letter; it is not allowed to start a number. To delete it, define a variable:
var row = $(this).parent().parent();
You can then delete it at the callbacks:
row.delete();
As kgiannakakis points out you'll need a reference to the element that was clicked.
To find out what went wrong, consider the following lines of your code:
$('a.readMore').click(function(){
var url = $('a.readMore').attr('href');
...
return false;
});
What you do here is add an event handler to all a elements with a readMore class.
When the link is clicked you again select all a elements with a readMore class and retreive the href attribute from the first matched element.
What you want to do is get the attribute from the element that was clicked.
$('a.readMore').click(function(){
var url = $(this).attr('href');
...
return false;
});
The same problem occurs in the success and complete handlers of your ajax request, note that you can't use this in the success/complete handlers because it will probably point to another object so you need to store it in a var before calling the ajax function.