I am using jQuery to get results, as xml, from a MySQL database. What is the best way to paginate the results?
Right now my script gets the xml and appends each result as a <li> element to a <ul> element.
I'm guessing it will have something to do with creating a global var that gets changed with the next/previous page button that runs a script to remove, then re-append the correct results range, but I'm not really sure.
You shouldn't make pagination dependent on Javascript, it should be done server-side instead. So, for example, the server could return a "next" link that would be something like View next 50 results. The script would take that variable of 50 and return the 50 next results and the link would then be returned as results.php?entry=100. You could integrate this with Ajax so the results would come back without a page refresh, however, but the pagination itself would still be done in the backend.
i would do something like this
var numRows = $table.find('tbody tr').length
var numPages = Math.ceil(numRows / numPerPage)
var $pager = $('</p><br>
<div class="pager"></div>
')
for (var page = 0 page < numPages page++) {
$('<span class="page-number">' + (page + 1) + '</span>')
.appendTo($pager).addClass('clickable')
}
$pager.insertBefore($table)
There are a few plugins, but you're on the right track. When you do the remove/re-append thing, do a $('#mydiv').load('/path/to/myfile.php'). Pass your file the start and stop points, which would serve as the points in your array from which to grab your data.
function paginate(start, limit) {
// Maybe show a preloader?
$('#loader').show();
$("#mydiv").load("/path/to/myfile.php", {start: start, end: limit}, function(){
// hide preloader or do other code here
$('#loader').hide();
});
}
Do you get the entire result set (all the pages) in one go, or do you get one page at a time? In any case you should keep a local cache of the data you received from the server and use that when the user navigates the pages. For example, if you retrieve one page at a time, and the user goes from page 1 to page 2, then you need to retrieve page 2 from the server. But if the user now goes back to page 1, then you should load that from the cache. If the user goes to page 3, then you should fetch that from the server and add it to the cache.
Next I would separate the logic for displaying a single page to the user and fetching a page from the server. When the user clicks on the next page button, you should ask the cache object for the next page, but don't return anything. Instead the cache will call a callback function once it has data. If the data is in the cache, it would call the callback function immediately, passing the result as an argument. The callback function would then update the view presented to the user. If the data is not in the cache, an ajax request is made to the server for that data. Once the data is retrieved, the callback function would be called.
I'm usually against using xml with ajax (I prefer ajaj; Asynchronous JavaScript and JSON. It's also a lot more fun to say out loud). JSON is a better alternative, because it's a lot easier to work with in JavaScript, it takes up less space, both in memory and during transport. Since JSON objects are normal JavaScript objects, adding them to a local cache is as easy as concatenating two arrays (the cache you already have and the new elements retrieved from the server).
Related
Assuming I am loading a web with domain.com/1/?nick=lili
Right now I am including in my html - multiple files, in one of them I do :
$(document).ready(function(){
let path = window.location.href ;
let nick = path.split('=')[1];
getData(nick,loadUI);
});
Using fast servers (Google's Firebase) I still get quite a delay, about 1-2 seconds while at this time the page is loaded with placeholders so no data, and the experience is not good.
I do not want to put a loader UI element, but to load faster.
Is there anywhere else in the code that I can put this to make things faster? (assuming I also need to load Google's server API on the body).
Removing all of this to the head should work better?
The window.location.href will be populated on pageload - there's no need to wait before checking it. Since getData does not need any data from the page in order to start the request, you can move it outside of the $(document).ready(, and even move it up to the top of the document, in the <head>, before any other scripts have run or elements have loaded. This ensures that the request gets sent out as fast as possible.
But
when someone open the page, all html placeholders (texts and photos) are loaded, then I need to fill them with data from DB
Because you need the page to be loaded when the request comes back, you can't just call getData alone, in the rare case that the page hasn't finished loading by then. So, if you change getData to return a Promise that resolves to the desired data, you could use Promise.all to wait for both the data and for the page to be loaded, after which you can populate the page elements:
Promise.all([
getData(nick,loadUI),
new Promise(res => window.addEventListener('DOMContentLoaded', res))
])
.then(([data]) => {
// Populate page with data from request
});
I'm trying to make a search page for a mysql database. I'm trying to get a Next and Previous button to cycle though the search results one result at a time. I understand that ajax is the best way to do this.
I know very little about ajax. I'm just now getting a hang of PHP.
I've searched on here but can't find exactly what I want to do. I have also read though W3's ajax section and it has not helped with this issue.
I have it so that a user searches for items (creates a mysql query) and the search results only outputs one result at a time. How can I get it so the next result will be displayed on the press of the Next button. Likewise for the Prev button.
I've tried getting if and while statements to work but it seems to keep coming back to a client to server problem.
I was thinking of using a PHP variable to represent each search result and have the button increase/decrease the variable number and tell the page to re-display the information with the new variable.
Any help would be great. I've been stuck on this for more than a week.
Code examples would be even more helpful.
I would do it by doing:
one search request -ajax- to the server and the server responses with an array in JSON format of the results that you are going to navigate throw them by a next and previous buttons, by doing one search request you are going to avoid many requests to server for every next and previous click, and also avoid the server from keeping track of the current result.
The client side - Javascript and JQuery
<script>
var results; // the results array that will have all your search results
var currentresult = 0; // the index of the current result
//the search ajax function
function buttonSearchPressed(){
$.ajax({type:"POST",url:"test.php",
data:{keyword:$('input#searchkeyword')[0].value}
success:function(data){
try{results = JSON.parse(data)}catch(e){alert('error');}
}
});
}
function previous(){
if(currentresult>0){
currentresult--;
$('span#result')[0].innerHTML =results[currentresult];
}
}
function next(){
if(currentresult<results.length-1){
currentresult++;
$('span#result')[0].innerHTML =results[currentresult];
}
}
</script>
The client side - HTML
<input id="searchkeyword">
<button onclick="buttonSearchPressed()">search</button><br>
<button onclick="previous()">previous</button>
<span id='result'></span>
<button onclick="next()">next</button>
The server side - PHP test.php
if($_SERVER['REQUEST_METHOD'] == "POST"){
//search ajax handler goes here
$keyword= $_POST['keyword'];//the search keyword
//apply the search you want here, (for example database query)
$searchResult = ["result1","result2","result3","result4","result5"];
$searchResult = json_encode($searchResult );
die($searchResult );
}
Well i wanna create an Ajax Drag and Drop Shopping cart using only javascript and ajax. Currently i'm using the example in this page as a stepping stone. Right now it's only with local jquery and it works fine but i want to make the cart work with ajax calls. Note that i do not want to use a server side language( like php, rubby, asp etc), only html and javascript.
My initial thought was that at the $(".basket").droppable i should add an ajax call to another html page containing the "server logic" in javascript, execute in that file all the necessary steps( like reading the get variables (product name, product id and quantity), set a cookie and then return an ok response back. When the server got the "ok" response it should "reload" the cart div with the updated info stored inside the cookie.
If this was with php i would know how to do it. The problem is that as far as i know, you can execute javascript once it reaches the DOM, but how can you execute that js from inside the page that isbeing called upon ? ( thanks to Amadan for the correction)
I've thought about loading the script using $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ).. but the problem with that is that the url GET variables i want to pass to the "server script" do not exist in that page.
I havent implemented all the functionality yet as i am stuck in how to first achieve javascript execution inside an ajax target page.
Below is a very basic form of my logic so far
// read GET variables
var product = getQueryVariable("product");
var id = getQueryVariable("id");
var quantity= getQueryVariable("quantity");
//To DO
//--- here eill go all the logic regarding cookie handling
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
alert('Query Variable ' + variable + ' not found');
}
Any help regarding this matter will be appreciated.
Note: Logic in simple words:
1)have an html page with products+cart
2)Have an "addtocart.html" with the "Cart Server Logic"( being the target of the ajax call when an item is dropped into the product.)
If you have some other idea on this, please enlighten me :)
thanks in advance
Foot Note-1:
if i try loading the scipt using
$("#response").load("ajax/addtocart.html?"+ $.param({
product: product,
id: id,
quantity:quantity
})
);
i get the alert about not being able to find the url parameters( something that i thing is normal as because the content is being loaded into the initial page, from which the request is started, there are no get parameters in the url in the first place)
The problem is that as far as i know, you cannot execute javascript contained in the target of an ajax call, as that page never reaches the browser interpreter.
This is either incorrect or misleading. The browser will execute any JavaScript that enters DOM. Thus, you can use $.load to load content and execute code at the same time. Alternately, you can use hacked JSONP to both execute code and also provide content as a JSON document.
EDIT: Yes, you can't get to the AJAX parameters from JavaScript. Why do you want to? Do you have a good reason for it, or is it an XY problem?
The way I'd do it is this:
$('#response').load(url, data, function() {
onAddedToCart(product, id, quantity);
});
and wrap your JS code in your HTML into the onAddedToCart function.
Depending on what exactly you're doing, it could be simplified even further, but this should be enough to cover your use case.
I am using ajax from JQuery. I am doing in a page that I see the results of a POST/GET having provided specific parameters as filters to the server.
Assume I have provided parameters a&b&c to the user so that I see in the page the subset of the data that these parameters hold true.
In a specific case I do an ajax call to pass a value to the server that modifies this set that I am seeing.
What I need is a way to do a refresh of the page but that will only display the new version of the current subset of data I.e. somehow refreshing passing back to the server a&b&c
Right now I am doing: window.location.reload(true); which reloads all the data and it is time-consuming to re-apply the filters manually.
How can I solve this?
Essentially what I need is not full refresh?
If you are using Ajax from jQuery and want to do a partial reload but have chosen window.location.reload, then you are doing it wrong.
Use the format
$("#someDiv").load("someUrl?a=x&b=y")
or
$.get("someUrl?a=x&b=y",function(data) { $("#someDiv").html(data)});
for example this code in the head where .parameters could be checkboxes
$(function() {
$(".parameters").on("click",function() {
var url = "someUrl.php?"+$("#myForm").serialize();
$.get(url,function(data) {
$("#someContainer").html(data);
});
});
});
You would have to return something from the server which will contain th einformation needed to update
And then update the content based on the returned data.
I am making a forum and I want it to run like a desktop application, so I do not refresh the page. For lack of a better method without another complete Ajax request I receive the number of pages of data available in an Ajax request. I need to display this data (as I have at ethoma.com/testhome.php -- I set the page size to 1 for testing) but I also need to add event handlers to each individual number displayed to trigger an event that will change the color of the text and trigger an Ajax call to get the page number specified. The challenge for me is that there could be 500 pages (of course then I wouldn't be able to display every page number). For those who don't want to view the code via my site, here is the important parts of it:
function getPosts()
{
var queryString = "category=" + category + "&page=" + page + "&order=" + order;
$.ajax(
{
url: 'getposts.php',
data: queryString,
success: function(data)
{
var oldHtmlTemp;
var dataArray = data.split("%^&$;");
numpage = dataArray[0];
$('#postcontainer').html(dataArray[1]);
$('#enterpage').html('');
if (numpage != 0)
{
for(var i=1;i<=numpage;i++)
{
oldHtmlTemp = $('#enterpage').html();
$('#enterpage').html(oldHtmlTemp + " " + i);
}
oldHtmlTemp = $('#enterpage').html();
$('#enterpage').html(oldHtmlTemp + " ");
}
else
{
$('#enterpage').html('No results for this query');
}
}
});
}
If you are wondering what the .split() is doing, the php doc returns the number of pages seperated by that weird string that I designated. I decided it would be the easiest way to put the number of pages within the rest of the post text.
Anyway how would I add event handlers to these individual numbers?
I have a quick follow-up question, this code isn't working for some weird reason. It adds an event handler to the next page and previous page buttons, but also error checks to make sure you aren't trying to hit page -1.
$("#nextpage").click(function()
{
if (page < numpage -1)
{
page++;
getPosts();
alert(page);
}
});
$("#prevpage").click(function()
{
if (page >= 1);
{
page--;
getPosts();
alert(page);
}
});
Alerts are for debugging. Also worth noting is that when page = 0, you get page 1. What I mean is, I am counting from 0 1 2, but the user sees 1 2 3.
Thanks to anyone who views/answers this post.
I will refer to the last question first.
I didn't understand the followup question as you didn't specify what exactly is not working.
I am guessing you are overriding your "next","prev" while dynamically loading new HTML.
To resolve this, take a look in the "live" jquery method.
What it does is exactly like assigning "click" (like you did) but it re-evaluates the selector on each event. So the new elements will still be included.
I believe the "live" method will work on the first question as well.
Simply wrap each number with some "span" identified by a unique "class". and add something like this :
$(".pagination-number").live("click",function(){
$(".pagination-number").attr("color:black"); // remove previous click color
$(this).attr("color:red"); // mark currently clicked number
.... // load the content
})
When I write an HTML that loads dynamically, I always assign the Javascript to that HTML.
This way - I reevaluate the JS when the new HTML is loaded.
For example - my returned html looks something like
<div class="highlight"> some content here </div>
<script> $(".highlight").effect("highlight",{},300)</script>
The benefit it gives me is that I assign the behavior to the data. (just like in OOP).
I don't need to rewrite the behavior for each time I load the HTML. (in this example to highlight the text).
It will be highlighted each time I load the HTML because the script is evaluated.
You should consider using this design pattern as it will :
Concentrate all your code into a single place
This design pattern overcomes scenarios in which you override a dom object. ( for example, the old HTML has a #prev button, and the new html also has a #prev button. The code will always refer to the most recent dom element hence the behavior will be consistent.