<style>
/* CSS Styles */
.mytool-text {
font-size: 1.125rem;
color: #2c2222;
max-width: 80%;
margin: 0 auto;
line-height: 1.6;
}
.mytool-collection-container {
width: 100%;
max-width: 1500px;
margin: 20px auto;
padding: 0 10px;
}
.mytool-top-section {
width: 100%;
display: flex;
justify-content: center;
margin-top: 30px;
}
.mytool-search-box {
width: 90%;
display: flex;
justify-content: center;
align-items: center;
}
.mytool-search-input {
width: 70%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 12px;
max-width: 100%;
background-color: #FFFFFF;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-right: 10px;
}
.mytool-search-input:focus {
outline: none;
border-color: #f0f0f0;
box-shadow: 0 0 8px rgba(0, 143, 122, 0.5);
}
.mytool-category-filter {
padding: 10px;
border-radius: 12px;
border: 1px solid #ccc;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.mytool-items {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
list-style: none;
justify-content: ;
padding: 0;
margin: 20px auto;
max-width: 1200px;
}
.mytool-item {
background-color: #fff;
padding: 20px;
box-shadow: 0 16px 30px rgba(0, 0, 0, 0.1);
border-radius: 20px;
transition: transform 1s ease;
cursor: pointer;
}
.mytool-item:hover {
transform: translateY(-5px);
background-color: #f9f9f9;
}
.mytool-title {
font-size: 18px;
font-weight: bold;
margin: 10px 0;
display: flex;
align-items: center;
}
.mytool-text {
font-size: 15px;
color: #808080;
margin: 1;
}
.mytool-thumbnail {
height: auto;
width: 100%;
border-radius: 10px;
margin-bottom: 10px;
display: block;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.mytool-logo {
width: 30px;
height: 30px;
border-radius: 50%;
margin-right: 10px;
}
.mytool-item a {
text-decoration: none;
color: inherit;
display: block;
margin-right: 0px;
margin-left: 20px;
}
.mytool-item a:hover {
text-decoration: none;
color: #006400;
}
.mytool-back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
display: none;
background-color: #008F7A;
color: white;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
text-align: center;
cursor: pointer;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
font-size: 18px;
z-index: 1000;
}
.mytool-back-to-top:hover {
background-color: #006F5A;
}
.mytool-sticky-logo {
position: fixed;
bottom: 20px;
left: 120px;
width: 150px;
background-color: #333;
height: auto;
z-index: 1000;
cursor: pointer;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
border-radius: 10px;
}
.mytool-sticky-logo:hover {
opacity: 0.8;
}
</style>
<a href="https://siamwebtools.com/directoryplus-Makeweb" target="_blank">
<img src="https://directoryplus.org/images/logo.png" alt="Directory Plus Logo" class="mytool-sticky-logo">
</a>
<div class="mytool-collection-container">
<!-- Search Section -->
<div class="mytool-top-section">
<div class="mytool-search-box">
<input type="text" id="mytool-search-input" class="mytool-search-input" placeholder="Search for tools...">
<select id="mytool-category-filter" class="mytool-category-filter">
<option value="">All Categories</option>
</select>
</div>
</div>
<!-- Tools List -->
<div class="main-content">
<ul id="mytool-tools-list" class="mytool-items"></ul>
</div>
</div>
<button id="mytool-back-to-top" class="mytool-back-to-top">jn✈</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const sheetUrl = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSiQiYOxGlVmX2FjveKUTfDUIbQ6w0l6qEQDbIUFP8Y8uT96wNkBLr6264EIvEu3HiOzQvPYkAEJjBU/pub?output=csv';
const toolsList = document.getElementById('mytool-tools-list');
const searchInput = document.getElementById('mytool-search-input');
const categoryFilter = document.getElementById('mytool-category-filter');
let toolsData = [];
let currentStartIndex = 0;
const batchSize = 30;
// Check if data is cached in localStorage
const cachedData = localStorage.getItem('mytool-toolsData');
if (cachedData) {
toolsData = JSON.parse(cachedData);
toolsData = shuffleArray(toolsData);
loadCategories();
loadMoreTools();
} else {
fetchData();
}
// Fetch data from Google Sheet
function fetchData() {
fetch(sheetUrl)
.then(response => response.text())
.then(data => {
toolsData = Papa.parse(data, { header: true }).data;
toolsData = shuffleArray(toolsData); // Shuffle the data
localStorage.setItem('mytool-toolsData', JSON.stringify(toolsData)); // Save to localStorage
loadCategories();
loadMoreTools();
});
}
// Shuffle array for random display of cards
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// Load categories from tools data
function loadCategories() {
const categories = new Set();
toolsData.forEach(tool => {
const toolCategories = tool.Category.split(';');
toolCategories.forEach(category => categories.add(category.trim()));
});
const sortedCategories = Array.from(categories).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
sortedCategories.forEach(category => {
const option = document.createElement('option');
option.value = category;
option.textContent = category;
categoryFilter.appendChild(option);
});
}
function renderTools(tools) {
tools.forEach(tool => {
const li = document.createElement('li');
li.className = 'mytool-item';
li.innerHTML = `
<a href="${tool.URL}" target="_blank">
<div class="mytool-title">
<img class="mytool-logo" src="${tool.LogoUrl}" alt="${tool.title} logo" onerror="this.onerror=null; this.src='https://www.google.com/favicon.ico';">
${tool.title}
</div>
<p class="mytool-text">${tool.Text}</p>
</a>
`;
toolsList.appendChild(li);
});
}
// Load more tools when needed
function loadMoreTools() {
const toolsToDisplay = toolsData.slice(currentStartIndex, currentStartIndex + batchSize);
renderTools(toolsToDisplay);
currentStartIndex += batchSize;
}
// Infinite scroll event
window.addEventListener('scroll', () => {
const scrollPosition = window.innerHeight + window.scrollY;
const threshold = document.body.offsetHeight - 200; // 200px from the bottom
if (scrollPosition >= threshold) {
loadMoreTools();
}
// Show or hide back to top button
const backToTop = document.getElementById('mytool-back-to-top');
if (window.scrollY > 200) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
// Search functionality
searchInput.addEventListener('input', function() {
const query = searchInput.value.toLowerCase();
const filteredTools = toolsData.filter(tool =>
tool.title.toLowerCase().includes(query) ||
tool.Category.toLowerCase().includes(query) ||
tool.Text.toLowerCase().includes(query)
);
currentStartIndex = 0; // Reset start index
toolsList.innerHTML = ''; // Clear previous results
renderTools(filteredTools); // Render filtered tools
});
// Filter tools by category
categoryFilter.addEventListener('change', function() {
const selectedCategory = categoryFilter.value;
let filteredTools;
if (selectedCategory) {
filteredTools = toolsData.filter(tool =>
tool.Category.split(';').map(cat => cat.trim()).includes(selectedCategory)
);
} else {
filteredTools = toolsData; // Show all tools if no category is selected
}
currentStartIndex = 0; // Reset start index
toolsList.innerHTML = ''; // Clear previous results
renderTools(filteredTools); // Render filtered tools
});
// Back to top button
const backToTop = document.getElementById('mytool-back-to-top');
backToTop.addEventListener('click', function() {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
});
</script>
JAVASCRIPT
10,621 characters