I have a problem creating a search box i my JS code. The search needs to find in the restaurant name and the restaurant description. Actually when I search, the code duplicate the cards in my web because my function showRestaurants creates the cards of the web. I don't know how to fix this problem. The JS code:
import { RestaurantService } from './restaurant-service.class.js';
import '../node_modules/bootstrap/dist/css/bootstrap.css';
import css from '../styles.css';
import RestaurantTemplate from '../templates/restaurant.handlebars';
let restaurants = [];
const restaurantService = new RestaurantService();
const weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
const currentDay = new Date().getDay();
restaurantService.getAll().then((array) => {
restaurants = array;
restaurants = array.filter((restaurant) => restaurants.id !== restaurant.id);
showRestaurants(restaurants);
});
function createCard(titleName, descriptionText, openDays, cuisineText, phone, image, id) {
// I need a new form to create the cards with handlebars
const objectCard = {
restaurantName: titleName,
restaurantDescription: descriptionText,
restaurantOpenDays: openDays.map(day => weekdays[day]).join(', '),
restaurantOpen: openDays.includes(String(currentDay)),
restaurantCuisine: cuisineText,
restaurantPhoneNumber: phone,
restaurantImageSource: image,
};
const htmlCard = RestaurantTemplate(objectCard);
const container = document.createElement('div');
container.className = 'col';
container.innerHTML = htmlCard;
container.getElementsByTagName('button')[0].addEventListener('click', () => {
if (window.confirm('Are you sure to delete this card?')) {
restaurantService.delete(id).then(() => {
container.remove();
});
}
});
document.getElementById('placesContainer').appendChild(container);
}
function showRestaurants(restaurants) {
for (let index = 0; index < restaurants.length; index ) {
createCard(restaurants[index].name, restaurants[index].description, restaurants[index].daysOpen, restaurants[index].cuisine, restaurants[index].phone, restaurants[index].image ,restaurants[index].id);
}
}
// Search box but actually duplicates the cards that find
document.getElementById('search').addEventListener('keyup', e => {
const searchRestaurant = restaurants.filter(restaurant =>
restaurant.name.toLowerCase().includes(document.getElementById('search').value.toLowerCase()) ||
restaurant.description.toLowerCase().includes(document.getElementById('search').value.toLowerCase()));
showRestaurants(searchRestaurant);
});
The html code:
<html>
<head>
<title>Exercise 3 | Home</title>
<meta charset="UTF-8">
</head>
<body>
<nav >
<div >
<a href="#">FoodScore</a>
<ul >
<li >
<a href="index.html">Home</a>
</li>
<li >
<a href="new-restaurant.html">New restaurant</a>
</li>
</ul>
</div>
</nav>
<div >
<!--Optional-->
<nav >
<form >
<input type="text" name="search" id="search" placeholder="Search"
aria-label="Search">
</form>
</nav>
<div id="placesContainer" >
<!-- <div >
<div >
<img src="IMAGE_BASE64">
<div >
<button >Delete</button>
<h4 >Restaurant Name</h4>
<p >Restaurant Description</p>
<div >
<small >
<strong>Opens: </strong>Mo, Tu, We, Th, Fr, Sa, Su
</small>
<span >Open</span>
</div>
<div >
<small >
<strong>Phone: </strong>999999999
</small>
</div>
</div>
<div >
<small >Cuisine style</small>
</div>
</div>
</div> -->
</div>
</div>
</body>
</html>
The handlebars:
<div >
<img src="{{restaurantImageSource}}">
<div >
<button >Delete</button>
<h4 >{{restaurantName}}</h4>
<p >{{restaurantDescription}}</p>
<div >
<small >
<strong>Opens: </strong>{{restaurantOpenDays}}
</small>
{{#if restaurantOpen}}
<span >Open</span>
{{else}}
<span >Closed</span>
{{/if}}
</div>
<div >
<small >
<strong>Phone: </strong>{{restaurantPhoneNumber}}
</small>
</div>
</div>
<div >
<small >{{restaurantCuisine}}</small>
</div>
</div>
I've tried making a function similar to showRestaurants to filter the array, but is not really necessary because the includes is already in the eventlistener from the search box.
CodePudding user response:
Thanks to James for the clue, I can fix the problem with a function:
function clearRestaurants() {
const everyChildren = document.getElementById('placesContainer').children;
const arrayEveryChildren = Array.from(everyChildren);
for (let index = 0; index < arrayEveryChildren.length; index ) {
arrayEveryChildren[index].remove();
}
}
And adding the function just before the showRestaurants(searchRestaurant)