I have a table as the following datatable table :
<button id="addRow">Add New Row</button><br>
<table class="table table-striped table-bordered table-hover " id="example" cellSpacing=0 width="100%">
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
</tr>
</thead>
<tr style="text-align: center;">
<td>hola</td>
<td>ciao</td>
<td>bonjour</td>
<td>yo</td>
<td>salut</td>
</tr>
</table>
I'd like to append elements using a javascript script as the following :
<script type="text/javascript">
$(document).ready(function () {
debugger;
var t = $('#example').DataTable({ "searching": true, "paging": true });
var counter = 1;
$('#addRow').on('click', function ciicici() {
var now = new Date();
var now = now.toMysqlFormat();
var tii = new Date();
tii.setSeconds(tii.getSeconds() - 50000);
var tii = tii.toMysqlFormat();
$.post( "sqlmachine_test_ajax.php", { timing: now,seconding: tii })
.done(function( data ) {
t.row.add([
counter +'.1',
counter +'.2',
counter +'.3',
counter +'.4',
counter +'.5'
]).draw();
counter++;
// });
//setTimeout(function(){ciicici();}, 5000);
}); // Automatically add a first row of data
$('#addRow').click();
});
</script>
The two are working properly, the only thins is that I'd like to retreive the elements to append trough an Jquery AJAX script.
Let's say I have a php page sending back 5 values I'd like to add to each column (instead of the counter1, counter2 etc...) as the following :
<?php
echo 'counter1, counter2, counter3, counter4, counter5';
?>
and in the javascript I wanted to put simply :
...
.done(function( data ) {
t.row.add([
data //(instead of the counters)
]).draw();
counter++;
...
I have tried this, as well as arrays and json encoded arrays, but all I get is the 5 results in the same first cell of the table.
So how could I append the ajax php response to a table as data in different cells of the table?
marko
When you get your data back from the call, you have to separate using .split().
so you can do this when you get your callback
.done(function( data ) {
var splitData = data.split(", ") //Split your data with the comma and space
$.each(splitData, function(e){ //For each piece of data
//Add your rows here one by one
t.row.add([
splitData[e] //Make sure the 'e' in the function and here are the same
]).draw();
})
counter++;
});
This a loose answer, I'll try to add more soon.
Edit: More info
what I normally do is echo everything with separators. So, in your case, I would echo 1, 2, 3, 4, 5:A, B, C, D, E. So when the data returns, that's what you'll see.
In your data success, you would do something like
var dataParts = data.split(":") //This splits your data into the 2 parts using the : separator
var dataPart1 = dataParts[0] //This will get 1, 2, 3, 4, 5
var dataPart2 = dataParts[1] //this will get A, B, C, D, E
Then from there, you split using commas.
var dataPieces1 = dataPart1.split(', ');
var dataPieces2 = dataPart2.split(', ');
Then run the loops. (using javascript's for loop is usually better than using jQuery's .each())
for(var i = 0; i < dataPieces1.length; i++){ //Start your for loop on the first part
//Create a row here using dataPieces1[i], this will loop and make a new
//row every time the next loop finishes
for(var j = 0; j < dataPieces2.length; j++){ //Start the second loop
//Not sure how you would want to do this, but here's some example code
//Since you're inside a row now, append your dataPieces2[j] to that row
//This will loop for every dataPieces2 and append each one as a column
//in that single row.
}
}
Related
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>
I have a dynamic (via jquery) html table like this:
<form action="index.php" method="post">
<table class="myTable" id="cup">
<tbody>
<tr><td class="header" colspan="6">YOUR SELECTIONS</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> //selected
</tbody>
</table>
<input type="submit" value="submit">
</form>
First, the table has only 1 row and 6 cells (except "selections" part). After some conditions satisfied, the cells get filled with some values and the "selected" row is appended into the table via jquery. But my problem here, is not related to jquery.
Each of 6 cells will be inserted into the mysql table part by part. My database table structure like this:
ID | Selection1 |...| Selection6 | Date, time stuffs and other info.
So, I need some code that will do these jobs:
define an array with 6 element.
counter=0;
loop(until there is no traveled cell in the html table)
{
find a cell that is not NULL or its value is not "selections";
array[counter] <-- value of cell;
counter++;
if (counter == 6)
{
insert all of them into the mysql table (?)
counter=0;
}
}//end loop
So, this is my problem. I just can't know how to do it. Should I have to add "id" or "name" stuffs in the html tags or what? :)
EDIT: I don't want you guys to code it for me of course. The thing I couldn't get is how to separate these values 6 by 6 and send them into the database. I just need ideas.
From the html table data you can construct a JSON object. For instance:
var myData = [],
keys = ['ID','Selection1','Selection2', ..... ]
url = './index.php';
$('table').find('tr:gt(0)').each(function( i, row ) {
var oRow = {};
$( row ).find( 'td' ).each( function( j, cell ) {
oRow[ keys[ j ] ] = $( cell ).text();
});
myData.push( oRow );
});
//myData = [ {"ID":"3u3y","Selection1",....},{"ID":"jdjdj",...}.... ]
//now you can use one key to send all the data to your server
$.post( url, { mydata: JSON.stringify( myData ) }, function(d) {
alert( 'Server said, ' + d );
});
//In your PHP script you would look for the data in mydata --> $_POST['mydata']
EDIT
Click the link below to go to a demo.
In THIS DEMO click submit and then look at the console on the right. Click the plus on the left of the failed ajax call and then click the Post tab to examine the data the call attempted to send.
Does that help?
I've got a script on my website which checks for new database entries every second and updates puts them into a table.
I'm having a problem where the script is deleting the table headers from the page. They still appear in the source code (Right clicking and displaying page source), but they don't appear visible to the user.
The problem seems to lie within "while (tbl.lastChild != tbl.firstChild) { tbl.removeChild(tbl.lastChild); }", but if I remove this line of code, the script will continuously display the same data, over and over again. For example, if I have name 1, name 2 and name 3 in the database. All three will be displayed, and then repeated.
How can I display the table headers, while stopping the data from repeating?
My full script code is:
function tick() {
var xhttp = new XMLHttpRequest();
xhttp.onload = (function() {
var data = JSON.parse(xhttp.responseText);
var tbl = document.getElementById("reports");
while (tbl.lastChild != tbl.firstChild) { tbl.removeChild(tbl.lastChild); }
function cell(data) {
var c = document.createElement("td");
c.appendChild(document.createTextNode(data));
return c;
}
for (var i = 0; i < data.length; i++) {
var row = document.createElement("tr");
row.appendChild(cell(data[i]["id"]));
row.appendChild(cell(data[i]["firstname"]));
row.appendChild(cell(data[i]["lastname"]));
row.appendChild(cell(data[i]["date"]));
var a = document.createElement("a");
var c = document.createElement("td");
a.href = "view.php?id=" + data[i]["id"];
a.appendChild(document.createTextNode("View ID"));
c.appendChild(a);
row.appendChild(c);
tbl.appendChild(row);
setTimeout(tick, 1000);
}
});
xhttp.open("GET", "reportload.php", true);
xhttp.send("");
}
addEventListener("DOMContentLoaded", function() {
tick();
});
You can try create next html table and use it:
<table>
<thead>
<tr>
<th>title1</th>
<th>title1</th>
</tr>
</thead>
<tbody id="reports">
<tr>
<td>value</td>
<td>value</td>
</tr>
</tbody>
</table>
The childern of the HTML node are not only TRs, but also any portion of whitespaces between them, so Your loop probably deletes all TRs and leaves only the first portion of whitespaces.
I would suggest to put header in THEAD and data rows in TBODY and then operate only on TBODY, leaving the header intact.
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/
<html>
<head>
<script src="jquery-1.4.4.js"></script>
<script>
$('table').each(function(a, tbl) {
var currentTableRows = $(tbl).attr('rows').length - 1;
$(tbl).find('th').each(function(i) {
var remove = 0;
var currentTable = $(this).parents('table');
var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')');
tds.each(function(j) { if (this.innerHTML == '') remove++; });
if (remove == currentTableRows) {
$(this).hide();
tds.hide();
}
});
});
</script>
</head>
<body>
<table border="1" >
<tr><td colspan="4" > alaa </td></tr>
<tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4</th></tr>
<tr ><td>1st</td><td>1.1</td><td></td><td></td></tr>
<tr class="data"><td>2nd</td><td>2.1</td><td></td><td></td></tr>
<tr class="data"><td>3rd</td><td>3.1</td><td></td><td>1</td></tr>
<tr class="data"><td>4th</td><td></td><td></td><td></td></tr>
<tr ><td></td><td></td><td></td><td></td></tr>
<tr class="data"><td></td><td></td><td></td><td></td></tr>
</table>
</body>
here is my code ... I thought that the problem from the library, so I tried many libraries such as jQuery 1.4.4 , 1.5.2 and others
Here is the test and it works fine there http://jsfiddle.net/nlovatt/JsLn8/
but in my file .. it doesn't work ..
regards,
There are two reasons your code isn't working.
1) You're executing the script immediately upon loading of the HEAD, at this stage, your table doesn't exist and so it does nothing. To fix this, make sure you execute it on page load instead.
2) When you're comparing the number of blank cells in the column with the number of total rows in the table, you're missing the fact that most of your columns don't have the same number of rows as the table (your first row is only one column wide). You need to compare to the number of rows in the actual column, or better yet, just do the reverse thing and check for non-empty columns.
The full code then becomes:
$(document).ready(function() {
$('table').each(function(a, tbl) {
$(tbl).find('th').each(function(i) {
var remove = true;
var currentTable = $(this).parents('table');
var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')');
tds.each(function(j) { if (this.innerHTML != '') remove = false; });
if (remove) {
$(this).hide();
tds.hide();
}
});
});
});
try it like this
$('#mytable tr th').each(function(i) {
//select all td in this column
var tds = $(this).parents('table')
.find('tr td:nth-child(' + (i + 1) + ')');
//check if all the cells in this column are empty
if(tds.length == tds.filter(':empty').length) {
//hide header
$(this).hide();
//hide cells
tds.hide();
}
});
for hiding columns in table if all cells in column are empty