homepage/index.php
var form = document.createElement("form");
form.id = "survey-form";
var elements = [
{
type: "select",
label: "Send to employee",
id: "empno",
options: [] // Options will be populated dynamically
},
];
elements.forEach(function (element) {
var wrapper;
var label = document.createElement("label");
label.className = "form-label";
label.textContent = element.label;
if (element.type === "select") {
input = document.createElement("select");
input.id = element.id;
input.className = "user-input";
form.appendChild(label);
form.appendChild(input);
fetchOptionsUsingWorker(input, element.options);
$(document).ready(function() {
$('#' + element.id).select2();
});
}
});
function fetchOptionsUsingWorker(selectElement) {
var worker = new Worker('optionsWorker.js');
worker.addEventListener('message', function(e) {
if (e.data.type === 'optionsData') {
var optionsData = e.data.data;
populateSelectWithOptions(selectElement, optionsData);
} else if (e.data.type === 'error') {
console.error('Error fetching options data:', e.data.message);
}
});
worker.postMessage('fetchOptions');
}
function populateSelectWithOptions(selectElement, optionsData) {
selectElement.innerHTML = '';
optionsData.forEach(function (option) {
var optionElement = document.createElement("option");
optionElement.value = option;
optionElement.text = option;
selectElement.appendChild(optionElement);
});
}
homepage/optionsWorker.js
function fetchOptionsFromServer() {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", "../backend.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onload = function () {
if (xhr.status === 200) {
var data;
if (xhr.responseText === "No data found") {
data = ["No data found"];
} else {
data = JSON.parse(xhr.responseText);
}
resolve(data);
} else {
reject(xhr.statusText);
}
};
var data = "input=get_options";
xhr.send(data);
});
}
self.addEventListener('message', async function(e) {
if (e.data === 'fetchOptions') {
try {
const optionsData = await fetchOptionsFromServer();
self.postMessage({ type: 'optionsData', data: optionsData });
} catch (error) {
self.postMessage({ type: 'error', message: error });
}
}
});
As there are thousands of data being fetched from the server, I used webworkers to run the code which fetches the data in the background thread, otherwise the webpage keeps on freezing. But even after using webworkers, it was of no good, as the webpage still freezes. Where am I going wrong? Please guide me.
You should use some kind of virtual scrolling, so a usual
<select>won't work. Basically you need a custom dropdown and add a virtually scrolling list in its popup.A virtual scrolling with the same row height is implemented quite easily (in this example there's no individual item offset (simplified)):