I would like to retrieve the class when I click on the link that contains -> class="prez_col-'+i +'" in the viewPoster function. I don't know if it's because of the html() function or the event that prevents me from retrieving the name of the class from the DOM when I click on
template += '<p class="prez_title">' + data[i].title + '</p><img src="' + condJaq + '" class="prez_jaquette" />';
$("#prez_choiseJaq").html(template);
I tried to put onclick in the template variable:
template += '<p class="prez_title">' + data[i].title + '</p><img src="' + condJaq + '" class="prez_jaquette" />';
$("#prez_choiseJaq").html(template);
I have an error! when on one of the posters displays
File HTML
<div id="prez_rech" class="prez_rech">
<label for="fname">Recherche du film :</label>
<input type="text" placeholder="Entrez votre film ici" id="prez_input">
<xf:button type="button" id="prez_btn">Rechercher</xf:button>
</div>
<div id="prez_choiseJaq"></div>
<footer class="prez_footer">Created by Marilyn</footer>
<script type="module" src="js/vendor/prez/prez.js"></script>
File getValue .js
import { array } from './params.js';
const key = array['key'];
const urlMovie = array['urlMovie'];
const noCover = array['noCover'];
const urlImg = array['urlImg'];
const urlJaq = array['urlJaq'];
var jaq = document.getElementById("prez_choiseJaq");
var input = document.getElementById("prez_input");
var myBtn = document.getElementById("prez_btn");
var rech = document.getElementById("prez_rech");
var jaqSelected = $("a.prez_col-" + i);
var data = [];
var inputRep;
var urlNoCover = urlImg + noCover;
var url = urlMovie + key;
var i;
var test = false;
input.addEventListener("keypress", function (event) {
if (event.key === "Enter") {
event.preventDefault();
inputRep = input.value;
getValue();
}
});
myBtn.addEventListener("click", event => {
event.preventDefault();
inputRep = input.value;
getValue();
});
jaqSelected.click(function() {
alert(jaqSelected);
});
async function getValue() {
console.log(inputRep);
try {
const response = await fetch(url + "&language=fr-FR&query=" + inputRep + "&page=1&include_adult=false");
const responseData = await response.json();
data = responseData?.results;
console.log(data);
if (!data.length) {
alert("Le film que vous demandez n'est pas disponible !");
} else {
viewPoster();
}
} catch (error) {
console.log(error);
}
return data;
};
function viewPoster() {
test = false;
if (data) {
var template = "";
jaq.style.display = "inline-grid";
i = -1;
do {
i += 1;
console.log(i);
let condJaq;
if (data[i].poster_path == null) {
condJaq = urlNoCover;
} else {
condJaq = urlJaq + data[i].poster_path;
};
template += '<p class="prez_title">' + data[i].title + '</p><img src="' + condJaq + '" class="prez_jaquette" />';
$("#prez_choiseJaq").html(template);
} while (i < data.length);
};
};
function selected(arg) {
console.log(arg);
};
export { getValue };
File params.js
var array = {
key: "exemple",
urlMovie: 'https://api.themoviedb.org/3/search/movie?api_key=',
urlSerie: 'https://api.themoviedb.org/3/search/tv?api_key=',
urlImg: 'styles/prez/img/',
urlJaq: "https://image.tmdb.org/t/p/w154",
noCover: "no_cover.jpeg",
};
export { array };
File prez.js
import { array } from './params.js';
import { getValue } from './getValue.js';
do you have an idea ?
Thanks in advance.
There are so many issues here it's difficult to explain why your code isn't working. The issue with the for loop is a candidate for the error you didn't share, but there others.
The primary problem is that you were not adding a click handler for your links.
I've converted your code from module based JS (because I believe that's difficult to do in a snippet), mocked the Movie API call and cleaned up the code to remove most unnecessary globals, leverage jQuery more, and fix the for loop.
var array = {
key: "exemple",
urlMovie: 'https://api.themoviedb.org/3/search/movie?api_key=',
urlSerie: 'https://api.themoviedb.org/3/search/tv?api_key=',
urlImg: 'styles/prez/img/',
urlJaq: "https://image.tmdb.org/t/p/w154",
noCover: "no_cover.jpeg",
};
function mock_fetch(url, rep) {
const query = url + "&language=fr-FR&query=" + rep + "&page=1&include_adult=false"
// response = await fetch(query);
// return await reponse.json()
return { results: [{ poster_path: "This is the poster path"
, title: rep
}
,{ poster_path: "Some other path"
, title: "Some other movie"
}
]
}
}
var data; // this will hold whatever data retrieved by the last query to the movie API (may be null/undefined)
async function getValue(inputRep) {
try {
const responseData = mock_fetch(array.urlMovie + array.key, inputRep);
data = responseData?.results;
if (!data.length) {
alert("Le film que vous demandez n'est pas disponible !");
} else {
viewPoster(data);
}
} catch (error) {
console.error(error);
}
return data;
};
function viewPoster() {
$("#prez_choiseJaq").css("display", "inline-grid");
var template = "";
data.forEach( (film, index) => {
template += `${film.title}</p><img src="${film.poster_path?(array.urlJaq + film.poster_path):array.urlImg+array.noCover}" class="prez_jaquette" />`;
})
$("#prez_choiseJaq").html(template);
};
function selectMovie(event) {
event.preventDefault();
getValue($('#prez_input').val());
}
function doSomethingWithFilm(event) {
let index = $(this).data('index');
console.log(`The index you clicked was ${index}`)
if (data && data[index]) {
console.log(`The data for that index is ${JSON.stringify(data[index])}`)
} else {
console.log(`The data for that index is not available`)
}
}
function init() {
$('#prez_input').keypress(event => { event.key === "Enter" && selectMovie(event) });
$('#prez_btn').on("click", selectMovie);
// Add the click handler for the links as a delegate because the links do not exist at the time this code is executed
$(document).on("click", ".prez_col", doSomethingWithFilm);
}
$(init)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</script>
</head>
<body>
<div id="prez_rech" class="prez_rech">
<label for="fname">Recherche du film :</label>
<input type="text" placeholder="Entrez votre film ici" id="prez_input">
<xf:button type="button" id="prez_btn">Rechercher</xf:button>
</div>
<div id="prez_choiseJaq"></div>
</body>
</html>
Your do {} while () loop condition is trying to loop one beyond your data array. The problem is how you set up and increment your iterator variable: i.
You set your iterator to i = -1; before the loop, then, first thing in the loop you increment it: i += 1;, and the while condition is set to stop looping when i is equal to the array length: while ( i < data.length ). If an array has one element, i must be value 1 to discontinue the loop. At the end of the first pass i is equal to 0. Even in the case of a single array element it is still less than the length of the array so the loop will loop again. One element, two loops. Two elements, three loops. Three elements, four loops, etc.
The easy fix is change:
while (i < data.length);
...to:
while (i < data.length - 1);
let data = ['a','b','c','d','e'];
// ALWAYS ONE TO MANY LOOPS
let i = -1;
do {
i += 1;
console.log(i, data[i]);
} while (i < data.length);
// EASY FIX
i = -1;
do {
i += 1;
console.log(i, data[i]);
} while (i < data.length - 1); // <-- reduce length by one
// BETTER YET
i = 0;
do {
console.log(i, data[i]);
i += 1; // <-- move iterator increment to end of loop
} while (i < data.length);
How to use an iterator variable to control a loop:
Regardless of what type of loop you use: for, while, do while, it makes more sense to me to use your loop iterator, when you need one, as such:
let data = [1,2,3,4,5,6];
let ii = 0;
do {
console.log(ii, data[ii]);
ii++;
} while ( ii < data.length );
Before the loop, set ii to 0. The loop starts, use ii as 0, then at the very end of the loop increment ii. Every element is accessed, and only accessed once.
Here's the function (simple fixed) where you're do {} while () loop is:
function viewPoster() {
test = false;
if (data) {
var template = "";
jaq.style.display = "inline-grid";
i = -1;
do {
i += 1;
console.log(i);
let condJaq;
if (data[i].poster_path == null) {
condJaq = urlNoCover;
} else {
condJaq = urlJaq + data[i].poster_path;
};
template += '<p class="prez_title">' + data[i].title + '</p><img src="' + condJaq + '" class="prez_jaquette" />';
$("#prez_choiseJaq").html(template);
} while (i < data.length - 1);
};
};
Related
I have the following code:
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
};
return result;
};
var instance = "{{ user }}" + makeid(16);
var checksum = "First Request Not recieved";
console.log(instance);
function downloadPlay(){
console.log("\ndownloadPlay - Begin\n")
try{
fetch("/file?instance=" + instance + "&checksum=" + checksum)
.then(function(resp) {
resp.headers.forEach(
function(val, key) {
// console.log("key, val: " + key + ", " + val);
if(key == "checksum"){
console.log("checksum: " + val);
checksum = val;
};
}
);
}
)
.then(file => {
var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
console.log("Done");
audio.addEventListener('ended', (event) => {
delete audio;
downloadPlay();
});
audio.play();
}
)
} catch (error) {
console.log("Something went wrong, Retrying: " + error);
}
console.log("downloadPlay - Complete\n")
};
downloadPlay();
This works perfectly when the promise succeeds. However when it fails(such as when the client device switches networks, i.e. wifi to data or just different access points on the same wifi network) it stops dead and never resumes no matter how many while loops, extra recursion points or try and catch statements I use. The best I could do so far is get it to play ever increasing numbers of the audio mostly in sync with each other and I just dont understand why. It seems I have a general lack of understanding of how this promise thing actually functions, but no matter how many tutorials I read/watch my lack of understanding seems to remain unchanged.
Heres the code that somewhat worked if that helps:
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
};
return result;
};
var instance = "{{ user }}" + makeid(16);
var checksum = "First Request Not recieved";
console.log(instance);
function downloadPlay(){
console.log("\ndownloadPlay - Begin\n")
try{
console.log('fetching')
fetch("/file?instance=" + instance + "&checksum=" + checksum)
.then(function(resp) {
resp.headers.forEach(
function(val, key) {
// console.log("key, val: " + key + ", " + val);
if(key == "checksum"){
console.log("checksum: " + val);
checksum = val;
};
}
);
}
).catch(function(error) {
console.log('request failed', error)
console.log('retrying')
downloadPlay();
return;
})
.then(file => {
var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
console.log("Done");
audio.addEventListener('ended', (event) => {
delete audio;
downloadPlay();
});
audio.play();
}
)
} catch (error) {
console.log("Something went wrong, Retrying: " + error);
}
console.log("downloadPlay - Complete\n")
};
downloadPlay();
Any solution or very simple explanation on what im doing wrong would be much appreciated
Thanks in advance :)
You can do something like this
Just remove the comment and use your original fetching function
You can't use try catch with promises unless you use async await
const fakeChecking = Promise.resolve({headers: {checksum: 'aaaa'}})
const errorChecking = Promise.reject('error')
function downloadPlay(fetching) {
console.log("\ndownloadPlay - Begin\n")
console.log('fetching')
fetching
.then((resp) => resp.headers.checksum)
.then(checksum => {
/*var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
console.log("Done");
/*audio.addEventListener('ended', (event) => {
delete audio;
downloadPlay();
console.log("downloadPlay - Complete\n")
});
audio.play();*/
console.log("downloadPlay - Complete\n")
})
.catch(function(error) {
console.log('request failed', error)
console.log('retrying')
downloadPlay(fakeChecking);
})
};
downloadPlay(errorChecking);
I want to learn such new JavaScript features as fetch() and arrow functions. To this end, I selected a function from a recent app, and attempted to replace older features with new. Very little success. Here's my original function:
function popNames(arNumbers,ctrlName) {
var arSortedList = [];
var strNameList = "";
$.getJSON("NAME.json").done(function(zdata) {
$.each(arNumbers, function(i, ydata) {
$.each(zdata.NAME, function(k,v) {
if(v.idName == ydata) {// important: === did NOT work
if(ctrlName) arSortedList.push(v.last + ", " + v.first + ";" + v.idName);
else arSortedList.push(v.last + ", " + v.first);
}
}); // each element of NAME.json
}); // each idName value in the array passed
if(ctrlName) {
setOptions(arSortedList, ctrlName);
} else {
strNameList = arSortedList.join();
}
}); // getJSON NAME
}
I was successful using this line:
fetch("NAME.json").then(zdata => zdata.json())
but nothing I did after that worked. I'd appreciate seeing an example from which I can learn.
function popNames(arNumbers,ctrlName) {
let arSortedList = [];
let strNameList = "";
fetch("NAME.json").then(zdata => zdata.json())
.then(zdata => {
for(const ydata of arNumbers) {
for(const v of zdata.NAME) {
if(v.idName == ydata) { // important: === did NOT work
if(ctrlName) arSortedList.push(v.last + ", " + v.first + ";" + v.idName);
else arSortedList.push(v.last + ", " + v.first);
}
}
}
if(ctrlName) {
setOptions(arSortedList, ctrlName);
} else {
strNameList = arSortedList.join();
}
}); // getJSON NAME
}
I was researching why I couldn't next two Array.forEach statements, and discovered a new iterable construction (for...of).
Got some code that works just fine and will retrieve all the items in a specified playlist but need to amend it so it can loop through an array of playlists and retrieve all items in each list.
I've tried putting for-next loops in various places in the code but, as my javascript is poor, those efforts have failed and I don't know what to do next.
function onGoogleLoad() {
showhide('hidden');
getSearchParameters();
gapi.client.setApiKey(APIKEY);
gapi.client.load('youtube', 'v3', function () {
GatherVideos("", function () {
for (var i = 0; i < allVideos.length; i++) {
console.log(allVideos[i].snippet.title + " published at " + allVideos[i].snippet.publishedAt)
}
showhide('visible');
build_html(allVideos);
});
});
}
ORIGINAL CODE ...
function GatherVideos(pageToken, finished) {
var request = gapi.client.youtube.playlistItems.list({
part: 'snippet, contentDetails',
playlistId: 'UU_FksrzP3q-IuoWTiG501LQ',
maxResults: 50,
pageToken: pageToken
});
request.execute(function(response) {
allVideos = allVideos.concat(response.items);
if (!response.nextPageToken)
finished();
else
GatherVideos(response.nextPageToken, finished);
});
}
END ORIGINAL CODE
NEW CODE WITH ATTEMPT AT LOOPING ...
function GatherVideos(pageToken, finished) {
for (var p=0;p<allPlaylists.length;p++)
{
console.log('Gathering: ' + allPlaylists[p]);
var request = gapi.client.youtube.playlistItems.list({
part: 'snippet, contentDetails',
playlistId: allPlaylists[p],
maxResults: 50,
pageToken: pageToken
});
request.execute(function(response) {
console.log('Executing: ' + request);
allVideos = allVideos.concat(response.items);
if (!response.nextPageToken)
finished();
else
GatherVideos(response.nextPageToken, finished);
});
} //End for loop
}
END NEW CODE ...
function build_html(parArray) {
var n = 0;
var playlistHtml = '';
var rows = Math.floor(parArray.length / vinrow);
var rem = (allVideos.length % vinrow);
if (rem > 0) {
rows++;
}
for (var i = 0; i < rows; i++) {
playlistHtml += '<div class="row">';
for (var k = 0; k < vinrow; k++) {
if (n < parArray.length) {
playlistHtml += '<div id=' + n + ' class="col item"><img class="img-responsive fit-image" src="' +
parArray[n].snippet.thumbnails.default.url + '"><div class="vtitle">' +
parArray[n].snippet.title + '</div></div>';
n++;
} else {
playlistHtml += '<div class="col item"><div class="vtitle"> </div></div>';
}
}
playlistHtml += "</div>";
}
playlist_div.innerHTML = playlistHtml;
}
}
So, need some help about where to place the code which will loop through the array of playlists.
You loop over allPlaylists, building the request and saving it in the request variable. The issue is, that this loops overwrites the request variable each time it is executed. When you later call request.execute(...) you're only executing the last request build (last playlist in the array).
You should move the request execution inside the for-loop.
for (var p = 0; p < allPlaylists.length; p++)
{
console.log('Gathering: ' + allPlaylists[p]);
var request = gapi.client.youtube.playlistItems.list({ /* ... */ });
request.execute(/* ... */);
}
The above already fixes part of the issue. This however doesn't fix the problem in its entirety. You're recursively calling GatherVideos (if there is more than 1 page) which in turn walks through the whole allPlaylists array again. Setting out new requests for each playlist.
To resolve the issue above retrieving videos from a single playlist should be moved into its own method. Using with the current structure is a bit cumbersome for different reasons, so I've rebuild it from scratch using a somewhat different approach. This might not be the exact answer you're looking for, but I hope it will give you some inspiration:
async function listPlaylist(options = {}) {
var maxResults, pendingMaxResults, response;
options = Object.assign({}, options);
maxResults = options.maxResults;
if (Number.isInteger(maxResults) && maxResults > 0) {
// set options.maxResults to a value 1-50
options.maxResults = (maxResults - 1) % 50 + 1;
pendingMaxResults = maxResults - options.maxResults;
} else if (maxResults === "all") {
pendingMaxResults = "all";
}
response = await Promise.resolve(gapi.client.youtube.list(options));
if (response.nextPageToken && (pendingMaxResults === "all" || pendingMaxResults > 0)) {
options.maxResults = pendingMaxResults;
options.pageToken = response.nextPageToken;
return response.items.concat(await listPlaylist(options));
} else {
return response.items;
}
}
(async function () {
var playlistsVideos, videos;
// retrieve all videos of all playlists
playlistsVideos = await Promise.all(allPlaylists.map(function (playlistId) {
return listPlaylist({
id: playlistId,
part: "snippet, contentDetails",
maxResults: "all"
});
}));
// the above variable `playlistsVideos` is in the format:
// [[p1v1, p1v2, p1v3], [p2v1, p2v2, p2v3]] (p = playlist, v = video)
// this needs to be flattened to have the result you want
videos = playlistsVideos.reduce((videos, playlistVideos) => videos.concat(playlistVideos), []);
})();
I'd recommend checking out the guide Using Promises and checking out the documentation for async/await. The above is based upon YouTube API V3. I hope I wrote the code clear enough to let it speak for itself. If you have any question just ask away in the comments.
I'm trying to make a kind of newswire for a school project but I'm having a few problems with jQuery's .each() function. I'm trying to find a way to skip every 2nd array element in a loop.
Basically I have data from a NY Times API and got both title and abstract and push these into an array that I then loop and animate every once and awhile.
My problem is, I can't seem to find a way to get Title + Abstract (Index[0]+[1]) without the loop just moving to index[1] again. Now I knows in Javascript you can simply use a for (i=0; i < array.length; i+2) and thus skip every 2nd array element, but I haven't had any luck incorporating that. Any suggestions? :)
$(document).ready(function() {
var newsWire = [];
function loadNewswire() {
return $.getJSON('http://api.nytimes.com/svc/news/v3/content/all/all.json',
{'api-key': 'XXXXXXXXXXXXXXXXXXX'},
function(data) {
console.log(data)
var newsWireTemp = [];
for (var i = 0; i < data.results.length; i++) {
var breakingNews = data.results[i];
var breakingTitle = breakingNews.title.toUpperCase();
var breakingAbstract = breakingNews.abstract;
newsWireTemp.push(breakingTitle);
newsWireTemp.push(breakingAbstract);
}
newsWire = newsWireTemp;
});
}
loadNewswire().done(function () {
var items = newsWire;
$text = $('#newswiretxt span'),
delay = 10; //seconds
function loop (delay) {
$.each(items, function (i, elm){
$text.delay(delay*1E3).fadeOut();
$text.queue(function(){
$text.html(items[i]+ ": " +items[i+1]);
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if (i == items.length -1) {
loop(delay);
}
$text.dequeue();
});
});
}
console.log(items.length);
loop(delay);
});
});
Basically, just push the desired text concatenated into the array for the load function. Then as you iterate you can simply write the contents as is without messing with the iteration.
$(document).ready(function() {
var newsWire = [];
function loadNewswire() {
return $.getJSON('http://api.nytimes.com/svc/news/v3/content/all/all.json',
{'api-key': 'XXXXXXXXXXXXXXXXXXX'},
function(data) {
console.log(data)
var newsWireTemp = [];
for (var i = 0; i < data.results.length; i++) {
var breakingNews = data.results[i];
var breakingTitle = breakingNews.title.toUpperCase();
var breakingAbstract = breakingNews.abstract;
newsWireTemp.push(breakingTitle + ': ' + breakingAbstract);
}
newsWire = newsWireTemp;
});
}
loadNewswire().done(function () {
var items = newsWire;
$text = $('#newswiretxt span'),
delay = 10; //seconds
function loop (delay) {
$.each(items, function (i, elm){
$text.delay(delay*1E3).fadeOut();
$text.queue(function(){
$text.html(items[i]);
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if (i == items.length -1) {
loop(delay);
}
$text.dequeue();
});
});
}
console.log(items.length);
loop(delay);
});
});
See if this SO thread helps you.
From what I understand, you'd like to skip every other iteration, so checking i's parity to skip when appropriate should work.
For the lazy:
$.each(array, function(index, item) {
if(index % 2 === 0) return true; // This would skip
// Other logic
});
Let me know if it helps or not.
Instead of using two array indexes, use one object, var bn={};, add the two entries, bn.breakingTitle=breakingNews.title.toUpperCase(); and bn.breakingAbstract=breakingNews.abstract; then one push newsWireTemp.push(bn); so each entry in newsWire is more like newsWire[i].breakingTitle and newsWire[i].breakingAbstract.
One way to do it:
Fiddle: http://jsfiddle.net/q18dv4wr/
HTML:
<div id="test1">odds:</div>
<div id="test2">evens:</div>
JS:
var someData = [0,1,2,3,4,5,6,7,8,9,10];
var div1 = $('#test1');
var div2 = $('#test2');
$.each(someData,
function (index, value) {
if (index % 2 == 0) {
return;
}
else {
div1.append(' ' + value);
}
}
);
$.each(someData,
function (index, value) {
if (index % 2 != 0) {
return;
}
else {
div2.append(' ' + value);
}
}
);
EDIT: Seems I posted a moment too late. Someone else gave same idea already. =] Oh well.
You could do this:
$text.html(items[i]+ ": " +items[(i+=1)]);
But personally, I would push the breakingNews object into the array instead of having a different index for each property:
$(document).ready(function() {
var newsWire = [];
function loadNewswire() {
return $.getJSON('http://api.nytimes.com/svc/news/v3/content/all/all.json',
{'api-key': 'XXXXXXXXXXXXXXXXXXX'},
function(data) {
console.log(data)
var newsWireTemp = [];
for (var i = 0; i < data.results.length; i++) {
newsWireTemp.push(data.results[i]);
}
newsWire = newsWireTemp;
});
}
loadNewswire().done(function () {
var items = newsWire;
$text = $('#newswiretxt span'),
delay = 10; //seconds
function loop (delay) {
$.each(items, function (i, elm){
$text.delay(delay*1E3).fadeOut();
$text.queue(function(){
$text.html(items[i].title.toUpperCase()+ ": " +items[i].abstract);
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if (i == items.length -1) {
loop(delay);
}
$text.dequeue();
});
});
}
console.log(items.length);
loop(delay);
});
});
Try using .append() , checking if items[i + 1] is defined before appending items[i + 1] , else return empty string
$text.append(items[i] + (!!items[i+1] ? ":" + items[i+1] + " ": ""))
var items = "abcdefg".split("")
$.each(items, function(i, item) {
$("body").append(items[i] + (!!items[i+1] ? ":" + items[i+1] + " ": ""))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I'm trying to write a function that takes a large array and iterates up and down it in a set number of chunks via a previous and next button. I have the next button working fine but cannot get it to reverse the array the same way I go forward. Here's what I have:
Javscript
success: function(data) {
var body = data;
console.log(body.length);
//body/data is a string
var text = body.split(' ');
text.chunk = 0; text.chunkSize = 15;
var next = true;
var increment = function(array,next) {
if (array.chunk < array.length) {
var slice = array.slice(
array.chunk,
Math.min(array.chunk + array.chunkSize, array.length));
var chunk = slice.join(" ");
if (next) {
array.chunk += array.chunkSize;
$( '#test' ).html('<p>' + chunk + '</p>');
}
else {
var slice = array.slice(
array.chunk,
Math.min(array.chunk+array.chunkSize, array.length));
array.chunk -= array.chunkSize;
$( '#test' ).html(chunk);
}
}
}
$("#prev").click(function() {
increment(text);
});
$("#button").click(function() {
increment(text, next);
});
}
success: function(data) {
var body = data;
console.log(body.length);
//body/data is a string
var text = body.split(' ');
text.chunk = 0; text.chunkSize = 15;
var increment = function(array,next) {
if(next) {
array.chunk = Math.min(array.chunk + array.chunkSize, array.length);
} else {
array.chunk = Math.max(array.chunk - array.chunkSize, 0);
}
var slice = array.slice(
array.chunk,
Math.min(array.chunk + array.chunkSize, array.length));
var chunk = slice.join(" ");
}
$("#prev").click(increment(text,false));
$("#button").click(increment(text, true));
}
Is this what you need? Fastly coded, and without testing so use with caution.
Okay, so first of all I really suggest breaking up your code. It looks like this is a response back from a server. I would in the response from the server, parse the data just like you are (side note, why don't you just return json from the server?) but use a call back to handle pagination.
var returnData = data.split(' ');
addPagination(returnData);
Under addPagination I would handle the DOM manipulation:
function addPagination(array) {
$('#container').show();
var incremental = incrementArray(array);
var responseSpan = $('#response');
$('#previous').click(function() {
incremental.previous();
showText();
});
$('#next').click(function() {
incremental.next();
showText();
});
showText();
function showText() {
responseSpan.text(incremental.array.join(', '));
}
}
But to handle the actual shifting of the array, I would use some function outside of your own. This uses Object Oriented JavaScript, so it is a bit more complex. It stores the original array in memory, and has 2 methods (next, previous), and has 1 attribute (array):
function incrementArray(array) {
_increment = 2;
var increment = _increment < array.length ? _increment : array.length;
var index = -2;
this.next = function () {
var isTopOfArray = index + increment > array.length - increment;
index = isTopOfArray ? array.length - increment : index + increment;
this.array = array.slice(index, index + increment);
return this.array;
};
this.previous = function () {
var isBottomOfArray = index - increment < 0;
index = isBottomOfArray ? 0 : index - increment;
this.array = array.slice(index, index + increment);
return this.array;
};
this.next();
return this;
}
To test it, use this jsFiddle.