Handling Infinite Scroll Effect Jquery and PHP - php

Why is the url I created getting 404 instead of loading the page data set to each group I want to show on scroll?
I implemented a infinite scroll effect to paginate my data from a table in my mysql database. Now that I am trying to load the page I am getting a 404 error for the url my query is creating.
example.com/inventory-search.php?limit=15&offset=0&_=1455489762864 404 (Not Found)
I am operating under the impression that the url being formed was specifying the amount of pages and my logic should be keeping track on which page set to be shown. Loading more on scroll.
I did use a tutorial online to get this part of the logic done so I am wondering if I am assuming something that is wrong.
My code looks like this,
DB Config
$db_host = "localhost";
$db_user = "username";
$db_pass = "password";
$db_name = "dbName";
try
{
$DB_con = new PDO("mysql:host={$db_host};dbname={$db_name}",$db_user,$db_pass);
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $exception)
{
echo $exception->getMessage();
}
?>
Inventory search script,
<?php
require_once get_stylesheet_directory() . '/wuno-search/Dbconfig.php';
$limit = (intval($_GET['limit']) != 0 ) ? $_GET['limit'] : 15;
$offset = (intval($_GET['offset']) != 0 ) ? $_GET['offset'] : 0;
$sql = "SELECT * FROM wuno_inventory WHERE 1 ORDER BY id ASC LIMIT $limit OFFSET $offset";
try {
$stmt = $DB_con->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
} catch (Exception $ex) {
echo $ex->getMessage();
}
if (count($results) > 0) {
foreach ($results as $res) {
echo '<tr class="invent">';
echo '<td>' . $res['wuno_product'] . '</td>';
echo '<td>' . $res['wuno_alternates'] . '</td>';
echo '<td>' . $res['wuno_description'] . '</td>';
echo '<td>' . $res['wuno_onhand'] . '</td>';
echo '<td>' . $res['wuno_condition'] . '</td>';
echo '</tr>';
}
}
?>
My Jquery
<script type="text/javascript">
jQuery(document).ready(function($) {
var busy = false;
var limit = 15;
var offset = 0;
var assetPath = "<?php echo $assetPath; ?>"
function displayRecords(lim, off) {
jQuery.ajax({
type: "GET",
async: false,
url: assetPath,
data: "limit=" + lim + "&offset=" + off,
cache: false,
beforeSend: function() {
$("#loader_message").html("").hide();
$('#loader_image').show();
},
success: function(html) {
$("#productResults").append(html);
$('#loader_image').hide();
if (html == "") {
$("#loader_message").html('<button data-atr="nodata" class="btn btn-default" type="button">No more records.</button>').show()
} else {
$("#loader_message").html('<button class="btn btn-default" type="button">Loading please wait...</button>').show();
}
window.busy = false;
}
});
}
(function($) {
$(document).ready(function() {
if (busy == false) {
busy = true;
// start to load the first set of data
displayRecords(limit, offset);
}
});
})( jQuery );
(function($) {
$(document).ready(function() {
$(window).scroll(function() {
// make sure u give the container id of the data to be loaded in.
if ($(window).scrollTop() + $(window).height() > $("#productResults").height() && !busy) {
busy = true;
offset = limit + offset;
displayRecords(limit, offset);
}
});
});
})( jQuery );
});
</script>
define $assetPath
$assetPath = get_stylesheet_directory() . '/wuno-search/inventory-search.php';
?>

There are a number of things that could be factors, but what may be the biggest issue is that you are trying to access result properties that you have not SELECTed. For example, you are trying to get $res['wuno_product'] when you have only selected id in your query. You can always do a print_r($results) or var_dump($results), etc. to see what the query is returning.

Related

Creating Dynamic Pages with php and MySQL

I am creating a list of links in main.php using "donemler" table in mySQL database and would like to create a page that shows data from "sikkeler" table (which has a foreing key donemID that is used as a relationship between the two tables) as the user clicks it. (data.php is a part of the index.php which is a infinite scroll page)
Here I tried to call $row["donemID"] with GET method using
$k=$_GET['donemID'] in index.php but did not work.
I have also tried to use SESSIONS method where I add "$_SESSION['donemID']=$row$row["donemID"] to main.php
and called it back in index.php as
$k=$_SESSION['donemID']
but it also did not work.
I would like to learn how to create pages and show relevant data in php.
Thanks in advance!
main.php
<?php
require_once "config.php";
$sql = $conn->query("SELECT * FROM donemler ORDER BY donemID");
if ($sql->num_rows > 0) {
// output data of each row
while($row = $sql->fetch_assoc()) {
echo "<tr><td><a href='index.php?devletID=".$row["devletID"]."&donemID=".$row["donemID"]."'>" .$row["donemler"]. "</a></td></tr>";
}
} else {
echo "0 results";
}
$conn->close();
?>
index.php
<script type="text/javascript">
var start = 0;
var limit = 20;
var reachedMax = false;
var dnmID = $_GET("donemID");
$(window).scroll(function () {
if ($(window).scrollTop() == $(document).height() - $(window).height() )
getData();
});
$(document).ready(function () {
getData();
});
function getData() {
if (reachedMax)
return;
$.ajax({
url: 'data.php',
method: 'POST',
dataType: 'text',
data: {
getData: 1,
start: start,
limit: limit,
dnmID: dnmID,
},
success: function(response) {
if (response == "reachedMax")
reachedMax = true;
else {
start += limit;
$(".results").append(response);
}
}
});
}
</script>
data.php
<?php
if (isset($_POST['getData']) ) {
$conn = new mysqli('localhost', 'usrnm', 'pss', 'db');
$dnmID = $conn->real_escape_string($_POST['dnmID']);
$start = $conn->real_escape_string($_POST['start']);
$limit = $conn->real_escape_string($_POST['limit']);
$sql = $conn->query("SELECT * FROM sikkeler WHERE donemID='$dnmID' ORDER BY kayit_no DESC LIMIT $start, $limit");
if ($sql->num_rows > 0) {
$response = "";
while($data = $sql->fetch_array()) {
$response .= '
<tr>
<td>ICD#'.$data['kayit_no'].'</td>
<td>'.$data['donemi'].'</td>
<td><img src="coin_images/'.$data['resim'].'" border="2" width="200px" /></td>
<td>'.$data['darp'].'</td>
<td>'.$data['tarih'].'</td>
<td>'.$data['birim'].'</td>
<td>'.$data['agirlik'].'</td>
<td>'.$data['cap'].'</td>
<td>'.$data['tip'].'</td>
<td>'.$data['reference'].'</td>
</tr>
';
}
exit($response);
} else
exit('reachedMax');
}
?>
You are checking through two different request methods:
$_POST['getData']
$k=$_GET['donemID']
Since you are using the query strings, it is a GET method to check with.
There is no such variable i.e. getData on main.php

AJAX not separating JSON string

I'm using a star ratings system to display rating data from SQL. Each item that can be rated has unique identifyer variable $id and each rating in ratings tabl has unique identifyer $storyidr. I would like this script to display:
the average rating
the number of times the item has been rated.
The values are retirevable but they display on the page together and I can't see how to seperate them. FOr example, for an item that has an average rating of 4 and has been rated 200 times. when user clicks the data returns via AJAX looking like:
For 'response1' 4"200"
For 'response2' 4"200"
I would like to be able to seperate them to look like:
For 'response1' 4
For 'response2' 200
html page
<div id="products" style="">
<div class="rateit" data-storyidr="<?php echo $id; ?>">
</div>
<div class="averagevote">
<div style="display:block;" id="response<?php echo $id; ?>"><?php echo $avgratep; ?></div><br>
<div style="display:block;" id="response2<?php echo $id; ?>">RaTeD <?php echo $rankcount; ?> TiMeS</div>
</div>
</div>
<?php endwhile; mysqli_close($connection); ?>
<script type ="text/javascript">
$('#currentslide .rateit').bind('rated reset', function (e) {
var ri = $(this);
var value = ri.rateit('value');
var storyidr = ri.data('storyidr');
ri.rateit('readonly', true);
$.ajax({
dataType : 'json',
url: 'rate.php',
data: {storyidr: storyidr, value: value},
type: 'POST',
success: function (data) {
$('#response'+storyidr).replaceWith('Avg rating ' + data.avg + '/5');
$('#response2'+storyidr).replaceWith('Rated ' + data.cnt + ' times');
},
error: function (jxhr, msg, err) {
$('#response').append('<li style="color:red">' + msg + '</li>');
}
});
});
</script>
PHP
<?PHP
$storyidr=$_POST['storyidr'];
$mysqli = mysqli_connect($dbhost,$dbusername,$dbpasswd,$database_name) or die ("Couldn't connect to server.");
if (mysqli_connect_errno($mysqli))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql = "INSERT INTO ratings (storyidr, rank, entry_date) VALUES ('$_POST[storyidr]','$_POST[value]',now());";
$sql .= "SELECT AVG(rank) AS avrank, COUNT(rank) AS countrank FROM ratings WHERE storyidr = $storyidr";
if($mysqli->multi_query($sql))
{ $mysqli->next_result();
if ($result = $mysqli->store_result())
{
$data = mysqli_fetch_assoc($result);
$avrank = $data['avrank'];
$countrank = $data['countrank'];
$avrankr = round($avrank,2);
if(is_null($avrank)){$avrank ="null";}
echo json_encode(array('avg' => $avrankr, 'cnt' => $countrank));
}
}
?>
You should only use json_encode() once and only echo the result of that function. Doing it more than once invalidates your json:
else
{
$results = array();
$results['av'] = $avrankr;
$results['cnt'] = $countrank;
echo json_encode($results);
}
Then, in your javascript, you can access data.av and data.cnt directly:
$('#response'+storyidr).replaceWith('Avg rating ' + data.av +'/5');
$('#response2'+storyidr).replaceWith(data.cnt);
You could also set the dataType parameter in your ajax call as mentioned by #barell, but normally jQuery will figure that out correctly already.
Edit: To avoid the undefined errors you are getting you should do something like:
$results = array('status' => 'fail');
...
if () {
...
if ($result)
{
$results['status'] = 'success';
$results['av'] = $avrankr;
$results['cnt'] = $countrank;
}
}
echo json_encode($results);
Now you can check for data.status first in the success callback of your ajax call and take the appropriate action:
success: function (data) {
if (data.status === 'fail') {
// show a warning message somewhere, this is just an example
alert('No results found!');
} else {
$('#response'+storyidr).replaceWith('Avg rating ' + data.av + '/5');
$('#response2'+storyidr).replaceWith('RaTeD ' + data.cnt + ' TiMeS');
}
},
I think the problem is you don't set the correct header. In the php file, before any output, put this:
header('Content-type: text/json');
And also, instead of write two objects, write it as an array:
echo json_encode(array('avg' => $avrankr, 'cnt' => $countrank));
Now it should work
Then, in your Javascript you will access this data like this:
$('#response'+storyidr).replaceWith('Avg rating ' + data.avg +'/5');
$('#response'+storyidr).replaceWith(data.cnt); // Suppose you want the count here

PHP Infinite scroll pulling random results?

I have a page that returns 16 records from my table.
As the user scrolls to the bottom, I then pull another 12 records from my table and append them to my previous results, my problem is that my results are being duplicated, and not in the correct order.
JS
// Ajax Getentries.php
var url = location.pathname;
if(url.indexOf('missing-people.php') > -1) {
didScroll = false;
$(window).scroll(function () {
didScroll = true;
});
setInterval(function () {
if(didScroll) {
didScroll = false;
if(($(document).height() - $(window).height()) - $(window).scrollTop() < 100) {
var number = $(".directory").children().length;
$.ajax({
type: "POST",
url: "getentries.php",
data: "count=" + number,
success: function (results) {
$('.directory').append(results).fadein();
}
});
}
}
}, 250);
}
PHP
$result = mysql_query("SELECT * FROM directory LIMIT {$_POST['count']},12");
$c = 1;
while($row = mysql_fetch_array($result))
{
echo '<div class="entry';
if (($c % 4) == 1) echo ' alpha ';
echo ' span3"><span class="name">' . $row['First_Name'] . ' ' . $row['Surname'] . "</span>";
echo '<img src="/access/upload/' . $row["picture_1"] . '" alt="' . $row['First_Name'] . ' ' . $row['Surname'] . ', missing since ' . $row['Date_Last_Seen'] . ' " />';
echo '<span class="missing-from">Last seen in ' . ucwords($row["Location_County_Last_Seen"]) . '</span>View Profile</div>';
$c++;
}
mysql_close($con);
it seems like it's a race condition. Indeed, if you quickly scroll the page this is what happens:
the setInterval gets triggered
there are already 12 images in the dom, hence var number = $(".directory").children().length is 12.
now new data is fetched from the server with ajax.
Now, if I'm still at the bottom of the page and the ajax calls hasn't completed yet, the setInterval is going to be triggered again, number still resolve to 12 and I'm going to do the same ajax request. Hence duplication.
Solving the issue could be as simple as setting number at the beginning of the script and incrementing it every time you make an ajax call.
// Ajax Getentries.php
var url = location.pathname;
var number = $(".directory").children().length;
if(url.indexOf('missing-people.php') > -1) {
didScroll = false;
$(window).scroll(function () {
didScroll = true;
});
setInterval(function () {
if(didScroll) {
didScroll = false;
if(($(document).height() - $(window).height()) - $(window).scrollTop() < 100) {
number += 12;
$.ajax({
type: "POST",
url: "getentries.php",
data: "count=" + number,
success: function (results) {
$('.directory').append(results).fadein();
}
});
}
}
}, 250);
}

Div onClick With JSON Call Doesn't Work

I have a search function that calls a php file onkeyup. Now in JQuery i have a onClick function that when you click a div from that same JSON call it alerts something, maybe it will be easier to understand from my code below:
<?php
$Connect = new mysqli("localhost", "root", "", "Data");
$Val = $_POST['Val'];
if($Val)
{
$Search = 'SELECT * FROM Users WHERE ';
$Term = explode(" ", $Val);
foreach($Term as $Key)
{
$I = 0;
$I++;
if($I == 1)
{
$Search .= 'Username LIKE "'.$Key.'%" LIMIT 0, 10 ';
}
else
{
$Search .= 'OR Username LIKE "'.$Key.'%" LIMIT 0, 10 ';
}
}
if($Result = $Connect->query($Search))
{
while($Row = $Result->fetch_assoc())
{
$User = $Row['Username'];
$USearch['S'][] = '<div class="Result"><label class="TText" style="cursor:pointer;">' . $User . '</label></div>';
}
}
}
echo json_encode($USearch);
?>
Now, as you can see, once the user types into a box a div shows up showing all LIKE records of Users, once the div is clicked on nothing happens.
$('.Result').click(function()
{
alert('Hi');
});
When the ajax call return a state of success you can use for example the jquery bind method. (see here for more info http://api.jquery.com/bind/ )
function myAjaxFunct(val){
$.ajax(
{
type: "POST",
url: myPhpFile.php,
datatype: "jsonp",
data: {val: val},
success: function (result) {
$("#jsonResultDisplay").text(result);
$('.Result').bind('click', function() {
alert('hi');
});
}
});
}
You are dynamically creating element that is why it doesn't work.
Use on()method.
Check an example:
http://jsfiddle.net/pZQ8T/

AJAX request causes change function unbind

I want to implement simple functionality to allow users to save their message text as template to be used in the future.
php:
echo '<div id="container">';
$sql = ("SELECT template_id, template_text, template_name, member_id FROM message_templates
WHERE member_id = {$member_id}");
$result = mysql_query($sql) or die(mysql_error());
$num_rows = mysql_num_rows($result);
$confName = get_conference_name($confID);
$confName = formatText_safe($confName);
echo "<label>" . $lang['my_template'] . "</label><select id='tempchoose' name='templates'>";
if ($num_rows == 0) {
echo '<option value=""> ' . $lang['no_saved'] . '</option>';
} else {
for ($i = 0; $i < $num_rows; $i++) {
//$template_id = mysql_result($result, $i, 0);
$temp_text = mysql_result($result, $i, 1);
$temp_name = mysql_result($result, $i, 2);
echo '<option value="' . $temp_text . '">' . $temp_name . '</option>';
}
}
echo "</select></div>";
echo '<input id="send" name="Message" value="send" disabled="disabled" type="submit" />
<input id="temp" name="temp" type="button" value="save as template" />"
<textarea style="width: 99%;" id="textarea" name="TextBox" rows="8" disabled="disabled" type="text" value=""/></textarea>';
javascript:
$("#temp").bind("click", function(){
name=prompt("template name?");
temp_text = $("#textarea").val();
if (name!=null && name!="" && name!="null") {
$.ajax ({
data: {temp_text:temp_text, name:name},
type: 'POST',
url: 'save_template.php',
success: function(response) {
if(response == "1") {
alert("template saved successfully");
} else {
alert(response);
}
}
});
} else {
alert("invalid template name");
}
$.ajax ({
url: 'update_templates.php',
success: function(response) {
$("#container").html(response);
}
});
});
$("select").change(function () {
$("select option:selected").each(function () {
$("#textarea").removeAttr("disabled");
$("#send").removeAttr("disabled");
});
$("#textarea").val($(this).val());
})
.trigger('change');
update_temp.php
$sql = ("SELECT template_id, template_text, template_name, member_id FROM message_templates
WHERE member_id = {$member_id}");
$result = mysql_query($sql) or die(mysql_error());
$num_rows = mysql_num_rows($result);
$confName = get_conference_name($confID);
$confName = formatText_safe($confName);
echo "<label>".$lang['my_template']."</label><select id='tempchoose' name='templates'>";
if ($num_rows == 0) {
echo '<option value=""> '.$lang['no_saved'].'</option>';
} else {
for ($i = 0; $i < $num_rows; $i++) {
//$template_id = mysql_result($result, $i, 0);
$temp_text = mysql_result($result, $i, 1);
$temp_name = mysql_result($result, $i, 2);
echo '<option value="' . $temp_text . '">' . $temp_name . '</option>';
}
}
echo "</select>";
the last ajax request in #temp click function is used to updated the droplist with the newly created template, the problem is that when i click save template; ajax request is performed successfully and droplist is updated, however something wired happen which is that the change function of select is not working anymore! anyone knows where's the problem?
Because ajax will inject new elements to your DOM and those elements don't know about the binding you already defined.
Solution : use jQuery on
Change
$("select").change(function () {
to
$(document).on("change","select", function(){
jQuery on is available from 1.7+ version onwards, if you are using a previous version of jQuery, consider using delegate.
If you are rewriting the select with Ajax you should use .delegate() rather than simply .change, like:
$("someSelector").delegate("select", "change", function() {
// do stuff...
});
where someSelector is an element that contains your select.
Yes, because you have replaced the drop down inside of container, which will unhook all of the events on the drop down. The solution would be to modify the code as below:
$.ajax ({
url: 'update_templates.php',
success: function(response) {
$("#container").html(response);
$("#container select").change(
// your drop down change functionality here //
);
}
});
What this is doing is saying, "After the drop down has been refreshed, also refresh the event."
I hope this helps.

Categories