I have a problem. I want to make page like this
https://www.idntimes.com/korea/kpop/matthew-suharsono/rekomendasi-lagu-dreamcatcher-untuk-pengantar-tidur-c1c2/5
I already can add the page number at the end of the URL. But when I'm in testing.html/4 and I want to refresh it, the page does not appear and shows the error "Cannot get testing.html/4". How to make it can refresh like usual?
Here's my code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<style>
.spinner {
display: none;
}
</style>
</head>
<body style="font-size: 60px;">
<div class="news-content">
</div>
<div class="loading">
<p>Loading Please Wait</p>
</div>
<script>
function loadData(count) {
fetch('/index.json')
.then(res => res.json())
.then(json => {
if (count < json.length) {
let text = document.createElement('p');
text.innerText = json[count].text;
document.querySelector('.news-content').append(text);
if (count > 0) {
history.pushState(null, null, `/testing.html/${count}`)
}
}
});
}
let count = 0
window.addEventListener('load', loadData(count));
window.addEventListener('scroll', () => {
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
count += 1;
loadData(count)
}
})
</script>
</body>
</html>
It seems to me that you are using pure HTML files in an HTTP/HTTPS local server. When you are having this kind of instance of the server you are not dynamically generating pages because you don't have any server side setup behind the HTML file.
You can do this using queries and since your app doesn't contain any server backend use client Javascript to create a pagination concept.
Instead of having a route type system ( which is usually handled by controller on the backend ) use query system:
Instead of:
/testing.html/{PAGE_NUMBER}
Use:
/testing.html?page={PAGE_NUMBER}
To get page query in Javascript, use the following function:
function getPageNumber() {
const urlParams = new URLSearchParams(window.location.search);
const page = urlParams.get('page');
return page;
}
Then create a function where you would paginate the data ( assuming the data is an array ):
function paginateData(data, resultsPerPage, pageNumber) {
// Chunk the data based on the limit
let result = data.reduce((rows, key, index) => (index % resultsPerPage == 0 ? rows.push([key]) : rows[rows.length-1].push(key)) && rows, []);
// Return the current page with index calculation
return result[pageNumber - 1];
}
And the final code should be something like this:
function getData(data) {
const RESULTS_PER_PAGE = 2;
const currentPageNumber = Number(getPageNumber());
const paginatedData = paginateData(data, RESULTS_PER_PAGE, currentPageNumber);
// If paginated data is undefined return first page
if (!paginatedData) {
/*
You can even redirect to /testing.html?page=1
*/
return paginateData(data, RESULTS_PER_PAGE, 1);
}
return paginatedData;
}
All you are left with is to provide the function getData with an data parameter resembling an array type.
Related
I'm trying to import RxJs in a small javascript project using "import" in my script file but I keep on getting the following error:
Subscriber.js:10 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'rxjs')
This is what my html file looks like:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./styles/style.css">
<title>Load RxJs using import</title>
</head>
<body>
<h1>Importing RxJs Lib</h1>
<div>
<h1 id="info">'loading ...'</h1>
</div>
<!-- <script src="https://unpkg.com/rxjs#7.5.7/dist/bundles/rxjs.umd.js"></script> -->
<script src="./js/script.js"></script>
</body>
</html>
The script file looks like this:
// const updateUI = text => document.querySelectorAll('#info')[0].innerText = "finished";
const loadRxJsLib = async () => {
await import('https://unpkg.com/rxjs#7.5.7/dist/bundles/rxjs.umd.js');
}
document.addEventListener('DOMContentLoaded', (event) => {
loadRxJsLib();
});
document.addEventListener('readystatechange', (event) => {
if (document.readyState === 'complete') {
const { range } = rxjs;
const { filter, map } = rxjs.operators;
range(1, 200)
.pipe(
filter((x) => x % 2 === 1),
map((x) => x + x)
)
.subscribe((x) => console.log(x))
}
});
Any idea why it's not working? any comment will be highly appreciated
After researching a little bit more, I found out that it might be related to the CDN. I have tried the skypack CDN with the following URL
https://cdn.skypack.dev/pin/rxjs#v7.5.7-j3yWv9lQY9gNeD9CyX5Y/mode=imports/optimized/rxjs.js
...and I did not get the error anymore
I'm attempting to create a simple to-do list and I've encountered two problems:
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage.
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
Despite that, the items displayed from the input fields are from the previous localStorage, which no longer exists (I really hope this makes sense).
const inputEl = document.getElementById("inputEl")
const submitBtn = document.getElementById("submit")
const clearBtn = document.getElementById("clearBtn")
const todoListContainer = document.getElementById("todoList")
const taskContainer = document.querySelector(".task")
const cancelBtn = document.querySelector(".cancelBtn")
const doneBtn = document.querySelector(".doneBtn")
const errorMsg = document.querySelector(".error")
let localStorageContent = localStorage.getItem("tasks")
let tasksItem = JSON.parse(localStorageContent)
let tasks = []
function createTask() {
if (inputEl.value.length != 0) {
const newDiv = document.createElement("div")
newDiv.classList.add("task")
const newParagraph = document.createElement("p")
const newCancelBtn = document.createElement("button")
newCancelBtn.classList.add("cancelBtn")
newCancelBtn.textContent = "X"
const newDoneBtn = document.createElement("button")
newDoneBtn.classList.add("doneBtn")
newDoneBtn.textContent = "Done"
todoListContainer.appendChild(newDiv)
newDiv.appendChild(newParagraph)
newDiv.appendChild(newCancelBtn)
newDiv.appendChild(newDoneBtn)
//^^ Creating a container for a new task, with all its elements and assigning the classes^^
tasks.push(inputEl.value)
inputEl.value = ""
for (let i = 0; i < tasks.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasks))
newParagraph.textContent = JSON.parse(localStorageContent)[i]
}
errorMsg.textContent = ""
} else {
errorMsg.textContent = "You have to type something in!"
errorMsg.classList.toggle("visibility")
}
}
submitBtn.addEventListener("click", () => {
createTask()
})
clearBtn.addEventListener("click", () => {
localStorage.clear()
})
HTML code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script>
<title>To-do list</title>
</head>
<body>
<h2 class="error visibility"></h2>
<div id="todoList">
<h1>To-Do List</h1>
<input type="text" name="" id="inputEl" placeholder="Add an item!">
<button type="submitBtn" id="submit">Submit</button>
<button id="clearBtn">Clear list</button>
<div class="task">
</div>
</div>
</body>
</html>
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage
That is because you are rendering the HTML only after the click event and not on page load. To render the HTML for existing tasks stored in the localStorage you have to write a code that loops over your existing tasks in the tasksItem and applies the rendering logic to it.
I would suggest splitting the rendering code from your createTask() function and create a new function for it (for example renderTask()), then you can use it inside a loop on page load and also call the function once a new task is created in the createTask() function.
window.addEventListener('load', (event) => {
// Your read, loop and render logic goes here
})
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
That's because you are actually overriding the tasks in the localStorage. To keep existing tasks, you have to use your tasksItem variable instead of the blank tasks array to create your tasks in and save them to the localStorage.
So, instead of:
tasks.push(inputEl.value)
You would use:
tasksItem.push(inputEl.value)
The same goes for:
for (let i = 0; i < tasksItem.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasksItem))
// …
}
This question already has answers here:
addEventListener Executing Before Being Clicked
(2 answers)
Closed 2 years ago.
Can anyone help me with that- I am using fetch api here and this is linked to a button ,here I used fetch api for a get request, but the problem is that without clicking the button ,my data is fetched from the api.
When I clicked the button to fetch data first time, it works perfectly but after that on reload my data is fetched automatically without clicking button. what's the problem here and how to fix it?
easyhttp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>easy http</title>
</head>
<body>
<ol id="getRequestData">
</ol>
<button id="btn1">get</button>
<button id="btn2">post</button>
<button id="btn3">put</button>
<button id="btn4">delete</button>
<script src="easyHttpWithFetch.js"></script>
</body>
</html>
easyHttpWithFetch.js
document.getElementById("btn1").addEventListener("click",get("https://jsonplaceholder.typicode.com/posts"));
function get(url){
fetch(url)
.then(response => response.json())
.then((data) => {
let str = "";
data.forEach(element => {
str += '<li><ol type="a">';
for (const key in element) {
if (Object.hasOwnProperty.call(element, key)) {
const value = element[key];
str+= `<li>${value}</li>`;
}
}
str += '</ol></li>';
let getRequestData = document.getElementById("getRequestData");
getRequestData.innerHTML = str;
});
}).catch((err) => {
console.log(err);
});
}
The second parameter of the addEventListener() is the function name that we want to call when the click occurs. But you are currently trying to execute the get() method by passing the url parameter immediately.
That's why get() is first called initially when btn1 is attached to the click event.
To fix this, try to use the arrow function.
document.getElementById("btn1").addEventListener("click", () => get("https://jsonplaceholder.typicode.com/posts"));
function get(url) {
fetch(url)
.then(response => response.json())
.then((data) => {
let str = "";
data.forEach(element => {
str += '<li><ol type="a">';
for (const key in element) {
if (Object.hasOwnProperty.call(element, key)) {
const value = element[key];
str += `<li>${value}</li>`;
}
}
str += '</ol></li>';
let getRequestData = document.getElementById("getRequestData");
getRequestData.innerHTML = str;
});
}).catch((err) => {
console.log(err);
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>easy http</title>
</head>
<body>
<ol id="getRequestData">
</ol>
<button id="btn1">get</button>
<button id="btn2">post</button>
<button id="btn3">put</button>
<button id="btn4">delete</button>
</body>
</html>
I am trying to implement an extension into my main code. I tried to copy the code and make my own but this didnt work or the extension was not visualised, I dont have a clue. This is the github page with the extension I would like to use: [link] (https://github.com/Autodesk-Forge/forge-rcdb.nodejs/tree/master/src/client/viewer.components/Viewer.Extensions.Dynamic/Viewing.Extension.IoT) Thank you in advance!
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<!-- The Viewer CSS -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/style.min.css" type="text/css">
<!-- Developer CSS -->
<style>
body {
margin: 0;
}
#MyViewerDiv {
width: 100%;
height: 100%;
margin: 0;
background-color: #F0F8FF;
}
</style>
</head>
<body>
<!-- The Viewer will be instantiated here -->
<div id="MyViewerDiv"></div>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/viewer3D.min.js"></script>
<!-- Developer JS -->
<script>
var viewerApp;
var options = {
env: 'AutodeskProduction',
getAccessToken: function(onGetAccessToken) {
//
// TODO: Replace static access token string below with call to fetch new token from your backend
// Both values are provided by Forge's Authentication (OAuth) API.
//
// Example Forge's Authentication (OAuth) API return value:
// {
// "access_token": "<YOUR_APPLICATION_TOKEN>",
// "token_type": "Bearer",
// "expires_in": 86400
// }
//
var accessToken = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Imp3dF9zeW1tZXRyaWNfa2V5In0.eyJjbGllbnRfaWQiOiJSRmcyZEh1TXFkemVuSjl2eng2ZWFScnhYRDczZ2RMMSIsImV4cCI6MTU2NzA3MjIxNywic2NvcGUiOlsiZGF0YTpyZWFkIiwiZGF0YTp3cml0ZSIsImRhdGE6Y3JlYXRlIiwiYnVja2V0OnJlYWQiLCJidWNrZXQ6Y3JlYXRlIl0sImF1ZCI6Imh0dHBzOi8vYXV0b2Rlc2suY29tL2F1ZC9qd3RleHA2MCIsImp0aSI6Ill0Ykozb0hxWDhIbGJMS0p2UDVkWWhEVEhPeUx1TXVxQWo4cnZSOW5LR2FIZmY4YmkweVQ4N2UzVXZvd2g0TWIifQ.Rq7TsewQlXl0VnSfzaR0bw7Vxgh4EOSf9xD9jqfg0b4';
var expireTimeSeconds = 60 * 30;
onGetAccessToken(accessToken, expireTimeSeconds);
}
};
let config3d = {
extensions: ['Autodesk.InViewerSearch']
};
var documentId = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6amFuc3NlbnNfMjcwODIwMTkvSUZDJTIwU2NoZXBlbmRvbWxhYW4ucnZ0';
Autodesk.Viewing.Initializer(options, function onInitialized(){
viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config3d);
viewerApp.loadDocument(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
});
function onDocumentLoadSuccess(doc) {
// We could still make use of Document.getSubItemsWithProperties()
// However, when using a ViewingApplication, we have access to the **bubble** attribute,
// which references the root node of a graph that wraps each object from the Manifest JSON.
var viewables = viewerApp.bubble.search({'type':'geometry'});
if (viewables.length === 0) {
console.error('Document contains no viewables.');
return;
}
// Choose any of the avialble viewables
viewerApp.selectItem(viewables[0].data, onItemLoadSuccess, onItemLoadFail);
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
function onItemLoadSuccess(viewer, item) {
console.log('onItemLoadSuccess()!');
console.log(viewer);
console.log(item);
// Congratulations! The viewer is now ready to be used.
console.log('Viewers are equal: ' + (viewer === viewerApp.getCurrentViewer()));
}
function onItemLoadFail(errorCode) {
console.error('onItemLoadFail() - errorCode:' + errorCode);
}
</script>
</body>
You will need to build this extension before you can use it - see this repo here to build the extensions separately.
But this extension is locked in with React so you will need to strip the React bits off before you can with your frameworkless plain old HTML.
We are working on a revamp of both RCDB and Extension Library just to isolate the extensions from unnecessary dependencies like React - will come back to update this answer once that's done.
I would like to redirect a user to a php page containing a form field after the user has viewed the three numbers after each other. I would like to also pass the index array to a php array for processing and storage.
Here's the code so far:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<title>Digit Span Backward</title>
<script src="jquery.min.js" type="text/javascript">
</script>
</head>
<body>
<p>Digit Span Backward - Javascript edition</p>
<script type="text/javascript" language="javascript">
function randomize(number)
{
var index = [];
for (var i = 0; i < number; i++)
{
index.push(Math.floor(Math.random()*10));
}
return index;
}
function showMessage(message)
{
$('p').html(message);
}
var i = 0;
function shuffle(list, i)
{
if (!(i >= 0))
{
i = 0;
}
setTimeout((function(msg)
{
i++;
return function()
{
if(i < list.length)
{
shuffle(list, i);
}
showMessage(msg);
}
})(list[i]), 1000);
}
</script>
<form>
<input type="button" onclick="shuffle(randomize(3))" value="Start Digit Span Backward">
</form>
</body>
</html>
Any ideas?
i am not a HTML 5 geek or a php professional but here is my suggestion
Can i suggest putting a hidden field in the page and then use the join method of the array to convert it to string splitted by what ever choice splitter like , and then set it to the hidden field value and pass it to the next page just give it a name
Example
JavaScript Function
function ArrayToStringSplitted(ary,splitter,hiddenfield)
{
var aryString= ary.join(spliter);
hiddenfield.value = aryString ;
}
HTML
just add the Hidden Field to the page
<input type='hidden' id="hdfld" name="hdfld" />
i think this will not work with the normal javascript redirection window.location = path
i think this will work with setting the form attributes the action to the location of the php page and the method to post
in there in the php page you can catch the hiddenfield value with $hiddenfield name and split it with the same splitter to return it to a array again
regards