EDIT
i was able to get it to work, but one problem now is, before it creates and additional empty item before showing other items.
NB the load on demand function works fine, but i don't know why an additional empty item is created. i guess there's an issue with my code
const viewModel = observableModule.fromObject({
_sourceDataItems: [],
dataItems: new ObservableArray(),
initDataItems: function () {
var url="https://adekunletestprojects.000webhostapp.com/skog/searchResults.php?search=" + encodeURIComponent("Adeyeye") + "&location=" + encodeURIComponent("Lagos");
fetch(url).then((response) => response.json()).then((res) => {
this._sourceDataItems = new ObservableArray(res.items);
this.dataItems.push(this._sourceDataItems);
}).catch((err) => {
var toast = Toast.makeText("Unable to load users");
toast.show();
});
},
addMoreItemsFromSource: function (chunkSize) {
console.log(this._sourceDataItems);
let newItems = this._sourceDataItems.splice(0, chunkSize);
this.dataItems.push(newItems);
},
onLoadMoreItemsRequested: function (args) {
console.log("---load more item---");
const that = new WeakRef(this);
const listView = args.object;
if (this._sourceDataItems.length > 0) {
setTimeout(function () {
that.get().addMoreItemsFromSource(10);
listView.notifyLoadOnDemandFinished();
}, 1500);
args.returnValue = true;
} else {
args.returnValue = false;
listView.notifyLoadOnDemandFinished(true);
}
},
});
Search-view-model.js
_sourceDataItems: new ObservableArray(),
dataItems: new ObservableArray(),
initDataItems: function () {
var url = "https://adekunletestprojects.000webhostapp.com/skog/searchResults.php?search=" + encodeURIComponent("Adeyeye") + "&location=" + encodeURIComponent("Lagos");
fetch(url).then((response) => response.json()).then((res) => {
this._sourceDataItems = res.items;
this.addMoreItemsFromSource(6);
}).catch((err) => {
alert(err.message);
});
},
addMoreItemsFromSource: function (chunkSize) {
console.log(this._sourceDataItems);
let newItems = this._sourceDataItems.splice(0, chunkSize);
this.dataItems.push(newItems);
},
onLoadMoreItemsRequested: function (args) {
console.log("---load more item---");
const that = new WeakRef(this);
const listView = args.object;
if (this._sourceDataItems.length > 0) {
setTimeout(function () {
that.get().addMoreItemsFromSource(10);
listView.notifyLoadOnDemandFinished();
}, 1500);
args.returnValue = true;
} else {
args.returnValue = false;
listView.notifyLoadOnDemandFinished(true);
}
},
Search.js
exports.pageLoaded = function (args) {
const page = args.object;
var searchViewModel = new SearchViewModel();
page.bindingContext = searchViewModel;
searchViewModel.initDataItems();
searchViewModel.addMoreItemsFromSource(5);
}
Related
Hi im working on a Chrome extension that adds badges to users, now the problem is i have to refresh the page everytime so the badges can load because there are client-side changes . How can i watch events change so i run the function on first time page load ?
I read something about input event listener or MutationObserver but im not sure how can i implement that , Any help would be much appreciated .
CODE:
function Foreground() {
let users = null;
let queries = [];
let userIds = [];
document.addEventListener("DOMContentLoaded", function(event) {});
window.addEventListener('load', () => {
fetchUsersAndQueries();
chrome.runtime.onMessage.addListener(async(message, sender, res) => {
if (message.users) {
fetchUsersAndQueries();
if (users) {
return res(users);
} else {
return res([]);
}
}
if (message.refresh) {
try {
assignBadges();
} catch (error) {
console.log(error.message);
}
}
return true;
});
let done = false;
setInterval(() => {
if (done) {
return;
}
if (users) {
done = true;
try {
assignBadges();
} catch (error) {
console.log(error.message);
}
}
}, 500);
});
async function fetchUsersAndQueries() {
userIds = await getAPIUserIds();
let isStop = false;
setInterval(() => {
if (isStop) {
return;
}
const parasiteContainer = document.querySelector('#parasite-container');
if (parasiteContainer) {
if (parasiteContainer.shadowRoot) {
try {
const roster1 = parasiteContainer.shadowRoot.querySelector(`[name="roster1"]`);
const roster2 = parasiteContainer.shadowRoot.querySelector(`[name="roster2"]`);
if (!roster1) {
return
};
if ([...roster1.children].length === 1) {
if (roster1.firstElementChild.children.length === 1) {
if (roster1.firstElementChild.firstElementChild.length === 1) {
const fTeam = [...roster1.firstElementChild.firstElementChild.firstElementChild.children].map(item => getUsername(item));
const sTeam = [...roster2.firstElementChild.firstElementChild.firstElementChild.children].map(item => getUsername(item));
users = fTeam.concat(sTeam).flat();
queries.push([...roster1.firstElementChild.firstElementChild.firstElementChild.children]);
queries.push([...roster2.firstElementChild.firstElementChild.firstElementChild.children]);
isStop = true;
} else {
const fTeam = [...roster1.firstElementChild.firstElementChild.children].map(item => getUsername(item));
const sTeam = [...roster2.firstElementChild.firstElementChild.children].map(item => getUsername(item));
users = fTeam.concat(sTeam).flat();
queries.push([...roster1.firstElementChild.firstElementChild.children]);
queries.push([...roster2.firstElementChild.firstElementChild.children]);
isStop = true;
}
} else {
const fTeam = [...roster1.firstElementChild.children].map(item => getUsername(item));
const sTeam = [...roster2.firstElementChild.children].map(item => getUsername(item));
users = fTeam.concat(sTeam).flat();
queries.push([...roster1.firstElementChild.children]);
queries.push([...roster2.firstElementChild.children]);
isStop = true;
}
}
queries.forEach(query => {
query.map(item => {
if (item.children.length > 1) {
[...item.children].map(child => {
// const container = child.querySelector('.sc-hCQDas'); // Classname might change in the future.
const container = child.firstElementChild ? .firstElementChild ? .firstElementChild ? .firstElementChild ? .children[2];
if (container) {
container.insertAdjacentHTML(
'beforeend',
createBadge(badgesResponse.data.exists, child.dataset.userId)
);
}
});
} else {
// const container = item.querySelector('.sc-hCQDas'); // Classname might change in the future.
const container = item.firstElementChild ? .firstElementChild ? .firstElementChild ? .children[0];
if (container) {
container.insertAdjacentHTML(
'beforeend',
createBadge(badgesResponse.data.exists, item.dataset.userId)
);
}
}
});
});
}
i am making electron desktop kiosk app and have problem with rendering pdf (im using library pdf.js). I need to help with this error, i make bold code where is error line 192 (const page = await doc.getPage(pageNumber);). HELP
Uncaught (in promise) TypeError: Cannot read properties of null
(reading 'sendWithPromise')
at WorkerTransport.getPage (api.js:2792:21)
at PDFDocumentProxy.getPage (api.js:786:12)
at createPDF (pdf-handler.js:192:26)
at HTMLDivElement.zoomInPdf (pdf-handler.js:96:7) getPage # api.js:2792 getPage # api.js:786 createPDF # pdf-handler.js:192
zoomInPdf # pdf-handler.js:96
let state = {
currentPage: 1,
scale: 1.5
};
export function getCurrentPage() {
return state.currentPage;
}
export function getCurrentScale() {
return state.scale;
}
export function setCurrentPage(currentPage) {
state = { ...state, currentPage };
}
export function setCurrentScale(scale) {
state = { ...state, scale };
}
export async function openPDF(filepath, filename) {
document.getElementById("pdfPageName").innerHTML = filename;
console.log(filename)
setCurrentPage(1);
setCurrentScale(1.5)
clearCanvas(canvas);
var pdfDocument = await pdfjsLib.getDocument(filepath).promise;
createPDF(pdfDocument, getCurrentPage(), getCurrentScale());
setPages(pdfDocument.numPages);
const nextButtonHandler = () => {
const nextPageNumber = getCurrentPage() + 1;
if (nextPageNumber > pdfDocument.numPages) return;
setCurrentPage(nextPageNumber);
if (pageRendering) {
console.log("renderuje sie")
//ensure previous operations were cancelled or completed.
clearCanvas(canvas)
.then(function () {
createPDF(pdfDocument, nextPageNumber, getCurrentScale());
});
} else {
createPDF(pdfDocument, nextPageNumber, getCurrentScale());
};
};
const prevButtonHandler = () => {
const prevPageNumber = getCurrentPage() - 1;
if (prevPageNumber < 1) return;
setCurrentPage(prevPageNumber);
if (pageRendering) {
console.log("renderuje sie")
//ensure previous operations were cancelled or completed.
clearCanvas(canvas)
.then(function () {
createPDF(pdfDocument, prevPageNumber, getCurrentScale());
});
} else {
createPDF(pdfDocument, prevPageNumber, getCurrentScale());
};
};
const zoomInPdf = () => {
const zoomIn = getCurrentScale() + 1;
if (zoomIn > 5) return;
setCurrentScale(zoomIn);
if (pageRendering) {
console.log("renderuje sie")
console.log(canvas)
console.log(canvasContext)
clearCanvas(canvas)
.then(function () {
createPDF(pdfDocument, getCurrentPage(), getCurrentScale());
});
} else {
createPDF(pdfDocument, getCurrentPage(), getCurrentScale());
};
};
const zoomOutPdf = () => {
const zoomOut = getCurrentScale() - 1;
if (zoomOut < 1) return;
setCurrentScale(zoomOut);
if (pageRendering) {
console.log("renderuje sie")
//ensure previous operations were cancelled or completed.
clearCanvas(canvas)
.then(function () {
createPDF(pdfDocument, getCurrentPage(), getCurrentScale());
});
} else {
createPDF(pdfDocument, getCurrentPage(), getCurrentScale());
};
};
const backButtonHandler = () => {
console.log(pdfDocument)
pdfDocument.destroy()
hidePDFView();
nextButton.removeEventListener("click", nextButtonHandler);
prevButton.removeEventListener("click", prevButtonHandler);
backButton.removeEventListener("click", backButtonHandler);
zoomInButton.removeEventListener("click", prevButtonHandler);
zoomOutButton.removeEventListener("click", backButtonHandler);
console.log(pdfDocument)
};
nextButton.addEventListener("click", nextButtonHandler);
prevButton.addEventListener("click", prevButtonHandler);
backButton.addEventListener("click", backButtonHandler);
zoomInButton.addEventListener("click", zoomInPdf);
zoomOutButton.addEventListener("click", zoomOutPdf);
}
var pageRendering = false
var pageNumPending = null
export async function createPDF(doc, pageNumber, scaleNumber) {
pageRendering = true;
console.log(doc)
console.log(doc.pageNumber)
console.log(pageNumber)
console.log(scaleNumber)
**const page = await doc.getPage(pageNumber);**
console.log(page)
const viewport = page.getViewport({ scale: scaleNumber });
console.log(viewport)
canvas.height = viewport.height;
canvas.width = viewport.width;
console.log(pageRendering)
var renderTask = page.render({ viewport, canvasContext });
renderTask.promise.then(function () {
console.log("sius")
console.log(pageRendering)
pageRendering = false;
});
setPage(pageNumber);
return renderTask
}
I have an array that has 3 contacts. I want the same person's name to be deleted when I click on the delete button, but unfortunately I do not know where the problem is that it does not work.
I have two functions in this program, one removeContact to perform the delete operation
And I have a function called showrecords to get the content of the array and display the name and number of contacts with a dedicated delete button for each contact
In this program, I used the pattern builder pattern
Please guide me to the conclusion to solve the problem of not being deleted
Please click on the show Person button to test the program. Contacts will be displayed and click on the delete button. You will see that the delete operation is not performed.
function ElementBuilder(name) {
this.element = document.createElement(name);
this.appendSelector = function(selector) {
this.appendElement = document.querySelector(selector).appendChild(this.element);
return this
};
this.setAttribute = function(attribute, valueAttribute) {
this.element.setAttribute(attribute, valueAttribute)
return this;
};
this.addEventListener = function(event, fun) {
this.element.addEventListener(event, fun);
return this;
};
this.text = function(text) {
this.element.textContent = text;
return this;
};
this.build = function() {
return this.element;
};
}
const builder = {
create: function(name) {
return new ElementBuilder(name);
}
};
function PhoneBook() {
this.records = [{ name: "niloufar", phone: 1111 }, { name: "sara", phone: 2222 }, { name: "sara", phone: 3333 }];
// function remove
this.removeContact = function() {
const self = this
function removePerson(item) {
if (item.target.classList.contains('delbutton')) {
const remID = item.target.getAttribute('data-id');
self.records.splice(remID, 1);
}
}
return removePerson;
}
}
function Render(container) {
this.container = container;
const phoneBook = new PhoneBook();
const remove = phoneBook
.removeContact();
this.removeEntry = (item) => {
remove(item); //
this.showrecords();
}
this.init = function() {
const btn = builder
.create("button")
.text("show person")
.addEventListener("click", this.showrecords)
.appendSelector("div")
.build();
};
// Function: Read contacts from the array and display them
this.showrecords = () => {
const addBookId = document.getElementById('phone-book-container');
let index = 0;
addBookId.innerHTML = '';
const arry = phoneBook.records;
arry.forEach(elm => {
const nameContent = builder
.create('p')
.text(`${elm.name}`)
.appendSelector("div")
.build();
const phoneContent = builder
.create('p')
.text(`${elm.phone}`)
.appendSelector("div")
.build();
const anchor = builder
.create('a')
.addEventListener('click', this.removeEntry)
.setAttribute('href', '#')
.setAttribute('class', 'delbutton')
.setAttribute("id", "deleteButton")
.text("delete")
.setAttribute('date-id', `${index}`)
.appendSelector("div")
.build();
});
}
}
const phoneBookContainer = document.getElementById("phone-book-container");
const app = new Render(phoneBookContainer);
app.init();
<div id="phone-book-container"></div>
You have to pass the item (which is actually the event object) to your function:
function ElementBuilder(name) {
this.element = document.createElement(name);
this.appendSelector = function(selector) {
this.appendElement = document.querySelector(selector).appendChild(this.element);
return this
};
this.setAttribute = function(attribute, valueAttribute) {
this.element.setAttribute(attribute, valueAttribute)
return this;
};
this.addEventListener = function(event, fun) {
this.element.addEventListener(event, fun);
return this;
};
this.text = function(text) {
this.element.textContent = text;
return this;
};
this.build = function() {
return this.element;
};
}
const builder = {
create: function(name) {
return new ElementBuilder(name);
}
};
function PhoneBook() {
this.records = [{ name: "niloufar", phone: 1111 }, { name: "sara", phone: 2222 }, { name: "sara", phone: 3333 }];
// function remove
this.removeContact = function() {
const self = this
function removePerson(item) {
if (item.target.classList.contains('delbutton')) {
const remID = item.target.getAttribute('date-id');
self.records.splice(remID, 1);
}
}
return removePerson;
}
}
function Render(container) {
this.container = container;
const phoneBook = new PhoneBook();
const remove = phoneBook
.removeContact();
this.removeEntry = (item) => {
remove(item);
this.showrecords();
}
this.init = function() {
const btn = builder
.create("button")
.text("show person")
.addEventListener("click", this.showrecords)
.appendSelector("div")
.build();
};
// Function: Read contacts from the array and display them
this.showrecords = () => {
const addBookId = document.getElementById('phone-book-container');
addBookId.innerHTML = '';
const arry = phoneBook.records;
arry.forEach((elm, index) => {
const nameContent = builder
.create('p')
.text(`${elm.name}`)
.appendSelector("div")
.build();
const phoneContent = builder
.create('p')
.text(`${elm.phone}`)
.appendSelector("div")
.build();
const anchor = builder
.create('a')
.addEventListener('click', this.removeEntry)
.setAttribute('href', '#')
.setAttribute('class', 'delbutton')
.setAttribute("id", "deleteButton")
.text("delete")
.setAttribute('date-id', `${index}`)
.appendSelector("div")
.build();
});
}
}
const phoneBookContainer = document.getElementById("phone-book-container");
const app = new Render(phoneBookContainer);
app.init();
<div id="phone-book-container"></div>
i'm creating a nativescript core app with radlistview and i would like the listview to add new items automatically at intervals.
if you have any knowledge of how i can achieve this, please help, i would appreciate.
this is my view-model.js
_sourceDataItems: new ObservableArray(),
dataItems: new ObservableArray(),
initDataItems: function () {
var url="example.com";
fetch(url).then((response) => response.json()).then((res) => {
var count = res.items.length;
this._sourceDataItems = res.items;
this.addMoreItemsFromSource(5);
}).catch((err) => {
});
},
addMoreItemsFromSource: function (chunkSize) {
console.log(this._sourceDataItems);
let newItems = this._sourceDataItems.splice(0, chunkSize);
this.dataItems.push(newItems);
},
onLoadMoreItemsRequested: function (args) {
console.log("---load more item---");
const that = new WeakRef(this);
const listView = args.object;
if (this._sourceDataItems.length > 0) {
setTimeout(function () {
that.get().addMoreItemsFromSource(25);
listView.notifyLoadOnDemandFinished();
}, 1500);
args.returnValue = true;
} else {
args.returnValue = false;
listView.notifyLoadOnDemandFinished(true);
}
},
});
if you need anymore info, let me know
I have two .js-files:
main.js
require("./randomEvent.js").start("hey");
require("./randomEvent.js").start("hi");
require("./randomEvent.js").start("hello");
randomEvent.js
var repeat = true;
exports.start = (randomString) => {
while (repeat) {
console.log(randomString);
}
}
exports.stop = (randomString) => {
repeat = false;
}
I want to start randomEvent.js 3 times, each with different randomStrings.
And if I do
require("./randomEvent.js").stop("hi");
it should stop the start("hi") function / it should set repeat to false.
How?
Thanks in advance!
You can implement your randomEvents.js as a class. So every instance has its own repeat flag.
function RandomEvent(str) {
this.repeat = true;
this.randomString = str;
this.start = () => {
setInterval(() => {
if (this.repeat) {
console.log('-->', this.randomString);
}
}, 1000);
}
this.stop = () => {
this.repeat = false;
}
}
module.exports = RandomEvent;
and main.js
let RandomEvent = require('./randomEvent');
let sayHi = new RandomEvent('hi');
let sayHello = new RandomEvent('hello');
let sayHey = new RandomEvent('hey');
sayHi.start();
sayHello.start();
sayHey.start();
setTimeout(() => {
console.log('stop saying hi')
sayHi.stop();
}, 5000);
Or you can store for every string, its own flag:
randomEvents.js
var repeat = {};
exports.start = (randomString) => {
repeat[randomString] = true;
setInterval(() => {
if (repeat[randomString]) {
console.log('-->', randomString);
}
}, 1000);
}
exports.stop = (randomString) => {
repeat[randomString] = false;
}
and in main.js
require("./randomEvent.js").start("hey");
require("./randomEvent.js").start("hi");
require("./randomEvent.js").start("hello");
setTimeout(() => {
console.log('stop saying hi')
require("./randomEvent.js").stop("hi");
}, 5000);
randomEvent.js
var repeatFlags = {};
function repeatLog(str) {
if (repeatFlags[str]) {
console.log(str);
setTimeout(() => {
repeatLog(str);
});
}
}
exports.start = (randomString) => {
repeatFlags[randomString] = true;
repeatLog(randomString);
}
exports.stop = (randomString) => {
repeatFlags[randomString] = false;
}