Limiting Pagination using Javascript - javascript

I have a web app that uses OMDB API which fetches all the related results that matches the title of a Movie searched by the user.
So for example the user searched for "Star Wars" the API will then return 483 results, I managed to make a pagination for it but it shows all the pages from 1-48 and what I'm trying to figure out is how can I only show pages [1,2,3,4,5,6,7...49(ending page)], then change that pagination to [2,3,4,5,6,7,8...49] and so on.
Heres the code for it:
<input type="text" class="form-control" id="title" name="title" placeholder="Movie Title...">
<button onclick="callOMDB(document.getElementById('title').value)" class="btn btn-primary">Search</button>
<div id="page" class="page">
<nav aria-label="Page navigation example">
<ul class="pagination" id="pagination">
</ul>
</nav>
</div>
<div id="info">
</div>
function callOMDB(x){
var poster = document.getElementById("info");
var page = document.getElementById("pagination");
var search = x;
var searchLink = 'https://www.omdbapi.com/?i=tt3896198&apikey=123456&s='+encodeURI(x);
$.getJSON(searchLink).then(function(response){
poster.innerHTML = '';
page.innerHTML = '';
var length = response.Search.length;
for(var i = 0; i < length; i++){
var yr = response.Search[i].Year;
var title = response.Search[i].Title;
poster.innerHTML += "<p>Year: "+yr+"</p><p>Title: "+title+"</p>";
}
var pageNo = response.totalResults/10;
var i = 0;
for(i = 1; i < pageNo; i++){
page.innerHTML += '<li class="page-item"><a onclick="nextPage('+i+',\''+search+'\')" class="page-link" href="#">'+i+'</a></li>';
}
});
}

You can use slice to get slice of the entire result and display that. For the purpose of demo I just shown you only. and results are just numbers. The array can be anything. Important things is slice to get parts of results you want and display them.
After as you click through you move the start and end positions
const resultsList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // This could be results / or page numbers
const maxResults = 9;
let upperPageIndex = maxResults;
let currentPageIndex = 0;
let resultsToDisplay = resultsList.slice(currentPageIndex , upperPageIndex); // slice(startIndex, endIndex);
console.log(resultsToDisplay)
// if currentPageIndex = 2 then show 2 more as you go through
upperPageIndex += 1; // You can make 2 a constant if needed
currentPageIndex += 1;
resultsToDisplay = resultsList.slice(currentPageIndex , upperPageIndex);
console.log(resultsToDisplay)

I used the paramter page in the omdbapi and that is my code
JS
window.addEventListener('DOMContentLoaded', function () {
const posterContainer = document.getElementById("info");
const pageContainer = document.getElementById("pagination");
const titleInput = document.getElementById('title');
const searchBtn = document.getElementById('searchBtn');
const searchLink = 'https://www.omdbapi.com/?i=tt3896198&apikey=56fbcd03';
searchBtn.addEventListener('click', () => {
getData(titleInput.value);
});
// event delegation
$('body').on('click', '.page-link', function (e) {
e.preventDefault();
getData(titleInput.value, this.id);
});
function getData(keyword, page = 1) {
$.getJSON(`${searchLink}&page=${page}&s=${keyword}`).then(function (response) {
posterContainer.innerHTML = '';
pageContainer.innerHTML = '';
var length = response.Search.length;
for (var i = 0; i < length; i++) {
var yr = response.Search[i].Year;
var title = response.Search[i].Title;
posterContainer.innerHTML += "<p>Year: " + yr + "</p><p>Title: " + title + "</p>";
}
var pageNo = response.totalResults / 10;
var i = 0;
for (i = 1; i < pageNo; i++) {
pageContainer.innerHTML += `<li class="page-item" ><a class="page-link" id="${i}" href="#">${i}</a></li>`;
}
});
}
});
HTML
<input type="text" class="form-control" id="title" name="title" placeholder="Movie Title...">
<button id="searchBtn" class="btn btn-primary">Search</button>
<div id="page" class="page">
<nav aria-label="Page navigation example">
<ul class="pagination" id="pagination">
</ul>
</nav>
</div>
<div id="info">
</div>

Related

Messing up the dynamic dropdown. What am I doing wrong?

I am trying to add dropdown list dynamically to a WebApp using google appscript. I wrote a few lines of javascript code in the client side to communicate the server side to fetch the data from google-sheets. After a lot of trying, I'm somewhat successful. However, it looks like, whenever I click on the "Add Product" button, for first 1-2 times the array from which the dropdown is generated is empty. As a result the dropdown remains blank. However after 1 or 2 blank dropdowns the it starts working as it's suppose to.
What am I doing wrong ?
I have 3 files-
form.html
code.gs
js_script.html
Link to the google sheet
Content of form.html-
<body>
<div class="container">
<div class = "row">
<h1>Order Form</h2>
</div> <!-- end of row -->
<div class = "row">
<input id="orderno" type="text" class="validate">
<label for="orderno">Order Number</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientname" type="text" class="validate">
<label for="clientname">Client Name</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientaddr" type="text" class="validate">
<label for="clientaddr">Client Address</label>
</div> <!-- end of row -->
<div class = "row">
<input id="clientphone" type="text" class="validate">
<label for="clientphone">Client Phone Number</label>
</div> <!-- end of row -->
<div class = "row">
<input id="ordertype" type="text" class="validate">
<label for="ordertype">Order Type</label>
</div> <!-- end of row -->
<div id="productsection"></div>
<div class = "row">
<button id="addproduct">Add Product</button>
</div> <!-- end of row -->
<div class = "row">
<button id="submitBtn">Submit</button>
</div> <!-- end of row -->
</div> <!-- End of "container" class -->
<?!= include("js_script"); ?>
</body>
Content of code.gs
const ssID = "1YKZYgKctsXU3DKTidVVPUhmPXUkzjjocaiMz1S76JAE";
const ss = SpreadsheetApp.openById(ssID);
function doGet(e){
Logger.log(e);
return HtmlService.createTemplateFromFile("form").evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function appendDataToSheet(userData){
const ws = ss.getSheetByName("orders");
ws.appendRow([new Date(), userData.orderNumber, userData.clientName, userData.clientAddress, userData.clientPhone, userData.orderType, userData.products].flat());
}
function getOptionArray(){
const ws = ss.getSheetByName("product_list");
const optionList = ws.getRange(2, 1, ws.getRange("A2").getDataRegion().getLastRow() - 1).getValues()
.map(item => item[0]);
return optionList;
}
function logVal(data){
Logger.log(data);
}
Content of js_script.html
<script>
let counter = 0;
let optionList = [];
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
function addInputField(){
counter++;
// The idea is, everytime when "add product" button is clicked, the following element must be added to the "<div id="productoption></div>" tag.
// <div class="row">
// <select id="productX">
// <option>option-X</option>
// </select>
// </div>
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(updateOptionList).getOptionArray();
google.script.run.logVal(optionList); // This is just to test the optionList array if it's updated or not
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
function updateOptionList(arr){
optionList = arr.map(el => el);
}
</script>
About your current issue of However, it looks like, whenever I click on the "Add Product" button, for first 1-2 times the array form which the dropdown is generated is empty. As a result the dropdown remains blank. However after 1 or 2 blank dropdowns the it starts working as it's suppose to., when I saw your script, I thought that the reason for your issue might be due to that google.script.run is run with the asynchronous process. If my understanding is correct, how about the following modification?
In this case, your js_script.html is modified.
Modified script:
<script>
let counter = 0;
// let optionList = []; // Removed
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
// Modified
function addInputField(){
counter++;
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(arr => {
const optionList = updateOptionList(arr);
google.script.run.logVal(optionList);
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}).getOptionArray();
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
// Modified
function updateOptionList(arr){
return arr.map(el => el); // I cannot understand this mean.
}
</script>
or, in this case, updateOptionList might not be required to be used as follows.
<script>
let counter = 0;
// let optionList = []; // Removed
document.getElementById("submitBtn").addEventListener("click", writeDataToSheet);
document.getElementById("addproduct").addEventListener("click", addInputField);
// Modified
function addInputField(){
counter++;
const newDivTag = document.createElement('div');
const newSelectTag = document.createElement('select');
newDivTag.class = "row";
newSelectTag.id = "product" + counter.toString();
google.script.run.withSuccessHandler(optionList => {
google.script.run.logVal(optionList);
for(let i = 0; i < optionList.length; i++){
const newOptionTag = document.createElement('option');
newOptionTag.textContent = optionList[i];
newOptionTag.value = optionList[i];
newSelectTag.appendChild(newOptionTag);
}
newDivTag.appendChild(newSelectTag);
document.getElementById('productsection').appendChild(newDivTag);
}).getOptionArray();
}
function writeDataToSheet(){
const userData = {};
userData.orderNumber = document.getElementById("orderno").value;
userData.clientName = document.getElementById("clientname").value;
userData.clientAddress = document.getElementById("clientaddr").value;
userData.clientPhone = document.getElementById("clientphone").value;
userData.orderType = document.getElementById("ordertype").value;
userData.products = [];
for(let i = 0; i < counter; i++) {
let input_id = "product" + (i+1).toString();
userData.products.push(document.getElementById(input_id).value);
}
google.script.run.appendDataToSheet(userData);
}
</script>
Note:
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Reference:
Class google.script.run (Client-side API)

Getting an Uncaught TypeError: Cannot set property 'onclick' of null with <script> at the end

I've looked at previous questions like this and cannot find the answer to my problem. I am working in javascript creating a checkout screen and I have two onclicks for two different html files but when I go to the html file for both it says that the other onclick is null. I have tried window.load and moving the script to the bottom of the
var cart = [];
var search = document.getElementById("addItem");
let placement = 0;
var cartElement = document.getElementById("showCart");
var cartTotal = document.getElementById("totalCart");
search.onclick = function(e) {
var userInput = document.getElementById("query").value;
var cartHTML = "";
e.preventDefault();
placement = 0;
for (i = 0; i < menu.length; i++) {
if (menu[i][0].includes(userInput)) {
cart.push(menu[i]);
placement++;
}
}
if (placement == 0) {
alert("Menu option not included. Please try again.");
}
cart.forEach((item, Order) => {
var cartItem = document.createElement("span");
cartItem.textContent = item[0] + " (" + item[1] + ")";
cartHTML += cartItem.outerHTML;
});
cartElement.innerHTML = cartHTML;
}
window.onload = function() {
var checkout = document.getElementById("addCartButton");
checkout.onclick = function(event) {
cart.forEach()
var cartTotalHTML = "";
event.preventDefault();
cart.forEach(Item, Order => {
var totalInCart = 0;
var writeCart = document.createElement("span");
totalInCart += Order[1];
});
writeCart.textContent = cartTotal += item[1];
cartTotalHTML = writeCart.outerHTML;
cartTotal.innerHTML = cartTotalHTML;
console.log(cartTotal);
}
}
<h3>Search for items in the menu below to add to cart</h3>
<form id="searchMenu">
<input type="search" id="query" name="q" placeholder="Search Menu..."></inpuut>
<input type = "Submit" name= "search" id="addItem" ></input>
</form>
<h4>Your cart: </h4>
<div class="Cart">
<div id="showCart"></div>
</div>
<script src="Script.js"></script>
<h4>Cart</h4>
<button id='addCartButton' class="Cart">Add Cart</button>
<div class="ShowCart">
<div id="totalCart"></div>
</div>
<script src="Script.js"></script>

Need help updating dropdowns in HTML Web Apps using Google Apps Script

This is my first time posting here so please let me know if I need to edit anything.
I am working on a program that runs through data that is imported in google sheets, displays one "row" of data in an HTML web app where the user can then assign an account number (found in a dropdown list) to the item that is displayed, and move on to the next row in the data. Each item in the data has a ID number and based on this ID number and the description of the data, the user selects the appropriate account number in the list to assign to the data.
The problem is that there are hundreds of these account numbers and having the users scroll/search through these to find the correct account will be very tedious.
The good news is that only certain accounts can be assigned to an ID number. I can effectively sort the dropdown list to only show accounts that can be assigned to the current ID therefore making the user's job much easier and much quicker.
However, I have no idea how to update the dropdown after the item loads on the html page. I am able to get the current ID number and sort through the accounts, I just am not able to update the drop down.
I have pasted the code.gs and the html/javascript code.
I did not include all of the code in code.gs file as some of it has nothing to do with my problem.
I am using Materialize CSS.
Code.gs:
var url = "hidden";
var ss = SpreadsheetApp.openByUrl(url);
var masterWS = ss.getSheetByName("Master List");
var items = [];
var Route = {};
Route.path = function (route, callback){
Route[route] = callback;
}
function doGet(e) {
Route.path("summary", summaryPage);
Route.path("edit", editPage);
if(Route[e.parameters.v]){
return Route[e.parameters.v]();
} else {
return editPage();
}
}
function summaryPage(){
var tmp = HtmlService.createTemplateFromFile("summary");
var sumList = showSummary();
tmp.summaryList = sumList;
return tmp.evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function editPage(){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("GLAccounts");
// Create drop down and populate with all account options
var SSassetList = ws.getRange(2,1, getLastRowSpecial("A", "GLAccounts"),1).getValues();
var htmlAssetList = SSassetList.map(function (r){return '<option>' + r[0] + '</option>';}).join('');
var tmp = HtmlService.createTemplateFromFile("page");
tmp.assetList = htmlAssetList;
return tmp.evaluate();
}
function calculateTotalEntries(){
//Logger.log("Done: " + done);
var lastRow = masterWS.getLastRow();
var totalEntries = 0;
var i = lastRow;
while (masterWS.getRange(i, 1).getValue() != "Transaction Date"){
i--;
totalEntries++;
}
masterWS.getRange("R1").setValue(totalEntries);
masterWS.getRange("R2").setValue(lastRow);
}
function userClicked(userInfo){
var r = masterWS.getRange("P1").getValue();
var GLAccount = userInfo.act;
var lastRow = masterWS.getRange("R2").getValue();
var totalEntries = masterWS.getRange("R1").getValue();
if(!(masterWS.getRange("P3").getValue())){
//Logger.log("Done parsing. Items length: " + items.length);
if(r <= totalEntries - 1 ){
masterWS.getRange("P4").setValue(lastRow - totalEntries + 1 + r);
if(masterWS.getRange("P1").getValue() != 0){
masterWS.getRange(lastRow - totalEntries + r, 8).setValue(GLAccount);
}
r = r + 1;
masterWS.getRange("P1").setValue(r);
} else {
//Logger.log("Last one");
masterWS.getRange("P3").setValue(true);
masterWS.getRange(lastRow, 8).setValue(GLAccount);
//return Error;
resetCounters();
calculateChange();
}
}
}
function showItem(){
var row = masterWS.getRange("P4").getValue();
return "Item: " + masterWS.getRange(row,5).getValue() + "; Date: " + slice(masterWS.getRange(row,1).getValue(), 13) + "; ID: "+ masterWS.getRange(row,6).getValue();
}
function getData(){
var row = masterWS.getRange("P4").getValue();
var id = "";
id = masterWS.getRange(row,6).getValue().toString();
var availAccounts = [];
var IDSheet = ss.getSheetByName("MerchantCodes");
var lastIDRow = IDSheet.getLastRow();
var lastIDCol = 0;
var currentRow = 0;
for(var i = 6; i < lastIDRow; i++){
if(IDSheet.getRange(i, 1).getValue().toString() == id){
currentRow = i;
break;
}
}
//Logger.log("ID: " + id + " # row " + i);
for( var j = 1; j < 10; j++){
if(IDSheet.getRange(currentRow,j).getValue() != ""){
lastIDCol = j;
}
}
//Logger.log("Last Column for row " + i + ": " + lastIDCol);
for(var r = lastIDCol - (lastIDCol - 3) + 1; r < lastIDCol+1; r++){
//Logger.log("Account: " + IDSheet.getRange(currentRow,r).getValue());
availAccounts.push(IDSheet.getRange(currentRow,r).getValue());
}
return availAccounts;
}
function resetCounters(){
masterWS.getRange("P1").setValue(0);
masterWS.getRange("P3").setValue(false);
masterWS.getRange("P4").setValue("");
masterWS.getRange("P5").setValue("");
masterWS.getRange("P6").setValue("");
}
function getLastRowSpecial(col, sheetName){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName(sheetName);
var data = ws.getRange(col + "2:" + col).getValues();
var lastRowData = data.filter(String).length;
return lastRowData;
}
}
HTML:
The item that is displayed in the web app, which changes based on the data, is in the tags.
The dropdown list is populated using the tags. The data in those tags comes from the doGet()and editPage() functions in the code.gs file.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<?!= include("page-css"); ?>
</head>
<body>
<div class = "container"> <!-- Open container -->
<div> <!-- Open row -->
<label>Item</label>
<p><span id="current"></span></p>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="btn2" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Start</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<div class="input-field col s6">
<select id="glAcc">
<option disabled selected>Choose your GL Account</option>
<?!= assetList; ?>
</select>
<label>GL Account</label>
</div>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="updDrop" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Update Dropdown
<i class="material-icons right">send</i>
</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<button id="btn" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div> <!-- Close row -->
<div class ="row"> <!-- Open row -->
<a href="<?= ScriptApp.getService().getUrl(); ?>?v=summary" id="summary" class="btn waves-effect waves-light red darken-3" type="submit" name="action">Go to Summary Page
<i class="material-icons right">arrow_forward</i>
</a>
</div> <!-- Close row -->
</div> <!-- Close container -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include("page-js"); ?>
</body>
</html>
HTML JS Code:
<script>
document.addEventListener('DOMContentLoaded', function(){
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
document.addEventListener('DOMContentLoaded', reset);
document.getElementById("btn").addEventListener("click",doStuff);
document.getElementById("btn2").addEventListener("click",doStuff);
document.getElementById("sumBtn").addEventListener("click", summary);
document.getElementById("updDrop").addEventListener("click", updateDropdown);
function doStuff(){
var userInfo = {};
userInfo.act = document.getElementById("glAcc").value;
google.script.run.withSuccessHandler(findItem).userClicked(userInfo);
//findItem();
//google.script.run.getLength();
// Reset dropdown
var myApp = document.getElementById("glAcc");
myApp.selectedIndex = 0;
M.FormSelect.init(myApp);
}
function reset(){
google.script.run.resetCounters();
google.script.run.calculateTotalEntries();
document.getElementById("current").textContent = "Click the Start Button";
}
function updateDropdown(){
google.script.run.withSuccessHandler(updateSelect).getData();
}
function updateSelect(vA){
var select = document.getElementById("glAcc");
select.options.length = 0;
vA.unshift("");
for(var i = 1; i < vA.length; i++){
select.options[i] = new Option(vA[i], vA[i]);
}
}
function findItem(){
google.script.run.withSuccessHandler(changeItem).showItem();
}
function changeItem(item){
document.getElementById("current").textContent = item;
//document.getElementById("options"). = "<option>1</option><option>2</option>";
}
function summary(){
google.script.run.withSuccessHandler(findSummary).calculateChange();
}
function findSummary(){
google.script.run.withSuccessHandler(changeSummary).showSummary();
}
function changeSummary(summary){
document.getElementById("sumText").textContent = summary;
}
</script>
Basically to summarize, I want the dropdown options to update as the item displayed also updates. If it is not possible to update at the same time, I can add a button which will update the dropdown once clicked.
I do not want to share the whole code/spreadsheet to everyone, but if you want access please message me and I can share it to you.
Thank you.
welcome to the SO community.
I believe the problem is not in the Apps Script.
When you use Materialize Select you need to re-init it.
This is the function I found in my codebase, it should help you:
function fillMaterializeSelect(elSelect, data) {
elSelect.options.length = 0;
for (let i = 0; i < data.length; i++) {
const dataElement = data[i];
const option = document.createElement("option");
option.value = dataElement.value;
option.text = dataElement.text;
elSelect.add(option);
}
M.FormSelect.init(elSelect);
}
Here is a JavaScript function I use a lot for updating <select>.
function updateSelect(vA,id){
var id=id || 'sel1';
var select = document.getElementById(id);
select.options.length = 0;
vA.unshift("");
for(var i=1;i<vA.length;i++)
{
select.options[i] = new Option(vA[i],vA[i]);//one is the value and the other is the display value
}
}
You retrieve the data with a
gooogle.script.run
.withSuccessHandler(updateSelect)
.getData();

HTML and Javascript search result pagination - limit the number of result pages showing

Using HTML and javascript I have some basic search result pagination which, although works, if there are hundreds of results, I can end up with pagination looking like this:
I would like to limit this to show only 1 - 10, then 11 - 10 etc, can anyone direct me to an example of how to do this?
<div class="row igs-learning-paths-pagination-row">
<div class="col-12 d-flex justify-content-center" >
<ul class="pagination pagination-info">
<li class="page-item">
<a href="javascript:void(0)" onclick="displayPreviousPage()" class="igs-learning-paths-pagingation-text igs-text-uppercase">
#Umbraco.GetDictionaryValue("Common Prev", "Prev..").ToUpper()
</a>
</li>
#for (int i = 0; i <= #Model.Results.Count() / numberPerPage; i++)
{
<li class="#(i == 0 ? "active" : null) page-item non-generate-page-item" id="page-list-item-#(i)" style="border-radius:16px;">
<a class="page-link" id="page-number-#(i)" href="javascript:void(0)" onclick="displayPages(#(i))">#(i + 1)</a>
</li>
}
<li class="page-item" alt="Go forward a page" title="Go forward a page">
<a href="javascript:void(0)" alt="Go forward a page" title="Go forward a page"
onclick="displayNextPage()"
class="igs-learning-paths-pagingation-text igs-text-uppercase search-result-margin">
#Current.UmbracoHelper.GetDictionaryValue("Common Next", "Next..").ToUpper()
</a>
</li>
</ul>
</div>
</div>
<script>
var numberPerPage = #numberPerPage;
var totalResults = #Model.Results.Count();
var maxPage = Math.floor(totalResults / numberPerPage);
var currentPage = 0;
var previousPage = 0;
function displayNextPage() {
if (currentPage == maxPage) return;
currentPage = currentPage + 1
displayPages(currentPage);
}
function displayPreviousPage() {
if (currentPage == 0) return;
currentPage = currentPage - 1
displayPages(currentPage);
}
function displayPages(pageToDisplay) {
$(".page-search-hider").hide();
currentPage = pageToDisplay;
if (!pageToDisplay) {
pageToDisplay = 0
}
else {
var skip = pageToDisplay * numberPerPage;
pageToDisplay = skip+1;
}
var newNumberPerPage = numberPerPage;
document.getElementById("page-list-item-" + previousPage).classList.remove("active")
previousPage = currentPage;
document.getElementById("page-list-item-" + currentPage).classList.add("active")
for (var i = 0; i <= newNumberPerPage; i++) {
var result = pageToDisplay + i;
$("#pageId-" + result).show();
$("#pageId-" + #(pageIdCount)).hide();
}
}
const pageNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const maxPageLimit = 5;
let upperPageIndex = maxPageLimit;
let currentPageIndex = 0;
let displayPages = pageNumbers.slice(currentPageIndex , upperPageIndex); // slice(startIndex, endIndex);
console.log(displayPages)
// if currentPageIndex = 2 then show 2 more as you go through
upperPageIndex += 2; // You can make 2 a constant if needed
currentPageIndex += 2;
displayPages = pageNumbers.slice(currentPageIndex , upperPageIndex);
console.log(displayPages)
REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

Why does my value keep returning as "NaN"?

Here is the link to the jsbin.
I was almost finished with my project (I thought I was) and then I tested it out. It is supposed to add buttons with the chosen title of the task and the number of points it awards. Every time the button is clicked the points would be added on to the "Points" section and every 500 points my "Level" would increase.
Upon finishing it, it worked. Then I went to clear the localStorage since that's what I used to save the information, but I wanted to start over. When I did that, the 'Points' section, or 'results' value, keeps returning as "NaN". The code is exactly the same as it was when it worked. Can someone please tell me how to fix this problem, thank you in advance.
Here is the code. (Used bootstrap for CSS)
HTML
<center>
<br>
<h2> Add task </h2>
<div class='well' style='width:500px' id="addc">
<div id="addc">
<input class='form-control' style='width:450px' id="btnName" type="text" placeholder="New Task" /><br>
<input class='form-control' style='width:450px' id="btnPoints" type="text" placeholder="Points" /><br>
<button id="addBtn">Add</button>
</div> </div>
<div class='well' style='width:230px' id="container">
</div>
<hr style="width:400px;">
<h3>Points </h3>
<div id="result">0</div>
</div>
<hr style="width:400px;">
<div style="width:400px;">
<h3>Level
<p id='lvl'>0</p>
</div>
<hr style="width:400px;">
</center>
JavaScript
var res = document.getElementById('result');
res.innerText = localStorage.getItem('myResult');
var level = document.getElementById('lvl');
level.textContent = localStorage.getItem('myLevel');
var btns = document.querySelectorAll('.btn');
for(var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
addToResult(this.getAttribute('data-points'));
this.parentNode.removeChild(this.nextElementSibling);
this.parentNode.removeChild(this);
});
}
var addBtn = document.getElementById('addBtn');
addBtn.className = "btn btn-default";
addBtn.addEventListener('click', function() {
var container = document.getElementById('container');
var btnName = document.getElementById('btnName').value;
var btnPoints = parseInt(document.getElementById('btnPoints').value);
if(!btnName)
btnName = "Button ?";
if(!btnPoints)
btnPoints = 50;
var newBtn = document.createElement('button');
var newPnt = document.createElement('span');
newBtn.className = 'btn btn-danger';
newBtn.innerText = btnName;
newBtn.setAttribute('data-points', btnPoints);
newBtn.addEventListener('click', function() {
addToResult(this.getAttribute('data-points'));
this.parentNode.removeChild(this.nextElementSibling);
this.parentNode.removeChild(this);
});
newPnt.className = 'label';
newPnt.innerText = "+" + btnPoints;
container.appendChild(newBtn);
container.appendChild(newPnt);
});
function addToResult(pts) {
var result = document.getElementById('result');
result.innerText = parseInt(result.innerText) + parseInt(pts);
var lvl = 0;
var a = 100;
while (result.innerText > 5*a) {
lvl+=1;
a+=100;
}
document.getElementById('lvl').innerText = lvl;
var res = document.getElementById('result');
localStorage.setItem("myResult", res.innerText);
var level = document.getElementById('lvl');
localStorage.setItem("myLevel", level.textContent);
}
You were parsing result.innerText as a number, but its value, initially, was actually either NaN or nothing, both which end up being NaN. One fix is to just check if it parsed to a number, and if it didn't, fall back to 0.
I just basically changed that and removed some getElementByIds that, in my opinion, were redundant, check the addToResult function:
http://jsfiddle.net/owc26a0p/1/
function addToResult(pts) {
// NaN is falsy, so you can just use || to make a fallback to 0
var result = parseInt(resDiv.innerText, 10) || 0,
lvl = 0,
a = 100;
result = result + parseInt(pts, 10) || 0;
while (result > 5 * a) {
lvl += 1;
a += 100;
}
resDiv.innerText = result;
levelDiv.innerText = lvl;
localStorage.setItem("myResult", result);
localStorage.setItem("myLevel", levelDiv.textContent);
}
I ended up using jsFiddle since I couldn't always get jsBin to save my changes. Good luck.

Categories