Sometimes function reload(); does't update the div's content. I call this function when clicking a button. Sometimes only one div won't update. Random div, on a random click. Sometimes first click won't work. The div content won't show any error, just a previous not updated number. and when I click the button again it updates and shows the correct one.
Example of the bug (Increasing the #number_input by one every time I click):
div content shows: 1, 2, 2, 4
The problem is with those 2s, 3 is missing. In database the number is correct.
I'm running a local server (XAMPP). Same problem in Firefox, Chrome and IE.
No errors in firebug console. Requests are done correctly but returned value sometimes wrong. Usually only one array item is wrong, the one returned from the database.
Exactly same ajax code with different parameters (on complete) on different button works fine.
PS: Changed my var names into shorter ones so they are eye friendly
Button HTML:
<button id="xButton" class="btn btn-info">Text</button>
Button JS:
document.getElementById('xButton').onclick = function() {
var val = $('#number_input').val();
if (val > 0)
{
var xx = 1;
var yy = 1;
properties(xx, yy, val); //this updates the database by current val + val. Works correctly. Values always updated, no errors there. Clean and simple code. No way this is the source of problem.
number_input.value = 0;
xButton.textContent = ("bla bla"); //just resets the text
p1_reload();
}
}
jQuery:
function reload() {
$.ajax({
type: 'POST',
url: 'example.php',
cache: false,
data: {reload: "action"},
dataType:"json",
success: function(data) {
var xres = new Array();
xres = data;
document.getElementById("x1").textContent = xres[0];
document.getElementById("x2").textContent = xres[1];
document.getElementById("x3").textContent = xres[2];
document.getElementById("x4").textContent = xres[3];
//these two functions has not connection with the updated divs. They don't update or even read them. So, there shouldn't be any problems.
xFunction();
yFunction();
}
});
}
PHP:
if(isset($_POST['reload'])) {
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
try
{
require_once("session.php");
$auth_user = new xClass();
$user_id = $_SESSION['user_session'];
$stmt = $auth_user->runQuery("SELECT * FROM blabla WHERE user_id=:user_id LIMIT 1");
$stmt->execute(array(":user_id"=>$user_id));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
$xxx = $userRow['xxx'];
$yyy = $userRow['yyy'];
$zzz = $userRow['zzz'];
$qqq = ($xxx * $yyy) + ($zzz + $yyy + $xxx);
$xres = array();
$xres[0] = $xxx;
$xres[1] = $yyy;
$xres[2] = $zzz;
$xres[3] = $qqq;
$result = json_encode($xres);
echo $result;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
}
Database return simple integer numbers. No triggers or decimal numbers.
jQuery version: 1.12.4 min.
Clicking every few second (no frequent clicking). Request and response complete in 10-38 ms.
The problem is somewhere in your button js as well as jQuery source. Try replacing textContent with innerHTML(for plain js) or html(JQuery)After replacement it would be
document.getElementById("x4").innerHTML = xres[3]; or as you are using jQuery you could have $("#x4").html(xres[3]).
Related
I have an ajax call which pulls data from the table and then transforms into a JSON object
Because I am also doing a lot with PHP as well I need to have a 2nd AJAX call
immediately after the first that will update $_SESSION info
I have tried putting
$_SESSION['company_id'] = $_POST['companyid'];
in the same file that handles the 1st AJAX call but it then doesn't process the data from the first call, hence I need to do the 2nd call
Here is my jQuery Code for the 1st and 2nd AJAX query
$(".showcompinfo").click(function(){
$("#comptable").hide();
$("#showcomptable").show();
var id = $(this).attr('id');
$("#comp_info").toggle();
var companyid = id;
var dataString = "companyid="+companyid;
$.ajax({ /* THEN THE AJAX CALL */
type: "POST",
url: "../inc/dataforms/complist.php",
data: dataString,
success: function(result){
var jsonObject = JSON.parse(result);
// here you can do your magic
var approved = jsonObject.customer_approved;
$("#showcompname").text(jsonObject.name);
// Get Reg Address Details - Check if any field is empty
var regoffice_2 = '';
var regoffice_3 = '';
var regoffice_city = '';
console.log(jsonObject.regoffice_city);
if(jsonObject.regoffice_2)
{
regoffice_2 = ', ' + jsonObject.regoffice_2;
};
if(jsonObject.regoffice_3)
{
regoffice_3 = ', ' + jsonObject.regoffice_3;
};
if(jsonObject.regoffice_city)
{
var regoffice_city = ', ' + jsonObject.regoffice_city;
};
var addlne1 = jsonObject.regoffice_1;
var regaddress = jsonObject.regoffice_1 + regoffice_2 + regoffice_3 + regoffice_city;
$("#addline1").val(jsonObject.regoffice_1);
$("#addline2").val(jsonObject.regoffice_2);
$("#addline3").val(jsonObject.regoffice_3);
$("#addcity").val(jsonObject.regoffice_city);
$("#addcounty").val(jsonObject.regoffice_county);
$("#countryselected").val(jsonObject.regoffice_country);
$("#countryselected").text(jsonObject.regoffice_country);
$("#addpostcode").val(jsonObject.regoffice_postcode);
console.log(regaddress);
if(approved == '1')
{
$("#approvedcust").text('Yes');
} else {
$("#approvedcust").text('Customer but Not Approved');
};
}
});
// 2nd Ajax
var companyid2 = jsonObject.company_id;
var dataString2 = "companyid="+companyid2;
$.ajax({ /* THEN THE AJAX CALL */
type: "POST",
url: "../inc/updatesession.php",
data: dataString2,
success: function(){
}
});
//
Here is the PHP code for complist.php
if(!empty($_POST['companyid']))
{
$companyid = $_POST['companyid'];
$query = mysqli_query($dbc,"SELECT * FROM `comp_companies` WHERE `company_id` = '$companyid'");
$result = mysqli_fetch_assoc($query);
if($result){
$newdata = json_encode($result);
}
}
print_r($newdata);
If anyone can help even consolidate this into 1 ajax query or help me get 2 calls
working correctly it would be much appreciated
** EDIT **
OK I now have it displaying the Company ID in the session variable however when the user clicks to view a different company info result the session company_id does not update
I have changed the complist.php to the following
if(!empty($_POST['companyid']))
{
unset($_SESSION['company_id']);
$companyid = $_POST['companyid'];
$query = mysqli_query($dbc,"SELECT * FROM `comp_companies` WHERE `company_id` = '$companyid'");
$result = mysqli_fetch_assoc($query);
if($result){
$_SESSION['company_id'] = $_POST['companyid'];
$newdata = json_encode($result);
}
}
print_r($newdata);
My thinking behind the above was that once the ajax call is made it immediately unsets the session variable company info
then once a result is found for the selected company it resets the session var company_id with the new value, however its not updating the session variable
Screenshots showing what I mean
Your code updates your session variable successfully. However, since you're making an AJAX call, only the code in the PHP script directly called by the AJAX ("complist.php" in this case) is executed on the server. None of the PHP code which originally used to create your page is run again - this is why you have to use JavaScript to populate the rest of your newly selected company details.
To update the ID on screen following the AJAX call, all you need to do is follow the pattern you've used to update the rest of the fields
Change your HTML so the element which contains the company ID has an ID which lets JavaScript identify it:
<span id="showcompname"></span><span id="showcompid"><?php echo $_SESSION['company_id'];?></span>
and then in the "success" callback of your AJAX code, write
$("#showcompid").text(jsonObject.company_id);
This is exactly the same concept as the other JavaScript code you've got e.g. to update the "showcompname" element.
Meanwhile, the value stored in your PHP session will be used next time you run the PHP code which updates the whole page (e.g. by refreshing the page).
Re-frased question do to new info
I'm trying to show a limited set of results on a search (i.e. LIMIT 10 in query) then have a button that will load the next 10 (now LIMIT 20 in same query).
The problem is that when I press the button, it not only refreshes the the specified div - but it re-runs the doSearch at the very top of the page - and thereby resetting the LIMIT to 10...
So if I
1. load the result-page
2. comment out the doSearch at top of page
and first then...
3. click the button
It works as perscribed... it now show 20 results... and if I click again it shows 30... etc.
And if I uncomment the doSearch at the very top of page and click the button... it now shows 10 results again...
the code in question in the ajax-code is
var showResult = self.closest('#showResultsAll').find('[id^="showResults"]');
showResult.load(location.href + " #showResults>*", "");
I can't see why my code would re-run the doSearch at the top of page... but hopeully some of you wise folks can see the error of my ways and set me on the right path...
My basic setup:
page with results:
<?php // get search results limit 10 ?>
.
.
.
<div id="showResultsAll">
.
.
.
<div id="showResults">
// Loop through and show results
<div id="moreResultsButton">
<input type="hidden" name="search" id="search" value="<?php // search terms ?>">
<button id="moreResults" value="<?php // number of results found ?>">
jquery.js
$(document).ready(function(){
"use strict";
$(document).on('click','button[id^="moreResults"]', function(){
var self = $(this);
var closestDiv = self.closest('#moreResultsButton');
var search = closestDiv.find('[id^="search"]').val();
var count = self.val();
var countNew = + count + 10;
$.ajax({
type: "POST",
url:'../scripts/moreresults.php',
data:"countNew="+countNew+"&search="+search,
success:function(){
var showResult = self.closest('#showResultsAll').find('[id^="showResults"]');
showResult.load(location.href + " #showResults>*", "");
}
});
});
});
moreresults.php
session_start ();
require ( "../scripts/functions.php" );
// Set variable
$search = $_POST['search'];
$limit = $_POST['countNew'];
doSearch ( $pdo , $search , $limit ); // same function that found the search results in the first place
Update
So found a solution loosely based on an answer given below by #delCano (although I'm still curious as to why my original code insisted on rerunning the doSearch at the top of the page)
Solution:
I split everything up by first dropping the limit in the doSearch and just let it find all results and then did the 'limiting' in the show-results part of the page, and then just added 10 to that in my jQuery
New code:
page with results
<?php // doSearch no limit ?>
.
.
.
<div id="showResultsAll">
.
.
.
<div id="showResults">
// Loop through and show results - limiting like this
// if isset $_POST['show'] (ie. button clicked)
// if $_POST['show'] less than $_SESSION['totalResults'] (ie. more results coming)
// $show = $_POST['show'] (ie. 20, 30, etc.)
// else
// $show = $_SESSION['totalResults'] (ie. 11, 12, ..., 21, 22, ..., 31, 32, ..., etc.)
// else (if button not clicked limit results to max. 10)
// if $_SESSION['totalResults'] more than 10
// $show = 10
// else
// $show = $_SESSION['totalResults'] (ie. 1, 2, 3, etc.)
// loop trough $show number of results
<div class="<?php if $show == $_SESSION['totalResults'] echo "disabled" // Only active if more results are available ?>" id="moreResultsButton">
<button id="moreResults" value="<?php echo $show; ?>">
jQuery.js
$(document).ready(function(){
"use strict";
$(document).on('click','button[id^="moreResults"]', function(){
var self = $(this);
var show = self.val();
var showNew = + show + 10;
$.ajax({
type: "POST",
url:'',
data:"show="+showNew,
success:function(){
self.closest('#showResultsAll').find('[id^="showResults"]').load(location.href + " #showResults>*", "");
}
});
});
});
OK, this is not the best answer, just a development from the comments above. I'll try and write a better answer tomorrow.
However, for the time being, my quick workaround would be:
Remove, as you mention, the doSearch from the top of the page, and set all the initial numbers to 0.
Replace your jQuery with this:
$(document).ready(function(){
"use strict";
$('button#moreResults').click(addResults);
function addResults(){
var self = $(this);
var closestDiv = self.closest('#moreResultsButton');
var search = closestDiv.find('[id^="search"]').val();
var count = self.val();
var countNew = + count + 10;
$.ajax({
type: "POST",
url:'../scripts/moreresults.php',
data:"countNew="+countNew+"&search="+search,
success:function(){
var showResult = self.closest('#showResultsAll').find('[id^="showResults"]');
showResult.load(location.href + " #showResults>*", "");
}
});
}
// load the first ten results
addResults();
});
Please note I did minimal changes to your Javascript. This is not necessarily the most optimal way to do it; I'll revise and edit it tomorrow.
Edit: major refactoring
doSearch is a PHP function that prints the search results to screen. I would change this into a function that returns an array of results. I don't have your code on this, and I don't know how it looks, but it should return something similar to:
array(
array( 'name' => 'One', 'surname' => 'Smith' ),
array( 'name' => 'Two', 'surname' => 'Smythe' ),
....
)
moreresults.php is the PHP that is called to load new results. Since all the rest of the logic will be done in Javascript, this is for now the ONLY PHP code we call. I would include doSearch() in this file now.
session_start ();
require ( "../scripts/functions.php" );
function doSearch( $pdo, $search, $limit) {
/* do logic here */
return $array_of_results;
}
// Set variable
$search = $_POST['search'];
$limit = $_POST['countNew'];
$results = doSearch ( $pdo , $search , $limit );
header('Content-Type: application/json'); // This will tell the client the type of content returned.
echo json_encode($results); // It is a good idea to make all data transmissions between your server-side code (PHP) and your front-end code (Javascript) in JSON. It's also a good idea to never output anything in your PHP code until the very end, where you have all the required data. It makes it easier to debug later on.
Now, the HTML. It doesn't need any PHP preprocessing now, since it will always start the same. We also don't need the tracking of the variables here, since all the logic would be in the Javascript part now.
.
.
.
<div id="showResultsAll">
.
.
.
<ul id="showResults">
</ul>
<button id="loadMore">Load more results</button>
</div>
.
.
.
The Javascript now bears the weight of most of the logic.
$(function() { // Shorthand for "$(document).ready(function()..."
var count = 0;
$("#loadMore").click(loadMoreResults);
function loadMoreResults() {
var url = "../scripts/moreresults.php";
var search = $("#search").val();
count += 10;
var data = {
'countNew': count,
'search': search
};
$.post(url, data, showResults, 'json' );
}
function showResults(data) {
$("#showResults").empty().append(`
<li>${data.name} ${data.surname}</li>
`);
}
});
Notes:
Since I didn't know what kind of data you're working with, I used a list of names and surnames as an example.
Likewise, I presented the results as a unordered list () and list items(); you might prefer a table, or something different.
The code is completely untested. I tried to be careful, but I may have made some typos or other mistakes.
If I were you, I would try to start by learning some jQuery basics before launching myself into Ajax. The FreeCodeCamp has a nice jQuery course.
Code architecture is extremely important, and not often well explained in online courses. As a summary:
Always plan ahead your code. Pick up a pen&paper, or your favourite text editor, and answer yourself the question: "What must the code do?". Then decompose the answer in smaller steps. Then separate each step into smaller steps, and so on.
Whenever you have a piece of code you might need twice, wrap it into a function. Think of functions as small "tasks"
Separate as much as possible the logic from the presentation. You should have part of your code working on the data itself, and part of it working on showing the data, and they should be almost independent from each other. You might want to look at the MVC pattern (Model-View-Controller); it may be in process of replacing, but it is a good starting point. This, by the way, is valid both on the backend (doSearch would be the logic, moreresults the presentation) and the frontend (html is the presentation, javascript the logic).
To finish, the code I gave you is not perfect, but I think is a better start. You'll assuredly find many ways to improve it
I have a problem with updating the data I display from my db. Initially, when the page opens I display the date corresponding to the current date but then the user can change the date by entering it in a text box and when he clicks update all the data displayed should be deleted and the data corresponding to the new date should be displayed. Right now I have a javascript function which deleted all the data in the div when the button is clicked. The div holds the data I want to change. But I don't know how to add new data into the div. I tried to add php code to look up the database for the data in the javascript function but I don't know how to add it to the text box.
function changedate()
{
document.getElementById("label1").innerText=document.getElementById("datepicker").valu e;
document.getElementById("selecteddate").innerText=document.getElementById("datepicker" ).value;
document.getElementById("teammembers").innerHTML = "";//empties the div(teammembers)
<?php
$con=mysqli_connect("localhost","*****","*****","*****");
$result = mysqli_query($con,"SELECT * FROM users");
while($row = mysqli_fetch_array($result))
{
if(trim($user_data['email'])!=trim($row['email']))
{
$email_users = $row['email'];
//I want to first show this email but I don't know how to add it to the div.
}
}
?>
}
You can use a combination of jQuery and AJAX to do this. Much simpler than it sounds. To see that this is the right answer for you, just view this example.
In the below example, there are two .PHP files: test86a.php and test86b.php.
The first file, 86A, has a simple selection (dropdown) box and some jQuery code that watches for that selection box to change. To trigger the jQuery code, you could use the jQuery .blur() function to watch for the user to leave the date field, or you could use the jQueryUI API:
$('#date_start').datepicker({
onSelect: function(dateText, instance) {
// Split date_finish into 3 input fields
var arrSplit = dateText.split("-");
$('#date_start-y').val(arrSplit[0]);
$('#date_start-m').val(arrSplit[1]);
$('#date_start-d').val(arrSplit[2]);
// Populate date_start field (adds 14 days and plunks result in date_finish field)
var nextDayDate = $('#date_start').datepicker('getDate', '+14d');
nextDayDate.setDate(nextDayDate.getDate() + 14);
$('#date_finish').datepicker('setDate', nextDayDate);
splitDateStart($("#date_finish").val());
},
onClose: function() {
//$("#date_finish").datepicker("show");
}
});
At any rate, when the jQuery is triggered, an AJAX request is sent to the second file, 86B. This file automatically looks stuff up from the database, gets the answers, creates some formatted HTML content, and echo's it back to the first file. This is all happening through Javascript, initiated on the browser - just like you want.
These two files are an independent, fully working example. Just replace the MYSQL logins and content with your own fieldnames, etc and watch the magic happen.
TEST86A.PHP
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
//alert('Document is ready');
$('#stSelect').change(function() {
var sel_stud = $(this).val();
//alert('You picked: ' + sel_stud);
$.ajax({
type: "POST",
url: "test86b.php", // "another_php_file.php",
data: 'theOption=' + sel_stud,
success: function(whatigot) {
//alert('Server-side response: ' + whatigot);
$('#LaDIV').html(whatigot);
$('#theButton').click(function() {
alert('You clicked the button');
});
} //END success fn
}); //END $.ajax
}); //END dropdown change event
}); //END document.ready
</script>
</head>
<body>
<select name="students" id="stSelect">
<option value="">Please Select</option>
<option value="John">John Doe</option>
<option value="Mike">Mike Williams</option>
<option value="Chris">Chris Edwards</option>
</select>
<div id="LaDIV"></div>
</body>
</html>
TEST86B.PHP
<?php
//Login to database (usually this is stored in a separate php file and included in each file where required)
$server = 'localhost'; //localhost is the usual name of the server if apache/Linux.
$login = 'abcd1234';
$pword = 'verySecret';
$dbname = 'abcd1234_mydb';
mysql_connect($server,$login,$pword) or die($connect_error); //or die(mysql_error());
mysql_select_db($dbname) or die($connect_error);
//Get value posted in by ajax
$selStudent = $_POST['theOption'];
//die('You sent: ' . $selStudent);
//Run DB query
$query = "SELECT `user_id`, `first_name`, `last_name` FROM `users` WHERE `first_name` = '$selStudent' AND `user_type` = 'staff'";
$result = mysql_query($query) or die('Fn test86.php ERROR: ' . mysql_error());
$num_rows_returned = mysql_num_rows($result);
//die('Query returned ' . $num_rows_returned . ' rows.');
//Prepare response html markup
$r = '
<h1>Found in Database:</h1>
<ul style="list-style-type:disc;">
';
//Parse mysql results and create response string. Response can be an html table, a full page, or just a few characters
if ($num_rows_returned > 0) {
while ($row = mysql_fetch_assoc($result)) {
$r = $r . '<li> ' . $row['first_name'] . ' ' . $row['last_name'] . ' -- UserID [' .$row['user_id']. ']</li>';
}
} else {
$r = '<p>No student by that name on staff</p>';
}
//Add this extra button for fun
$r = $r . '</ul><button id="theButton">Click Me</button>';
//The response echoed below will be inserted into the
echo $r;
Here is a more simple AJAX example and yet another example for you to check out.
In all examples, note how the user supplies the HTML content (whether by typing something or selecting a new date value or choosing a dropdown selection). The user-supplied data is:
1) GRABBED via jQuery: var sel_stud = $('#stSelect').val();
2) then SENT via AJAX to the second script. (The $.ajax({}) stuff)
The second script uses the values it receives to look up the answer, then ECHOES that answer back to the first script: echo $r;
The first script RECEIVES the answer in the AJAX success function, and then (still inside the success function) INJECTS the answer onto the page: $('#LaDIV').html(whatigot);
Please experiment with these simple examples -- the first (simpler) linked example doesn't require a database lookup, so it should run with no changes.
You want to output a literal JS statement with whatever you get back from php, basically:
document.getElementById("teammembers").innerHTML = // notice no erasing, we just
// overwrite it directly with the result
"<?php
$con=mysqli_connect("localhost","*****","*****","*****");
$result = mysqli_query($con,"SELECT * FROM users");
while($row = mysqli_fetch_array($result))
{
if(trim($user_data['email'])!=trim($row['email']))
{
$email_users = $row['email'];
//I want to first show this email but I don't know how to add it to the div.
// so just show it!
echo $email_users; // think about this for a second though
// what are you trying to achieve?
}
}
?>"
This is a vast question, not very specific. Checkout more about AJAX requests - basically from javascript you will have a call to the server that retrieves your data.
This is a snippet from the javascript library jQuery :
$.ajax({
type: "POST",
url: "emails.php",
data: { user: "John" }
}).done(function( msg ) {
$('teammembers').html(msg);
});
hope this will give you a starting point
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 recently came upon a site that has done exactly what I want as far as pagination goes. I have the same basic setup as the site I just found.
I would like to have prev and next links to navigate through my portfolio. Each project would be in a separate file (1.php, 2.php, 3.php, etc.) For example, if I am on the 1.php page and I click "next project" it will take me to 2.php.
The site I am referencing to accomplishes this with javascript. I don't think it's jQuery:
function nextPg(step) {
var str = window.location.href;
if(pNum = str.match(/(\d+)\.php/i)){
pNum = pNum[1] * 1 + step+'';
if ((pNum<1) || (pNum > 20)) { pNum = 1; }
pNum = "".substr(0, 4-pNum.length)+pNum;
window.location = str.replace(/\d+\.php/i, pNum+'.php');
}
}
And then the HTML:
Next Project
I can't really decipher the code above, but I assume the script detects what page you are on and the injects a number into the next page link that is one higher than the current page.
I suppose I could copy this code but it seems like it's not the best solution. Is there a way to do this with php(for people with javascript turned off)? And if not, can this script be converted for use with jQuery?
Also, if it can be done with php, can it be done without dirty URLs?
For example, http://www.example.com/index.php?next=31
I would like to retain link-ability.
I have searched on stackoverflow on this topic. There are many questions about pagination within a page, but none about navigating to another page that I could find.
From your question you know how many pages there are going to be. From this I mean that the content for the pages themselves are hardcoded, and not dynamically loaded from a database.
If this is the approach you're going to take you can take the same course in your javascript: set an array up with the filenames that you will be requesting, and then attach event handlers to your prev/next buttons to cycle through the array. You will also need to keep track of the 'current' page, and check that incrementing/decrementing the current page will not take you out of the bounds of your page array.
My solution below does the loading of the next page via AJAX, and does not change the actual location of the browser. This seems like a better approach to me, but your situation may be different. If so, you can just replace the related AJAX calls with window.location = pages[curPage] statements.
jQuery: (untested)
$(function() {
var pages = [
'1.php',
'2.php',
'3.php'
];
var curPage = 0;
$('.next').bind('click', function() {
curPage++;
if(curPage > pages.length)
curPage = 0;
$.ajax({
url: pages[curPage],
success: function(html) {
$('#pageContentContainer').html(html);
}
});
});
$('.prev').bind('click', function() {
curPage--;
if(curPage < 0)
curPage = (pages.length -1);
$.ajax({
url: pages[curPage],
success: function(html) {
$('#pageContentContainer').html(html);
}
});
});
});
HTML:
<div id = "pageContentContainer">
This is the default content to display upon page load.
</div>
<a class = "prev">Previous</a>
<a class = "next">Next</a>
To migrate this solution to one that does not have the pages themselves hardcoded but instead loaded from an external database, you could simply write a PHP script that outputs a JSON encoded array of the pages, and then call that script via AJAX and parse the JSON to replace the pages array above.
var pages = [];
$.ajax({
url: '/ajax/pages.php',
success: function(json) {
pages = JSON.parse(json);
}
});
You can do this without ever effecting the structure of the URL.
Create a function too control the page flow, with an ajax call
function changePage(page){
$.ajax({
type: 'POST',
url: 'myPaginationFile.php',
data: 'page='+page,
success: function(data){
//work with the returned data.
}
});
}
This function MUST be created as a Global function.
Now we call the function on page load so we always land at the first page initially.
changePage('1');
Then we need to create a Pagination File to handle our requests, and output what we need.
<?php
//include whatever you need here. We'll use MySQL for this example
$page = $_REQUEST['page'];
if($page){
$q = $("SELECT * FROM my_table");
$cur_page = $page; // what page are we on
$per_page = 15; //how many results do we want to show per page?
$results = mysql_query($q) or die("MySQL Error:" .mysql_error()); //query
$num_rows = mysql_num_rows($result); // how many rows are returned
$prev_page = $page-1 // previous page is this page, minus 1 page.
$next_page = $page+1 //next page is this page, plus 1 page.
$page_start = (($per_page * $page)-$per_page); //where does our page index start
if($num_rows<=$per_page){
$num_pages = 1;
//we checked to see if the rows we received were less than 15.
//if true, then we only have 1 page.
}else if(($num_rows % $per_page)==0){
$num_pages = ($num_rows/$per_page);
}else{
$num_pages = ($num_rows/$per_page)+1;
$num_pages = (int)$num_pages;
}
$q. = "order by myColumn ASC LIMIT $page_start, $per_page";
//add our pagination, order by our column, sort it by ascending
$result = mysql_query($q) or die ("MySQL Error: ".mysql_error());
while($row = mysql_fetch_array($result){
echo $row[0].','.$row[1].','.$row[2];
if($prev_page){
echo ' Previous ';
for(i=1;$i<=$num_pages;$i++){
if($1 != $page){
echo "<a href=\"JavaScript:changePage('".$i."');\";> ".$i."</a>";
}else{
echo '<a class="current_page"><b>'.$i.'</a>';
}
}
if($page != $num_pages){
echo "<a class='next_link' href='#' id='next-".$next_page."'> Next </a>';
}
}
}
}
I choose to explicitly define the next and previous functions; so here we go with jQuery!
$(".prev_link").live('click', function(e){
e.preventDefault();//not modifying URL's here.
var page = $(this).attr("id");
var page = page.replace(/prev-/g, '');
changePage(page);
});
$(".next_link").live('click', function(e){
e.preventDefault(); // not modifying URL's here
var page = $(this).attr("id");
var page = page.replace(/next-/g, '');
changePage(page);
});
Then finally, we go back to our changePage function that we built initially and we set a target for our data to go to, preferably a DIV already existing within the DOM.
...
success: function(data){
$("#paginationDiv").html(data);
}
I hope this gives you at least some insight into how I'd perform pagination with ajax and php without modifying the URL bar.
Good luck!