Home > Enterprise >  Making a search box works
Making a search box works

Time:12-06

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)

  • Related