Skip to content

Latest commit

 

History

History
202 lines (172 loc) · 6 KB

README.md

File metadata and controls

202 lines (172 loc) · 6 KB

'OBA voor beginnende ondernemers'

Insights

I only needed one API fetch for this whole project. This API fetch has error state noResults() included.

export function getData(scroll) { 
    let url = `${cors}${endpoint}${'Ondernemerschap+' + query}&page=${page}&authorization=${key}&detaillevel=${detail}&output=json`;
    fetch(url, config)
    .then(response => {
        return response.json();
    })
    .then(data => {
        console.dir(data)
        if(data.results.length > 0) {
            renderData(data, scroll);
        } else {
            noResults();
        }
    })
    .catch(err => {
        console.log(err)
        noResults();
    });
}

I also only use one data render function. everything below the <h4> only gets shown when you click a specific article. This way you don't need to load this info again when you click it.

export function renderData(data, scroll) {
  let articleEl = document.querySelectorAll('section:first-of-type article');
  if(!scroll) {
    articleEl.forEach((item) => {
      item.remove();
    });
  }
  firstLoader()
  data.results.forEach((item) => {
    section.insertAdjacentHTML('beforeend', 
        `
        <article class="results">
          <button class="hide"></button>
              <h3>${item.titles[0]}</h3>
              <p>${item.summaries ? item.summaries[0] : 'Geen samenvatting'}</p>
              <img src="${item.coverimages ? item.coverimages[1] : '' }">
              <h4 class="hide">Details</h4>
                <div class="hide">
                  <ul>
                    <li><p>Auteur:</p><p>${item.authors ? item.authors : 'Geen auteurs'}</p></li>
                    <li><p>Uitgever:</p><p>${item.publisher ? item.publisher : 'Geen uitgever'}</p></li>
                    <li><p>Taal:</p><p>${item.languages ? item.languages : 'Geen taal'}</p></li>
                    <li><p>Jaar:</p><p>${item.year ? item.year : 'Geen jaar'}</p></li>
                    <li><p>Onderwerp:</p><p>${item["subject-topical"] ? item["subject-topical"] : 'Geen onderwerp'}</p></li>
                  </ul>
              </div>
        </article>
        ` 
    );
  });
  suggestBook();
  triggerDetailed();
}

Getting the detailed version was getting a bit more messy. I had to play around with adding classes and removing specific classes and elements. The styling of the detailed "page" was the worst part. Making this much info responsive gets kind off annoying. It took me some time.

export function getDetailed(result) {
    result.classList.add('detailed');

    const appearance = document.querySelectorAll('body > div, .detailed button, .detailed h4, .detailed div');
    appearance.forEach((element) => {
        element.classList.remove('hide');
    })

    let removeBtn = document.querySelector('.detailed button')
    removeBtn.addEventListener('click', function() {
        removeDetailed(result);
    });
}

function removeDetailed(result) {
    const appearance = document.querySelectorAll('body > div, .detailed button, .detailed h4, .detailed div');
    appearance.forEach((element) => {
        element.classList.add('hide');
    });
    result.classList.remove('detailed');
}

If you don't know what book to choose, this randomBook() seaker chooses a random item for you.

export function randomBook() {
    history.replaceState("", "", location.pathname);
    let articleArray = document.querySelectorAll('.results');
    articleArray.forEach((item, i) => {
        if(item.id == 'random-book') {
            item.id = null;
        }
    });

    const random = Math.floor(Math.random() * articleArray.length);
    articleArray[random].id = 'random-book';
    window.location.hash = '#random-book';
    let randoBook = document.querySelector('#random-book');
    setTimeout(function() { randoBook.click() }, 1000);
}

The section where you can click the suggestBtn was a harder part. Because I have an infinite scroll I needed to make sure the suggestBook() was replaced once in a while so you can keep seeing the random suggestor.

export function suggestBook() {
    let beforeArticle;
    if(page % 2 == 0) {
        if (page > 2) {
            let suggestEl = document.querySelector('.suggest-book');
            suggestEl.remove();
        }   
        beforeArticle = document.querySelectorAll('main > section article'); 
    
        beforeArticle[beforeArticle.length-4].insertAdjacentHTML('beforebegin', 
        ` <article class="suggest-book">
            <h2>Weet je niet welke je moet kiezen?</h2>
            <p>Laat ons een willekeurig boek kiezen!</p>
            <button>Doe je ding</button>
        </article>`
        );

        const suggestBtn = document.querySelector('.suggest-book button');

        suggestBtn.addEventListener('click', function() {
            randomBook()
        });
    }
}

Small things I'm proud of

.to-top {
    animation: scroll 1.5s ease-out forwards;
}

@keyframes scroll {
    0% {
        opacity: 1; 
        height: 4rem;
    }
    20% {
        opacity: 1; 
        height: 80vh;
    }
    60% {
        opacity: 0;
        top: calc(20vh - 2rem);
        height: 4rem;
        opacity: 1; 
    }
    100% {
        opacity: 0;
        top: calc(20vh - 2rem);
        height: 4rem;
    }
}

form button:hover {
        width: 100px;
        padding-right: 5px;
    }

    form button::after {
        content: "zoeken";
        display: block;
        opacity: 0;
        color: white;
        transition: .5s;
        transition-delay: .1s ease-in-out;
    }

    form button:hover::after {
        opacity: 1;
        margin-left: 15px;
    }

Future plans

I still need to add the staging API. I had no time to fix this. Also I want to make a skeleton loader for the infinite scroll if it is loading new elements. Next to that I want to make a filter function above my searchbar. It gives the user a better oppurtunity to find what they are looking for. Also if you go to the page, it starts with a searchbar. It is a little bit of an empty section.