Skip to content

Instantly share code, notes, and snippets.

@jonseo
Last active May 1, 2023 23:01
Show Gist options
  • Save jonseo/d250aa5109be1271f2ad9410f3701e0b to your computer and use it in GitHub Desktop.
Save jonseo/d250aa5109be1271f2ad9410f3701e0b to your computer and use it in GitHub Desktop.
Modal w Pagination - remote json File
<div id="searchWrapper">
<input type="text" name="searchBar" id="searchBar" placeholder="search for Hardwood" />
</div>
<div id="buttons">
<button class="button-value" onclick="filterSelection(null)">All</button>
<button class="button-value" onclick="filterSelection('Arden')">Arden</button>
<button class="button-value" onclick="filterSelection('Caravan')">Caravan</button>
<button class="button-value" onclick="filterSelection('Grant')">Grant</button>
<button class="button-value" onclick="filterSelection('Timber')">Timber</button>
</div>
<ul id="charactersList"></ul>
<div id="pagination">
<button id="prevBtn" class="pagination-button">Previous</button>
<div id="pageBtns"></div>
<button id="nextBtn" class="pagination-button">Next</button>
</div>
const charactersList = document.getElementById('charactersList');
const searchBar = document.getElementById('searchBar');
let hpCharacters = [];
searchBar.addEventListener('keyup', (e) => {
const searchString = e.target.value.toLowerCase();
const filteredCharacters = hpCharacters.filter((character) => {
return character.title.toLowerCase().includes(searchString);
});
displayCharacters(filteredCharacters);
});
const filterSelection = (title) => {
if (title === null) {
displayCharacters(hpCharacters);
} else {
const filteredCharacters = hpCharacters.filter((character) => {
return character.title.toLowerCase().includes(title.toLowerCase());
});
displayCharacters(filteredCharacters);
}
};
const loadCharacters = async () => {
try {
const res = await fetch('https://cusapi.netlify.app/shaw-hardwood.json');
hpCharacters = await res.json();
displayCharacters(hpCharacters);
} catch (err) {
console.error(err);
}
};
const displayCharacters = (characters, page = 1) => {
const itemsPerPage = 6;
const startIndex = (page - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const htmlString = characters
.slice(startIndex, endIndex)
.map((character) => {
return `
<li class="character">
<img src="${character.image}" width="200" height="200" /><br/>
<a href="${character.url}"><h4>${character.title}</h4></a>
</li>
`;
})
.join('');
const charactersList = document.getElementById('charactersList');
charactersList.innerHTML = htmlString;
// Add pagination buttons
const totalPages = Math.ceil(characters.length / itemsPerPage);
//const pageBtns = document.getElementById('pageBtns');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
// Remove all child nodes from the pageBtns element
while (pageBtns.firstChild) {
pageBtns.removeChild(pageBtns.firstChild);
}
// Add event listeners to the previous and next buttons
prevBtn.addEventListener('click', () => {
if (page > 1) {
displayCharacters(hpCharacters, page - 1);
}
});
nextBtn.addEventListener('click', () => {
if (page < totalPages) {
displayCharacters(hpCharacters, page + 1);
}
});
// Disable the previous button on the first page
if (page === 1) {
prevBtn.disabled = true;
} else {
prevBtn.disabled = false;
}
// Disable the next button on the last page
if (page === totalPages) {
nextBtn.disabled = true;
} else {
nextBtn.disabled = false;
}
////////////////////////////////////////////////////////////////////////////////////
// Add a click event listener to the list items
const listItems = charactersList.querySelectorAll('li');
listItems.forEach((item) => {
item.addEventListener('click', function(event) {
event.preventDefault(); //Prevent the default behaviour of the link
// Create a new modal element
const modal = document.createElement('div');
modal.classList.add('modal');
// Add content to the modal
modal.innerHTML = `
<div class="modal-content">
<span class="close">&times;</span>
<iframe src="${item.querySelector('a').href}" width="600" height="700"></iframe>
</div>
`;
// Append the modal to the DOM
document.body.appendChild(modal);
// Add a click event listener to the modal's close button
const closeButton = modal.querySelector('.close');
closeButton.addEventListener('click', function() {
// Remove the modal from the DOM
document.body.removeChild(modal);
});
});
});
};
loadCharacters();
body {
font-family: sans-serif;
background-color: #556B2F;
}
* {
box-sizing: border-box;
}
h1 {
color: #eee;
margin-bottom: 25px;
}
.container {
padding: 40px;
margin: 0 auto;
max-width: 1000px;
text-align: center;
}
#charactersList {
padding-inline-start: 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
grid-gap: 20px;
}
.character {
list-style-type: none;
background-color: #eaeaea;
border-radius: 3px;
padding: 10px 20px;
display: grid;
grid-template-columns: 3fr 1fr;
grid-template-areas:
'name image'
'house image';
text-align: left;
}
.character > h2 {
grid-area: name;
margin-bottom: 0px;
}
.character > p {
grid-area: house;
margin: 0;
margin-top: -18px;
}
.character > img {
max-height: 100px;
grid-area: image;
}
#searchBar {
width: 100%;
height: 32px;
border-radius: 3px;
border: 1px solid #eaeaea;
padding: 5px 10px;
font-size: 12px;
}
#searchWrapper {
position: relative;
}
#searchWrapper::after {
content: '🔍';
position: absolute;
top: 7px;
right: 15px;
}
/* Styling for the modal */
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
max-width: 600px;
text-align: center;
}
.close {
position: absolute;
top: 10px;
right: 10px;
font-size: 44px;
font-weight: bold;
cursor: pointer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment