I am playing around with Game of thrones Api - https://anapioficeandfire.com/Documentation.
The documentation mentions they are implementing rate limiting. Hence implementing cache is important.
Let's say I want to print all the names of the houses from the Api on a button click
function getAllHouseNames() {
for (let i = 1; i <= 45; i++) {
getHouseNames(i)
}
}
async function getHouseNames(page) {
var req = new XMLHttpRequest();
req.onreadystatechange = await
function() {
if (this.readyState == 4 && this.status == 200) {
//console.log(req.getResponseHeader("link"));
let houseObj = JSON.parse(this.responseText);
for (let i = 0; i < houseObj.length; i++) {
let p = document.createElement("p");
let name = document.createTextNode(houseObj[i].name);
p.appendChild(name);
document.body.appendChild(p);
}
}
};
req.open("GET", "https://www.anapioficeandfire.com/api/houses?page=" + page + "&pageSize=10", true);
req.send();
};
Around 45 requests are fired (Since there are 45 pages with information about houses).
How do i implement caching technique in this scenario?
Create a global/module level variable. In the code below, I called it cache. then add the properties to it when you have retrieved them. then they are available for later use.
<!doctype html>
<head>
<title>A Song of Ice and Fire</title>
<!-- include jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var cache = {}; // create a new object for the cache
$(document).ready(function() {
// once the page is loaded, register a click listener on the button
$("#btn-get-house-names").on("click", getAllHouseNames);
});
function getAllHouseNames() {
// if the cache object doesn't have
// a property called "houseNames", go ajax
// otherwise just display the house names in the document
if (!cache.houseNames) {
$("#div-house-names").html("Getting House Names");
getHouseNamesAjax()
} else {
$("#div-house-names").html("");
$.each(cache.houseNames, function(index, houseName) {
$("#div-house-names").append("<p>" + houseName + "</p>");
});
}
}
function getHouseNamesAjax(page) { // use jQuery to ajax
let pageId = "";
let pageSize = "pageSize=10";
if (page) {
pageId = "?page=" + page + "&" + pageSize;
} else {
pageId = "?" + pageSize;
}
$.ajax({
type: "GET",
url: "https://www.anapioficeandfire.com/api/houses" + pageId,
dataType: "json",
success: function(data, textStatus, request) {
if (!cache.houseNames) { // add the houseNames array to the cache object
cache.houseNames = [];
}
$.each(data, function(index, house) {
cache.houseNames.push(house.name); // append to the end of the array
});
if (request.getResponseHeader("link")) { // this looks to see if there is another page of house names
let headerLinks = request.getResponseHeader("link").split(",");
let hasNext = false;
$.each(headerLinks, function(index, headerLink) {
let roughLink = headerLink.split("; ")[0];
let roughRel = headerLink.split("; ")[1];
let rel = roughRel.substring(5, roughRel.length - 1);
if (rel == "next") {
let pageNum = roughLink.split("?page=")[1].split("&page")[0];
getHouseNamesAjax(pageNum);
hasNext = true;
return false; // break out of $.each()
}
});
if (!hasNext) {
// if no more pages of houseNames,
// display the house names on the page.
// We have to do this here, because ajax is async
// so the first call didn't display anything.
getAllHouseNames();
}
}
},
error: function(data, textStatus, request) {
alert(textStatus);
}
});
};
</script>
</head>
<body>
<input type="button" id="btn-get-house-names" value="Get House Names"/>
<div id="div-house-names"> <!-- house names -->
</div>
</body>
</html>
Related
I have Javascript function returning an object with an HTMLHtmlElement object I'd like to parse:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://someothersite.com/widgets/whatson.js"></script>
<script src="https://someothersite.com/widgets/jquery-deparam.js"></script>
<script>
var configuration = {
schedule: 'now'
};
if ( window.location.search ) configuration = $.extend({}, configuration, $.deparam( (window.location.search).replace('?','') ));
$(function(){
var content = $('div#output').whatsOn( configuration );
console.log( $("div#output").html() );
});
</script>
The above whatsOn function fills my output div with the HTML content returned, but the console log outputs nothing. If I write content to the console, it is an init object with data I'd like to parse. If I add the following, it sends an [object HTMLHtmlElement] to the console with all the data to the console:
var html = content.context.childNodes[1];
console.log( html );
How can I parse that the HTML? What I am after is the innerText element of the html variable above. However, if I change to content.context.childNodes[1].innerText, I get nothing.
UPDATED
Here is the code pasted:
/**
* Source for the Daily and Weekly Widgets
* Both of these widgets are rendered via the custom whatsOn Jquery plugin which is implemented via this script
*/
;
(function ($, window, document, undefined) {
/*
=== Begin async caching functions ===
Asynchronous Caching Code
The below code seems to be a direct copy of the code from https://learn.jquery.com/code-organization/deferreds/examples/
This code ensures that multiple requests are not made for loading the same data/resource.
Generic cache factory (below)
One promise is cached per URL.
If there is no promise for the given URL yet, then a deferred is created and the request is issued.
If it already exists, however, the callback is attached to the existing deferred.
*/
$.cacheFactory = function (request) {
var cache = {};
return function (key, callback) {
if (!cache[ key ]) {
cache[ key ] = $.Deferred(function (defer) {
request(defer, key);
}).promise();
}
return cache[ key ].done(callback);
};
};
// Every call to $.cacheFactory will create a cache respository and return a cache retrieval function
$.template = $.cacheFactory(function (defer, url) {
$.ajax({
url: url,
data: $.template.params,
dataType: 'jsonp',
success: defer.resolve,
error: defer.reject,
complete: defer.always
});
});
// === End async caching functions
// This function handles rendering template markup and data
$.renderTemplate = function (data, elem, options) {
var label = ( !options.label ) ? elem.addClass('whatson-hidden') : '';
return elem.empty().append(data) && label;
};
// Handles error message display
$.errorMessage = function (elem) {
return elem.append('error');
};
/*
=== Begin .whatsOn plugin functions ===
The following functions create a jquery plugin which can be executed on a JQuery element to render the whatson widget
The .whatsOn() functions are added to $.fn in order to create this plugin
- see https://learn.jquery.com/plugins/basic-plugin-creation/
*/
$.fn.whatsOn = function (options) {
// Do not initialize the widget if it has already been initialized, or if the station param is missing
if (this.data('whatson-init') || !options.station) {
return;
}
this.data('whatson-init', true); // widget-initialized flag
options = $.extend({}, $.fn.whatsOn.options, options);
// Force fix the old widget calls that do not use iframes.
if (options.env == 'http://composer.nprstations.org') options.env = 'https://api.composer.nprstations.org/v1';
$.fn.whatsOn.env = options.env;// Determines which API request URL to use
// Add CSS stylesheet
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('type', 'text/css');
css.setAttribute('href', options.assets + '/widgets/css/v2.css');
document.getElementsByTagName('head')[0].appendChild(css);
/*
Return the plugin object
When you filter elements with a selector ($('.myclass')), it can match more than only one element.
With each, you iterate over all matched elements and your code is applied to all of them.
*/
return this.each( function () {// BEGIN Return the plugin.
var elem = options.elem = $(this);
var ucs = options.station;
var schedule = options.schedule;
var times = options.times;
var next = options.next;
var show_song = options.show_song || null;
var display_style = options.style || null;
var request_url;
// The buy links
var hide_itunes = options.hide_itunes || null;
var hide_amazon = options.hide_amazon || null;
var hide_arkiv = options.hide_arkiv || null;
if (!options.affiliates) options.affiliates = {};
if (options.itunes) options.affiliates.itunes = options.itunes;
if (options.amazon) options.affiliates.amazon = options.amazon;
if (options.arkiv) options.affiliates.arkiv = options.arkiv;
elem.addClass('whatson-wrap');// Add widget class
$("body").attr('id', 'nprds_widget'); // Add an ID to the body of the document
// Ensure that the moment() JS plugin is available, if not, then add and load it (http://momentjs.com/docs/)
if (!window.moment) {
$.getScript('https://composer.nprstations.org/widgets/js/moment.isocalendar.js').done(function (script) {
builder();// Build plugin function (see below)
});
} else {
builder();// Build plugin function (see below)
}
// This function builds the plugin, it does all of the setup required
function builder() {// BEGIN build plugin function
// Set the date/range for the widget header. If its the daily widget use a date, for the weekly widget use a range
var req_date = ( options.schedule === 'week' )
? moment().isoday(1).format('YYYY-MM-DD') + ',' + moment().isoday(7).format('YYYY-MM-DD')
: moment().format('YYYY-MM-DD');
request_url = $.fn.whatsOn.env + '/widget/' + ucs + '/' + schedule;
$.template.params = {
format: 'jsonp',
date: req_date,
times: times,
show_song: show_song || null,
style: display_style || null,
hide_itunes: hide_itunes || null,
hide_amazon: hide_amazon || null,
hide_arkiv: hide_arkiv || null,
itunes: options.affiliates.itunes || null,
amazon: options.affiliates.amazon || null,
arkiv: options.affiliates.arkive || null
};
// Pull out empty fields
if (!$.template.params.itunes) delete $.template.params.itunes;
if (!$.template.params.amazon) delete $.template.params.amazon;
if (!$.template.params.arkiv) delete $.template.params.arkiv;
if (!$.template.params.show_song) delete $.template.params.show_song;
if (!$.template.params.style) delete $.template.params.style;
if (!$.template.params.hide_itunes) delete $.template.params.hide_itunes;
if (!$.template.params.hide_amazon) delete $.template.params.hide_amazon;
if (!$.template.params.hide_arkiv) delete $.template.params.hide_arkiv;
// force now playing to an uncached request
if (schedule === 'now') request_url = request_url + '?bust=' + ~~(Math.random() * 1E9);
/*
$.template(request_url) = Request widget data (from cache or a new request), uses cacheFactory (see code at the top of this script)
When the data has been received, handle the construction and rendering of the HTML
*/
$.when( $.template(request_url) ).done( function (data) {
$.renderTemplate(data, elem, options);
// Set up the widget header
if (schedule === 'week') {
var week_of = moment().isoday(1).format('[Week of] MMMM Do, YYYY');
$.fn.whatsOn.header(elem, week_of, options);
}
if (schedule === 'day') {
var day_date = moment().format('dddd, MMMM Do, YYYY');
$.fn.whatsOn.header(elem, day_date, options);
}
// Add a handler for when an Itunes link is clicked
$('.itunes-link').on('click', function (e) { // BEGIN itunes link click handler
e.preventDefault();// If this method is called, the default action of the event will not be triggered.
var searchUrl = $(this).attr('href').split('?');
var forwardTo = '';
var searchPairs = searchUrl[1].split('&');
var searchTerms = '';
var affiliate = '';
$.each(searchPairs, function (key, value) {
var pairs = value.split('=');
if (pairs[0] == 'at') {
affiliate = pairs[1];
}
else {
searchTerms = searchTerms + ' ' + pairs[1];
}
});
$.ajax({
url: 'https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/wsSearch?entity=musicTrack&country=US&term=' + searchTerms + '&at' + affiliate + '&limit=1&callback=?',
type: 'GET',
dataType: 'jsonp',
success: function (data) {
console.log('data', data)
if (data.resultCount > 0) {
if (data.results[0].collectionViewUrl) {
forwardTo = data.results[0].collectionViewUrl;
}
else {
forwardTo = data.results[0].artistViewUrl;
}
}
else {
forwardTo = 'https://itunes.apple.com/us/';
}
window.open(forwardTo, 'itunes');
},
error: function (err) {
console.log('err', err);
console.log(err);
window.open('https://itunes.apple.com/us/', 'itunes');
}
});
});// END itunes link click handler
$.fn.whatsOn.collapse();
}).always(function () {
if (schedule === 'now') {
setTimeout(builder, 60000);
}
}).fail(function () {
$.errorMessage(elem);
});
}// END build plugin function
});// END return the plugin
};
// Expand/collapse episode detail - This widgets allows for you to expand an episode to view it's playlist and episode notes.
$.fn.whatsOn.collapse = function () {
$('.playlist-controls').on('click.whatsOn', function () {
$(this).toggleClass('opener');
$(this).parent().find('.dailyPlaylist').toggle();
});
$('.notes-controls').on('click.whatsOn', function () {
$(this).toggleClass('opener');
$(this).parent().find('.episodeNotes').toggle();
});
};
// Construct header and setup events handler for the next/previous link
$.fn.whatsOn.header = function (elem, date, options) {
var nav_control_prev = '<td class="whatson-prev arrow-left"><a class="hidden" href="#">Previous</a></td>';
var nav_control_next = '<td class="whatson-next arrow-right"><a class="hidden" href="#">Next</a></td>';
var header_nav = [
'<table id="whatson-header" width="100%" border="0" cellspacing="0" cellpadding="0">',
'<tr>' + nav_control_prev + '<td class="whatson-date">' + date + '</td>' + nav_control_next + '</tr>',
'</table>'
].join('');
elem.prepend(header_nav);
// Events handler for navigational next/previous links
$(elem).find('.whatson-prev, .whatson-next').on('click', options, $.fn.whatsOn.nav);
};
// This is the event handler for the widget's next/previous links
$.fn.whatsOn.nav = function (e) {// BEGIN next/previous date/date-range handler
e.preventDefault();
var widget = e.data.elem;
var header = '.whatson-header';
var date_header = '.whatson-date';
var content = '.whatson-content';
var direction = ( $(e.currentTarget).is('.whatson-next') ) ? 'next' : 'prev';
var current_date = widget.find(date_header).text();
var moment_date = moment(current_date, 'dddd, MMMM D YYYY');
var station = e.data.station;
var schedule = e.data.schedule;
var affiliates = e.data.affiliates;
var full_week_date = current_date.replace('Week of ', '');
var request_url;
var options = {}; // Configuration
// Configure buy links for songs within episodes
if (affiliates.itunes) options.itunes = affiliates.itunes;
if (affiliates.amazon) options.amazon = affiliates.amazon;
if (affiliates.arkiv) options.arkiv = affiliates.arkiv;
if (e.data.hide_itunes) options.hide_itunes = e.data.hide_itunes;
if (e.data.hide_amazon) options.hide_amazon = e.data.hide_amazon;
if (e.data.hide_arkiv) options.hide_arkiv = e.data.hide_arkiv;
if (e.data.show_song) options.show_song = e.data.show_song;// Display song meta data
if (e.data.style) options.style = e.data.style;// Which template is being used
// This function updates the display after a new request is made
var updater = function (request_url, update_header) {
$('.opener, .closer').off('.whatsOn'); // Disable event handlers
$.when( $.template(request_url) ).done( function (data) { // After the request, update the display
widget.find(header)
.remove().end()
.find(date_header).html(update_header).end()
.find(content).replaceWith(data);
$.fn.whatsOn.collapse();
});
};
if (direction === 'next') { // The 'next' link was clicked
var next_from_current = moment(full_week_date, 'MMMM D YYYY').add('d', 7);
// Set the next date/date-range. If its the daily widget use a date, for the weekly widget use a range
var next_api = ( schedule === 'week' )
? '?date=' + next_from_current.isoday(1).format('YYYY-MM-DD')
+ ',' + next_from_current.isoday(7).format('YYYY-MM-DD')
: '?date=' + moment_date.add('d', 1).format('YYYY-MM-DD');
var next_header = ( schedule === 'week' )
? moment(next_from_current, 'MMMM D YYYY').isoday(1).format('[Week of] MMMM Do, YYYY')
: moment_date.format('dddd, MMMM Do, YYYY');
request_url = $.fn.whatsOn.env + '/widget/' + station + '/' + schedule + next_api;
$.template.params = $.extend({ format: 'jsonp' }, options);
updater(request_url, next_header);// Go ahead and update the display to be the 'next' date/date-range
} else {
// Set the previous date/date-range. If its the daily widget use a date, for the weekly widget use a range
var prev_from_current = moment(full_week_date, 'MMMM D YYYY').subtract('d', 7);
var prev_api = ( schedule === 'week' )
? '?date=' + prev_from_current.isoday(1).format('YYYY-MM-DD')
+ ',' + prev_from_current.isoday(7).format('YYYY-MM-DD')
: '?date=' + moment_date.subtract('d', 1).format('YYYY-MM-DD');
var prev_header = ( schedule === 'week' )
? moment(prev_from_current, 'MMMM D YYYY').isoday(1).format('[Week of] MMMM Do, YYYY')
: moment_date.format('dddd, MMMM Do, YYYY');
$.template.params = $.extend({ format: 'jsonp' }, options);
request_url = $.fn.whatsOn.env + '/widget/' + station + '/' + schedule + prev_api;
updater(request_url, prev_header);// Go ahead and update the display to be the 'previous' date/date-range
}
};// END next/previous date/date-range handler
// Default widget options
$.fn.whatsOn.options = {
schedule: 'now',
label: true,
env: 'https://api.composer.nprstations.org/v1',
assets: 'https://composer.nprstations.org',
affiliate: {},
times: true,
next: true
};
// === End .whatsOn plugin functions ===
})(jQuery, window, document);
I am try to call a function onblur of my three elements in my table
but i am getting this error in my console
"((m.event.special[e.origType] || (intermediate value)).handle || e.handler).apply is not a function".
So onblur these elements i want to call my function.Please do have a look at my code once.
Apologies for my bad handwriting here .I am new to javascript
jq.ajax({
url: '/soap/ajax/36.0/connection.js',
dataType: 'script',
success: function() {
jq(document).ready(function() {
// call tookit dependent logic here
jq('#gbMainTable').on('blur', 'tr.dr td[name="v4"] select','tr.dr td[name="v6"] select','tr.dr td[name="v7"] input', function()
{
var thisInput = this;
console.log('thisInput.value',thisInput.value);
var thisInput1 = jq(this);
var thisRow = thisInput1.parents('tr.dr:first');
console.log('thisRow',thisRow);
var agentInput1 = thisRow.find('td:eq(7)');
console.log('agentInput1',agentInput1);
var finds1 = agentInput1.find('select');
console.log('finds1',finds1);
var agentInput2 = thisRow.find('td:eq(8)');
console.log('agentInput2',agentInput2);
var finds2= agentInput2.find('input');
if(agentInput1.text()!=='' & thisInput.value=='Programmable Cntrls/Welders/AC Drives/Soft Starts'){
exampleFunction('Programmable',agentInput1.text(),agentInput2.text());
console.log('YES');
}
else if(agentInput1.text()!=='' & thisInput.value=='Electro Mechanical'){
exampleFunction('Electro-Mechanical',agentInput1.text(),agentInput2.text());
}
});
});
},
async: false
});
function exampleFunction(Warranty,Years,charge) {
var state = { // state that you need when the callback is called
output : null,
startTime : new Date().getTime()};
var callback = {
//call layoutResult if the request is successful
onSuccess: doThis,
//call queryFailed if the api request fails
onFailure: queryFailed,
source: state};
sforce.connection.query(
"SELECT InOut__c,PlantPct__c,T37Pct__c,TotalPct__c,Type__c,Warranty_Code__c,Years__c FROM WarrantySpecialLine__c where InOut__c = '" +charge+"' and Years__c = '"+Years+"' and Type__c = '" +Warranty +"'",
callback);
}
function queryFailed(error, source) {
console.log('error: '+error);
}
/**
* This method will be called when the toolkit receives a successful
* response from the server.
* #queryResult - result that server returned
* #source - state passed into the query method call.
*/
function doThis(queryResult, source) {
if (queryResult.size > 0) {
var output = "";
// get the records array
var records = queryResult.getArray('records');
// loop through the records
for (var i = 0; i < records.length; i++) {
var warrantySpecial = records[i];
console.log(warrantySpecial.PlantPct__c + " " + warrantySpecial.TotalPct__c + " " +warrantySpecial.T37Pct__c );
}
}
}
I have a div in a page where I show a list of records which are stored in my Database ( firebase). Whenever there is a new record in the database, I want the div to auto load in the new record without refreshing the whole page. So how can I do that?
Javascript code on showing records
query.on("child_added", function(messageSnapshot) {
var keys = Object.keys(messageSnapshot);
var messageData = messageSnapshot.val();
var key = messageSnapshot.getKey();
console.log("key is " + messageSnapshot.getKey());
console.log("messagesnapshot is " + messageSnapshot);
var obj = {
key: key,
};
arr.push(obj);
ref.child(key + "/User Information").once('value').then(function(snapshot) {
var name = snapshot.val().firstName
s = "<li><a href='#'>" + no + '. ' + name + ' ' + key + "</a></li>";
no++;
sources.push(s);
// for ( property in messageSnapshot) {
// console.log( property ); // Outputs: foo, fiz or fiz, foo
//}
console.log("arr.length is " + arr.length);
}).then(function(pagination) {
Pagination();
});
});
function Pagination() {
var arrLength = arr.length;
var container = $("#mylist");
// var sources = function () {
// var result = [];
//
// for (var i = 1; i < arrLength; i++) {
// result.push(i);
// }
//
// return result;
// }();
var options = {
dataSource: sources,
pageSize: 10,
callback: function(data, pagination) {
//window.console && console.log(response, pagination);
var dataHtml = '';
$.each(data, function(index, item) {
dataHtml += item;
});
console.log(dataHtml);
container.prev().html(dataHtml);
}
};
//$.pagination(container, options);
container.addHook('beforeInit', function() {
window.console && console.log('beforeInit...');
});
container.pagination(options);
container.addHook('beforePageOnClick', function() {
window.console && console.log('beforePageOnClick...');
//return false
});
return container;
}
Html code div
<div data-role="page" id="pageone">
<div data-role="header">
<button onclick="goBack()">Back</button>
<h1>Pending Transaction</h1>
</div>
<div id="mylist"></div>
</div>
At first your local code must be aware of changes in the Database, so the plain answer is:
Your JS-Code must periodically ask your DB for changes, if changes are available you can call that changes and update your content via an AJAX-Request and put it into the div#mylist
This "periodically ask" is called long polling, aspnet has for example the framework called SignalR
When I run the javascript code below, it load specified amount of images from Flickr.
By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.
Then, I can see the object has exactly 10 items by checking console.log(photos);
But actual image appeared on the page is less than 10 items...
I have no idea why this work this way..
Thank you in advance.
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
var PhotoGroup = function(nativePhotos, callback) {
var _cache = new Array();
var numberOfPhotosLoaded = 0;
var containerWidth = $("#contents").css('max-width');
var containerHeight = $("#contents").css('max-height');
$(nativePhotos).each(function(key, photo) {
$("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
.attr("alt", photo['title'])
.attr("data-cycle-title", photo['ownername'])
.load(function() {
if(this.naturalWidth >= this.naturalHeight) {
$(this).attr("width", containerWidth);
} else {
$(this).attr("height", containerHeight);
}
_cache.push(this);
if(nativePhotos.length == ++numberOfPhotosLoaded)
callback();
})
});
var getRandom = function(max) {
return Math.floor((Math.random()*max)+1);
}
this.getPhotos = function(numberOfPhotos) {
var photoPool = new Array();
var maxRandomNumber = _cache.length-1;
while(photoPool.length != numberOfPhotos) {
var index = getRandom(maxRandomNumber);
if($.inArray(_cache[index], photoPool))
photoPool.push(_cache[index]);
}
return photoPool;
}
}
var Contents = function() {
var self = this;
var contentTypes = ["#slideShowWrapper", "#video"];
var switchTo = function(nameOfContent) {
$(contentTypes).each(function(contentType) {
$(contentType).hide();
});
switch(nameOfContent) {
case("EHTV") :
$("#video").show();
break;
case("slideShow") :
$("#slideShowWrapper").show();
break;
default :
break;
}
}
this.startEHTV = function() {
switchTo("EHTV");
document._video = document.getElementById("video");
document._video.addEventListener("loadstart", function() {
document._video.playbackRate = 0.3;
}, false);
document._video.addEventListener("ended", startSlideShow, false);
document._video.play();
}
this.startSlideShow = function() {
switchTo("slideShow");
var photos = photoGroup.getPhotos(10)
console.log(photos);
$('#slideShow').html(photos);
}
var api_key = '6242dcd053cd0ad8d791edd975217606';
var group_id = '2359176#N25';
var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
var photoGroup;
$.getJSON(flickerAPI, {
api_key: api_key,
group_id: group_id,
format: "json",
method: "flickr.groups.pools.getPhotos",
}).done(function(data) {
photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
});
}
var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>
I fix your method getRandom() according to this article, and completely re-write method getPhotos():
this.getPhotos = function(numberOfPhotos) {
var available = _cache.length;
if (numberOfPhotos >= available) {
// just clone existing array
return _cache.slice(0);
}
var result = [];
var indices = [];
while (result.length != numberOfPhotos) {
var r = getRandom(available);
if ($.inArray(r, indices) == -1) {
indices.push(r);
result.push(_cache[r]);
}
}
return result;
}
Check full solution here: http://jsfiddle.net/JtDzZ/
But this method still slow, because loop may be quite long to execute due to same random numbers occurred.
If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.
I have the following javascript code having class named as PurchaseHistory.
var baseUrl = null;
var parameters = null;
var currentPageNumber = null;
var TotalPages = null;
var PageSize = null;
$(document).ready(function () {
baseUrl = "http://localhost/API/service.svc/GetOrderHistory";
parameters = '{"userId":1 , "page":1 ,"pageSize":4}';
currentPageNumber = 1;
var history = new PurchaseHistory();
history.ajaxCall(parameters);
});
function PurchaseHistory() {
/* On ajax error show error message
-------------------------------------------------*/
this.onAjaxError = function() {
$('#error').text('No internet connection.').css('color', 'red');
}
/* Ajax call
-------------------------------------------------*/
this.ajaxCall = function (parameters) {
$.support.core = true;
$.ajax({
type: "POST",
url: baseUrl,
data: parameters,
//dataType: 'json',
contentType: "application/json; charset=UTF-8",
error: function () { this.onAjaxError() }
}).done(function (data) {
var json = data.GetOrderHistoryResult;
var jsonObject = $.parseJSON(json);
var history = new PurchaseHistory();
history.populateOrderHistory(jsonObject);
TotalPages = jsonObject.PgCnt;
currentPageNumber = jsonObject.CrntPg;
});
}
this.populateOrderHistory = function(results) {
var rowOutput = "";
var his = new PurchaseHistory();
for (var i = 0; i < results.Results.length; i++) {
rowOutput += this.renderCartList(results.Results[i], 1);
}
}
this.renderCartList = function(res, i) {
var container = $('#prototype-listelement>li').clone();
container.find('.order-date').text(res.OdrDate);
container.find('.item-count').text(res.Qty);
container.find('.total').text(res.Amt);
container.find('.order-id').text(res.OdrId);
$('#mainul').append(container).listview('refresh');
}
this.loadNextPage = function () {
parameters = '{"userId":1 , "page":' + currentPageNumber + 1 + ',"pageSize":4}';
this.ajaxCall(parameters);
}
}
The ajaxCall is made on the ready function of the javascript.
This ajax calls returns Json object with pages information, which includes current page number, total pages and page size.
Currently I am able to display the information on the UI, when the page gets loaded.
My Issue:-
I want to call the ajax method again, on the button click event.
How this can be made possible and where can I store the information obtained from previous ajax call?
For pagination I would create a link that will load more items onto the page, and save a starting number to pass to your data layer. This example loads 20 at a time.
<a class="more" href="#" data-start="0">show more</a>
$("a.more").click(function(e){
e.preventDefault();
var start = $(this).attr('data-start');
$.get('/more-data, { start: start }, function(d){
var next = start+20;
$("a.more").attr('data-start', next);
//process results here, do something with 'd'
});
});