I'd like to load items from an XML file and display them on a webpage via AJAX and limit the output via a date range. However I am struggling to pass the parameters to the anonymous function. All tries to hand over the parameter 'displayDateLimit' have ended in syntax errors. Any idea how to do this?
In addition to that: If do not pass the the parameter I get an incremented counter for inpTest instead. Why does this happen?
// loads XML to Div-Element.
function loadItemsToBox(id)
{
var boxElement = document.getElementById('someid');
if (!boxElement){ return;}
xmlUrl = 'someurl'];
displayDateLimit = new Date().getTime();
displayDateLimit -= 3600*1000;
$.ajax({
type: "GET",
url: xmlUrl,
dataType: "xml",
success: function (xml) {
var content = "";
$(xml).find("item").each(function (inpTest) { // or "item" or whatever suits your feed
var el = $(this);
content += "<p>";
content += el.find("title").text() + "<br>";
content += "<br>DateLimit: " + inpTest;
content += "</p>";
})(displayDateLimit);
boxElement.innerHTML = content;
},
error : function(xhr, textStatus, errorThrown )
{
// some errorhandling
}
});
}
Related
PHP/HTML:
<ul id="load-more-div"></ul>
<a id="load-more" data-ppp="<?php echo get_option('posts_per_page'); ?>">load more</a>
JavaScripts:
(function($) {
// Grab the load more button, since I only want to run the code if the button is on the page
var loadMoreButton = $("#load-more");
if (loadMoreButton) {
// Get the posts_per_page number set in Reading Options
var ppp = loadMoreButton.data("ppp");
// Initialize function
var loadPosts = function(page) {
var theData, loadMoreContainer, errorStatus, errorMessage;
// The AJAX request
$.ajax({
url: "/wp-json/wp/v2/posts",
dataType: "json",
data: {
// Match the query that was already run on the page
per_page: ppp,
page: page,
type: "post",
orderby: "date"
},
success: function(data) {
// Remove the button if the response returns no items
if (data.length < 1) {
loadMoreButton.remove();
}
// Create a place to store exactly what I need
// Alternatively, the response can be filtered to only return the needed data, which is probably more efficient as the following loop wont be needed
theData = [];
// Get only what I need, and store it
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
// Grab the container where my data will be inserted
loadMoreContainer = $("#load-more-div");
// For each object in my newly formed array, build a new element to store that data, and insert it into the DOM
$.each(theData, function(i) {
loadMoreContainer.append(
'<li><a href="' +
theData[i].link +
'">' +
theData[i].title +
"</a></li>"
);
});
},
error: function(jqXHR, textStatus, errorThrown) {
errorStatus = jqXHR.status + " " + jqXHR.statusText + "\n";
errorMessage = jqXHR.responseJSON.message;
// Show me what the error was
console.log(errorStatus + errorMessage);
}
});
};
// Since our AJAX query is the same as the original query on the page (page 1), start with page 2
var getPage = 2;
// Actually implement the functionality when the button is clicked
loadMoreButton.on("click", function() {
loadPosts(getPage);
// Increment the page, so on the next click we get the next page of results
getPage++;
});
}
})(jQuery);
This is the trouble part, it doesn't remove the link.
// Remove the button if the response returns no items
if (data.length < 1) {
loadMoreButton.remove();
}
Console errors when click the load more link after reaching the end of posts:
400 Bad Request The page number requested is larger than the number of pages available.
I found two ways to solve it:
###Using data attribute
Get the max number of pages in the template, assign it to a data attribute, and access it in the scripts. Then check current page against total page numbers, and set disabled states to the load more button when it reaches the last page.
PHP/HTML:
<ul id="ajax-content"></ul>
<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>" data-pages="<?php echo $wp_query->max_num_pages; ?>">Show more</button>
JavaScripts:
(function($) {
var loadMoreButton = $('#ajax-button');
var loadMoreContainer = $('#ajax-content');
if (loadMoreButton) {
var endpoint = loadMoreButton.data('endpoint');
var ppp = loadMoreButton.data('ppp');
var pages = loadMoreButton.data('pages');
var loadPosts = function(page) {
var theData, errorStatus, errorMessage;
$.ajax({
url: endpoint,
dataType: 'json',
data: {
per_page: ppp,
page: page,
type: 'post',
orderby: 'date'
},
beforeSend: function() {
loadMoreButton.attr('disabled', true);
},
success: function(data) {
theData = [];
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
$.each(theData, function(i) {
loadMoreContainer.append('<li>' + theData[i].title + '</li>');
});
loadMoreButton.attr('disabled', false);
if (getPage == pages) {
loadMoreButton.attr('disabled', true);
}
getPage++;
},
error: function(jqXHR) {
errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
errorMessage = jqXHR.responseJSON.message;
console.log(errorStatus + errorMessage);
}
});
};
var getPage = 2;
loadMoreButton.on('click', function() {
loadPosts(getPage);
});
}
})(jQuery);
###Using jQuery complete event
Get the total pages x-wp-totalpages from the HTTP response headers. Then change the button states when reaches last page.
PHP/HTML:
<ul id="ajax-content"></ul>
<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>">Show more</button>
JavaScripts:
(function($) {
var loadMoreButton = $('#ajax-button');
var loadMoreContainer = $('#ajax-content');
if (loadMoreButton) {
var endpoint = loadMoreButton.data('endpoint');
var ppp = loadMoreButton.data('ppp');
var pager = 0;
var loadPosts = function(page) {
var theData, errorStatus, errorMessage;
$.ajax({
url: endpoint,
dataType: 'json',
data: {
per_page: ppp,
page: page,
type: 'post',
orderby: 'date'
},
beforeSend: function() {
loadMoreButton.attr('disabled', true);
},
success: function(data) {
theData = [];
for (i = 0; i < data.length; i++) {
theData[i] = {};
theData[i].id = data[i].id;
theData[i].link = data[i].link;
theData[i].title = data[i].title.rendered;
theData[i].content = data[i].content.rendered;
}
$.each(theData, function(i) {
loadMoreContainer.append('<li>' + theData[i].title + '</li>');
});
loadMoreButton.attr('disabled', false);
},
error: function(jqXHR) {
errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
errorMessage = jqXHR.responseJSON.message;
console.log(errorStatus + errorMessage);
},
complete: function(jqXHR) {
if (pager == 0) {
pager = jqXHR.getResponseHeader('x-wp-totalpages');
}
pager--;
if (pager == 1) {
loadMoreButton.attr('disabled', true);
}
}
});
};
var getPage = 2;
loadMoreButton.on('click', function() {
loadPosts(getPage);
getPage++;
});
}
})(jQuery);
The problem appears to be an invalid query to that endpoint so the success: function() is never being run in this circumstance.
Add to All API Errors
You could add the same functionality for all errors like this...
error: function(jqXHR, textStatus, errorThrown) {
loadMoreButton.remove();
....
}
Though that may not be the desired way of handling of all errors.
Test for Existing Error Message
Another option could be to remove the button if you receive an error with that exact message...
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.statusText === 'The page number requested is larger than the number of pages available.') {
loadMoreButton.remove();
}
....
}
but this would be susceptible to breaking with any changes to that error message.
Return Custom Error Code from API
The recommended way to handle it would be to return specific error code (along with HTTP status code 400) to specify the exact situation in a more reliable format...
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.statusCode === '215') {
loadMoreButton.remove();
}
....
}
Here's an example on how to configure error handling in an API: Best Practices for API Error Handling
Return 200 HTTP Status Code
The last option would be to change the way your API endpoint handles this type of "error"/situation, by returning a 200 level HTTP status code instead, which would invoke the success: instead of the error: callback instead.
Below is an AJAX function I'm trying to use to show a loader gif during the request and hide when successful. Basically I started out with the function inside of the response.success which used to work by itself. It creates short urls and sets it to the value of an input field. And I was shown the rest that wraps that function, but i'm getting a 404 error in the console for failure to load resource. I'm sure this is a straightforward answer, I'm too new to tell but I think I'm close. Any help is much appreciated, thanks.
function getShare(url)
{
$('#loader').show(); // show loading...
$.ajax({
dataType: "jsonp",
jsonpCallback:'apiCallback', // this will be send to api as ?callback=apiCallback because this api do not want to work with default $ callback function name
url: 'http://b1t.co/Site/api/External/MakeUrlWithGet',
data: {'url':url},
success: function(response){
$('#loader').hide(); // hide loading...
//respponse = {success: true, url: "http://sdfsdfs", shortUrl: "http://b1t.co/qz"}
if(response.success){
{
var s = document.createElement('script');
var browserUrl = document.location.href;
//alert(browserUrl);
if (browserUrl.indexOf("?") != -1){
browserUrl = browserUrl.split("?");
browserUrl = browserUrl[0];
}
//alert(browserUrl);
var gifUrl = $('#gif_input').value;
var vidUrl = $('#vid_input').value;
//alert(gifUrl + "|" + vidUrl);
url = encodeURIComponent(browserUrl + "?gifVid=" + gifUrl + "|" + vidUrl);
//alert(encodeURIComponent("&"));
s.id = 'dynScript';
s.type='text/javascript';
s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
document.getElementsByTagName('head')[0].appendChild(s);
}
function resultsCallBack(data)
{
var obj = jQuery.parseJSON(JSON.stringify(data));
$("#input-url").val(obj.shortUrl);
}
}
},
error:function(){
$('#loader').hide();
}
});
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
Am getting data from ajax call and appending the data to table. Am getting title and url from the data. Now when i click on the url data of table , i need to call a outer javascript function with the clicked url data.
<script>
jquery(document).ready(function(){
jquery(#button).click(function{
showData();
});
});
function showData(){
var total = "";
var final = "";
jquery.ajax({
url : "AJAX_POST_URL",
type: "POST",
data : input,
dataType: "json",
success: function(jsondata)
{
//data - response from server
var document= jsondata.data.results; //am getting array of objects
for(int i=0; i<document.length; i++){
var tr = "<tr>";
var td = "<td>" + "Title : " +
document[i].title + "Url :" + "<a href=''>" + document[i].url + </a> + "</td></tr>";
final = tr + td;
total= total + final ;
}
$("#docTable").append(total) ;
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("error");
}
});
}
</script>
<script>
function download(){
//inside this function i need to get the value of document[i].url
}
</script>
You really should structure your program quite a bit better, and it would be easier if you could put your complete example up on jsfiddle.net.
But a quick solution in your current code may be to make "document" a global variable. Beware that document already is a global variable in the BOM (Browser Object Model), so use something else like say "docs".
<script>
// Global variable
var docs;
jquery(document).ready(function(){
jquery(#button).click(function{
showData();
});
});
function showData(){
var total = "";
var final = "";
jquery.ajax({
url : "AJAX_POST_URL",
type: "POST",
data : input,
dataType: "json",
success: function(jsondata)
{
//data - response from server
docs = jsondata.data.results; //am getting array of objects
for(int i=0; i<document.length; i++) {
var tr = "<tr>";
var td = "<td>" + "Title : " +
docs[i].title + "Url :" + "<a href=''>" + docs[i].url + </a> + "</td></tr>";
final = tr + td;
total = total + final;
}
$("#docTable").append(total) ;
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("error");
}
});
}
</script>
<script>
function download(){
//inside this function i need to get the value of document[i].url
// You have access to docs through the global variable
for(var i=0;i < docs.length;i++) {
console.log(docs[i].url)
}
}
</script>
I have a javascript function which executes on the change of a dropdown:
<script type="text/javascript">
$(function()
{
// Executes when the status dropdown changes value
$('select[name="status_dropdown"]').change(function(event)
{
var $this = $(event.target);
var orderId = $this.closest('tr').children('td:eq(0)').text(); // index 0 refers to the "order_id column" in the table
var result = null;
var scriptUrl = "ajax_php/update_status.php?order_id=" + orderId + "&status_id=" + this.value;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'html',
async: false,
success: function(data)
{
result = data;
alert(result);
}
});
});
})
</script>
I am trying to get the alert call to show the return value of the following php code (which is true):
<?php
.
.
.
return true;
?>
The alert doesn't pop up. Anyone know why ???
I tried your code with another URL and it's working well.
There are three cases:
scriptUrl is not calculated properly and doesn't point to your PHP script
your server is down
you are accessing an URL not served under the same domain as the one of your script (same-origin policy)
You can see detail of your error if you add an error handler to ajax parameters :
error : function(jqXHR, textStatus, errorThrown) {
alert(errorThrown);
}
Return only returns a value within the php script - to output it to ajax you need to actually output the result to the page, in this case something like echo "true"; or print("true");
Try this
$(document).ready(function(){
$('select[name="status_dropdown"]').change(function(event)
{
var $this = $(event.target);
var orderId = $this.closest('tr').children('td:eq(0)').text(); // index 0 refers to the "order_id column" in the table
var result = null;
var scriptUrl = "ajax_php/update_status.php?order_id=" + orderId + "&status_id=" + this.value;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'html',
async: false,
success: function(data)
{
result = data;
alert(result);
}
});
});
});
I have a function which updates a database via ajax. My issue is then how to update the data displayed on the page to show updated details. The POST data can vary and therefore the datastring would be something like this:
var dataString = '[name resource we are editing]=1' +
'¶1='+ para1 +
'¶2=' + para2+
'¶3=' + para3
I want the function below to split or loop through each of the POST variables in the datastring to update the text of an element on the page. I cannot figure out how.
function editAccount(dataString, details, form){
status = $(".status");
$.ajax({
type: "POST",
url: "<?php echo BASE_PATH; ?>/edit/",
data: dataString,
success: function(response) {
$.each(response, function(key, value) {
success_code = key;
message = value;
});
if(success_code == 1){
status.text(message).addClass("valid");
//show details and hide form
$("#" + details).show();
$("#" + form).hide();
//HOW to do below?
//update details being displayed with datasource data
//loop through dataString to assign eg. $('#para1')text(para1);
} else {
status.text(message).addClass("invalid");
}
},
error: function(response){
status.text("There was a problem updating your details into our database. Please contact us to report this error.").addClass("invalid");
}
});
}
As mentioned in a previous comment, I would suggest declaring the dataString variable as an object:
var dataString = { '[name resource we are editing]' : 1,
'para1': para1,
'para2': para2,
'para3': para3
}
Now it'll be much easier to loop over the params, just using the function each, for instance, which you already use in your code:
$.each(dataString, function(key, value) {
// Do stuff with each param
});
EDIT:
As #Qpirate suggests, you also can use the javascript for loop:
for(var key in dataString){
// value => dataString[key]
}