Populate table contents from PHP array using AJAX - javascript

I have a table as below;
<table>
<tr>
<td id="prev">prev</td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td class="content"></td>
<td id="next">next</td>
</tr>
</table>
and a PHP file, ajax.php for AJAX calls as;
<?php
$array = array(1,2,3,4,5,6,7,8,9,10);
$page = $_POST["page"];
$quantity = 5;
$offset = ($page-1)*$quantity;
$selectedFiles = array_slice($array, $offset, $quantity);
echo $selectedFiles;
?>
The PHP function is suppose to return an array with a limited number of elements with respect to $_POST["page"] like in pagination. The script will return first 5 elements for $page = 1, second 5 elements for $page = 2, etc..etc.. When page loads, the <td>s having id content may display 1,2,3,4 and 5 respectively.
When user click next, it may display next results and may return to previous result if user click prev. How can I do this using JavaScript using jQuery?
It will be more helpful if some effect is given when user clicks and data changes, like sliding (transition), so that it will look like sliding some bar.

Save yourself a TON of time. Use a pre-done grid solution like DataTables that does all this work for you. It allows you to sort, filter, paginate, order, and limit your table results that can be fed via the dom, JSON, or true server-side AJAX.
Since DataTables is such a mature project, it has already overcome all the random issues with cross-browser quirks, etc.
It also includes a pre-done PHP example with the query done for you. Just change to match your table, and voila!

This should help you get started:
<table id="pageLinks">
<tr>
<td id="prev">prev</td>
<td class="content">1</td>
<td class="content">2</td>
...
<td id="next">next</td>
</tr>
</table>
var currPage = 1;
$("#pageLinks tr td").click(function() {
if($(this).hasClass("content")) {
var currPage = $(this).text();
} else {
if(this.id == "next") {
currPage++;
} else {
if(currPage > 1)
currPage--;
}
}
$.post("script.php", {currPage: currPage}, function(html) {
$("#someDiv").hide().html(html).slideUp();
});
});
Notes:
IDs should not be duplicated in a document, so I've given those cells the class 'content' instead.
I don't fully understand your question, so I've assumed that the table is for paginated links, and you're loading in the content elsewhere.

Related

Unexpected behavior while looping a table

I'm creating a table while looping through an API array and I've hit a couple snags. Here is the repeated HTML ->
$html = "
<tr class='mt-2'>
<td>{$rank}.</td>
<td><img src='{$image}' height='75' width='75'></td>
<td>{$name}</td>
<td class='bold'>\${$final_worth}B</td>
<td class='{$class}'>\${$last_change}</td>
<td>{$country}</td>
<td>{$source}</td>
<td><button class='bg-color-primary text-color-third px-2' id='more_btn' onclick='showDetails({$cnt})'>More</button></td>
</tr>
<tr >
<div id='details'>lorem ipsum wahoo baby</div>
</tr>
";
Everything was going as expected until I went to add the second row (div#details).
There's actually 2 issues at play here - the first is how I make each button/div#details connected so button1 only effects div1 etc.
I can't tackle that one yet though, because right now when any button is clicked div#details shows up above the table header rather than underneath the previous row.
So until I have the positioning correct I can't really tackle the js functionality. Can someone please tell me why the <tr><div#details> is not appearing underneath it's previous row? The js code is as follows ->
<script>
var cnt = <?php echo $cnt; ?>;
function showDetails(cnt) {
var details = "details";
var x = document.getElementById(details);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
I know the code is a mess right now. It's kind of shameful lol but like I said I can't really do more with it until I can figure out why that table row isn't positioning properly
Try changing it to
<tr>
<td colspan='8' id='details'>lorem ipsum wahoo baby</td>
</tr>
If it isn't in a cell, it's rejected from the table, which is why it appears above.

How can I display first 3 values from a foreach loop and on click more display All the Values from the row

I am looping through a list of values and there are more than 22 values. I want to just show maximum 3 values and a click more button so it can display all the values as the user request.
I am a little bit confuse on how to do that.
This is what I did before which when you click on the plus it will show all the records and when you click on the minus it will hide all the records
Do we have to limit the number values on the sql query or is there a PHP way to show three records and then using Javascript to display all?
Help a sister out ^^
<table>
<thead>
<tr>
<th>Std Id</th>
<th>List of Names</th>
</tr>
</thead>
<tbody>
<?php
foreach ($Names as $key => $name): ?>
<tr>
<td><?= $key ?></td>
<td class="collapse-control collapse-plus">
<?php
$students = [];
foreach($name as $r){
if(!in_array($r->getStudent(), $students ))
$students []=$r->getStudent();
?>
<span class="form-names d-none"><?= $row->getName()?><br> </span>
<?php } ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Script
$(document).ready(function() {
$('.collapse-control').on('click', function(e) {
var $cell = $(this).toggleClass('collapse-plus collapse-minus');
$cell.find('.form-names').toggleClass('d-none');
});
});
You can show all the data in PHP using loop (like what you did). Now, you just need to add a condition inside the loop. Tell the loop to show the first three items without any style or class of display:none, then the rest will have a class or style. The idea is like this:
$counter = 0;
foreach($name as $r)){ // your loop here
if($counter < 3){ //show the first 3 items
echo "<span class='form-names'>".$row->getName()."</span>";
}else{ //show the rest items but hide it
echo "<span class='form-names' style='display:none'>".$row->getName()."</span>";
}
$counter++;//add a counter
}
Then you can now trigger a button, when clicked, it will show all .form-names. OR you can use your existing JQuery toggle function.
No need to use array_slice, you just add a counter variable to check if the item is greater than 3. The use of this is to show the first 3 items as normal (no style of display:none), but the rest items will loop with style of display:none so it will hide on the webpage (but it is already loaded in DOM).

How to automatically call a JavaScript that modify a value before show this value?

I am very new in JavaScript and I have the following problem to solve.
I have a table that contains this td cell:
<td class= "dateToConvert" width = "8.33%">
<%=salDettaglio.getDataCreazione() != null ? salDettaglio.getDataCreazione() : "" %>
</td>
This retrieve a String from an object and show it into the cell
The problem is the retrieved string represent a date having the following horrible form: 20131204 and I have to convert it into the following form: 2013-12-04.
So I am thinking to create a JavaScript that do this work when the value is retrieved.
My problem is: how can I do to automatically call the JavaScript before to show the value into the td cell? (So I show the modified output in the desidered form)
EDIT 1:
So I have create thid JavaScript function into my page:
function convertData() {
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.innerText = td.innerText.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
}
But it don't work because it never enter in this function (I see it using FireBug JavaScript debugger). Why? What am I missing? Maybe have I to call it explicitly in some way in my td cell?
Of course it is better to fix backend method to make it return proper format. But since you have no control over it try to use something like this:
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
Check the demo below.
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
<table>
<tr>
<td class= "dateToConvert" width = "8.33%">
20131204
</td>
<td class= "dateToConvert" width = "8.33%">
20140408
</td>
</tr>
</table>

Filter table data with Jquery based on HTML input

Can you please help me code Jquery right way so i can filter HTML table based on text input. So far this is my code:
<input type="text" name="inputdata" id="inputdata" onkeyup="filter()">
<table>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
<tr name="data">
<?php foreach ($products as $row) { ?>
<td><?php echo $row->id_product; ?></td>
<td><?php echo $row->name; ?></td>
<?php } ?>
</tr>
Jquery code
<script>
function filter(){
inp = $('#inputdata').val()
$("tr").filter(function() {
return $(this).text().indexOf(inp) == -1;
}).hide();
}
</script>
So my problems are:
Search is case sensitive
When i input some string, let's say Pants, Jquery filters data, but then i have to refresh a page, so i can search again. Or let me put this other way... When i delete inputted data in search field, table isn't refreshed. It just stay on Pants data, so for another search i have to reload web page
<th> are removed when searching for data. If i declare $('tr[name=data]').filter(function() { search stop working
thx in advance for helping me!
This should take care of your issues:
<script>
function filter(){
inp = $('#inputdata').val()
// This should ignore first row with th inside
$("tr:not(:has(>th))").each(function() {
if (~$(this).text().toLowerCase().indexOf( inp.toLowerCase() ) ) {
// Show the row (in case it was previously hidden)
$(this).show();
} else {
$(this).hide();
}
});
}
</script>

Getting inner tag element inside an "each"

I've been messing around with different forms and tables, now I need something that takes data from table tr and td field, runs a if statement on each fetched item, and outputs text inside the form, depending what was found in td fields.
So right now I have something like this, which doesn't do anything useful at all, for now, just outputs td-01 class values into the form:
var test;
$('tbody tr').each(function(index) {
test = $(this+'.td.td-0');
$('fieldset.csc-mailform').after($('td.td-0'));
});
and my table structure looks something like this:
<table class="contenttable contenttable-3 tabel">
<tr class="tr-even tr-0">
<td class="td-0">01</td>
<td class="td-1">Valik 1</td>
<td class="td-last td-2">150€</td>
</tr>
<tr class="tr-odd tr-1">
<td class="td-0">01</td>
<td class="td-1">Valik 2</td>
<td class="td-last td-2">50€</td>
</tr>
<tr class="tr-even tr-2">
<td class="td-0">01</td>
<td class="td-1">Valik 3</td>
<td class="td-last td-2">170€</td>
</tr>
<tr class="tr-odd tr-3">
<td class="td-0">01</td>
<td class="td-1">Valik 4</td>
<td class="td-last td-2">88€</td>
</tr>
</table>
Right now it only find tr tags and outputs all of them. I need it to split the tr tag up, run if condition on td-0 to determine if it needs to be radio button/text input/checkbox etc, then see what td-1 contains and make that field name, then td-2 is for example a price. all of this should end up in a form.
So as you can see, I am stuck with jQuery, but I think it should be doable.
edit:
I got something like this after messing around a little, but my if statements don't seem to work on jQuery objects, any way to get around this?
var check1;
$('tbody tr').each(function(index) {
//test = $(this+'.td.td-0');
check1 = $('td.td-0');
alert(check1);
if(check1=='01'){
content_type="checkbox";
}else if(check1=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type);
//$('fieldset.csc-mailform').after($('td.td-0'));
});
//edit2
Ugh, I was running if statement against jQuery object, of course it didn't work.
I got it working with this, looks quite nasty, but it seems to work:
$('tr').each(function () { var val = $(this).children('td:first').text();
//$check1 = $('td.td-0');
if(val=='01'){
content_type="checkbox";
}else if(val=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type + '<br/>');
}
);
Now, I need to figure out how to create input fields from these.
You could possibly make it a bit cleaner by using the jQuery selector context, e.g.:
$('tr').each(function () {
var val = $('td:first', this).text();
..
}
Something like this will do:
$('table tr').each(function() {
$tds = $(this).children();
for(var i=0;i<$tds.length;i++){
$td = $tds[i];
if($td.hasClass('td-0'){
//do your thing by getting next TD or something else
break;
}
}
});

Categories

Resources