Highlight Search Result Vanilla JavaScript - Tuts Make

Highlight Search Result Vanilla JavaScript - Tuts Make

search highlight javascript. Here you will learn how to highlight all occurrences of a word in javascript or highlight search text in div and web page.

Instant Search with Vanilla JavaScript

Instant Search with Vanilla JavaScript

Instant Search with Vanilla JavaScript

Instant Search

We live in a fast world and we want everything to be FAST, including search results, this is why instant search functionality became pretty much a "must have" feature instead of a "nice to have" feature.

In this article we're going to build this feature, but only using Vanilla JavaScript :smiley:.

Below is the Live Preview of what we are going to build in this article. Let's search through the Countries of the world to see their Population and Flag:

Note: that you can use React, Vue, Angular or any other framework/library to create this functionality, although making it in Vanilla JavaScript is much more fun. 😄

The HTML

We'll need 2 things in our HTML:

  1. A search field
  2. A results div where we'll display the search results




Usually we are going into the styling part next, but in this case considering that we don't yet have the entire markup (you'll see in a moment), we'll get to the JS part first. 🙂

The JavaScript

Let's make a plan before we actually type any code. The things that we need to do are:

  1. Gather a list of all the countries in the world
  2. Display the list of countries
  3. Update the results based on the search query

Pretty awesome, eh? 😎

Step one - getting the data

I found a nice API we can use to get the list of countries we need. It is: RestCountries.eu.

We're going to use the built in Fetch API in order to retrieve all the countries, and we're going to store them in a variable: countries.

let countries;

const fetchCountries = async () => {
    countries = await fetch(
        'https://restcountries.eu/rest/v2/all?fields=name;population;flag'
    ).then(res => res.json());
};

As you can see, we created an async function; You can read more about this here.

Also, note that we only want 3 fields from the API (name, population and flag) so this is what we're going to get from the API by setting the fields query parameter.

Step two - displaying the data

Now, we need to create the structure of our list in order to display the data and for that we're going to create all the elements that we need (ul, li, headings, etc) inside of a function and we'll insert them into the results div we declared in our HTML.

We're also going to call our fetchCountries function here because we want to loop over the countries in order to create the corresponding elements:

const results = document.getElementById('results');

const showCountries = async () => {
    // getting the data
    await fetchCountries();

    const ul = document.createElement('ul');
    ul.classList.add('countries');

    countries.forEach(country => {
        // creating the structure
        const li = document.createElement('li');
        li.classList.add('country-item');

        const country_flag = document.createElement('img');
        // Setting the image source
        country_flag.src = country.flag;
        country_flag.classList.add('country-flag');

        const country_name = document.createElement('h3');
        country_name.innerText = country.name;
        country_name.classList.add('country-name');

        const country_info = document.createElement('div');
        country_info.classList.add('country-info');

        const country_population = document.createElement('h2');
        country_population.innerText = numberWithCommas(country.population);
        country_population.classList.add('country-population');

        const country_popupation_text = document.createElement('h5');
        country_popupation_text.innerText = 'Population';
        country_popupation_text.classList.add('country-population-text');

        country_info.appendChild(country_population);
        country_info.appendChild(country_popupation_text);

        li.appendChild(country_flag);
        li.appendChild(country_name);
        li.appendChild(country_info);

        ul.appendChild(li);
    });

    results.appendChild(ul);
};

// display initial countries
showCountries();

// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

There is a "little" bit of code above, so let's break it down. 😄

First, we have our list (ul) with the lis that are created in the forEach loop.

All the lis have three children:

  1. The flag - img
  2. The name of the country heading - h3
  3. A div which holds: (a) the population number - h2 - and (b) The 'Population' text - h5

We organized them in this manner because it'll be easier in the CSS to align everything using flexbox.

Alongside that, we added a class for each element because we want to style them individually in the CSS and then we used the appendChild to add these elements into the DOM at the end of the forEach function.

And lastly, we have a numberWithComma function from StackOverflow which will add a comma as a thousand separator for the population number.

Step 3 - update the view based on the search query

In this final step we're going to get the search query from the input by attaching an eventListener on it, and we're going to modify our showCountries function so that it will filter out the values we don't want to be displayed. Let's see how we can do that:

const search_input = document.getElementById('search');

let search_term = '';

search_input.addEventListener('input', e => {
    // saving the input value
    search_term = e.target.value;

    // re-displaying countries based on the new search_term
    showCountries();
});

const showCountries = async () => {
    // clear the results
    results.innerHTML = '';

    // see code above at Step 2.

    countries
        .filter(country =>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(country => {
            // see code above at Step 2.
        });

    // see code above at Step 2.
};

As you can see we added two new things in the showCountries function:

  1. We are clearing the previous results by setting the innerHTML to an empty string
  2. We are filtering the countries by checking if the entered search_term is included in the name of the country, and we're also converting these two values toLowerCase as the user might type in upperCase letters and we still want to display the corresponding country
The entire JS Code

Below you can find the entire JS code in case you want to copy it:

const search_input = document.getElementById('search');
const results = document.getElementById('results');

let search_term = '';
let countries;

const fetchCountries = async () => {
    countries = await fetch(
        'https://restcountries.eu/rest/v2/all?fields=name;population;flag'
    ).then(res => res.json());
};

const showCountries = async () => {
    results.innerHTML = '';

    await fetchCountries();

    const ul = document.createElement('ul');
    ul.classList.add('countries');

    countries
        .filter(country =>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(country => {
            const li = document.createElement('li');
            li.classList.add('country-item');

            const country_flag = document.createElement('img');
            country_flag.src = country.flag;
            country_flag.classList.add('country-flag');

            const country_name = document.createElement('h3');
            country_name.innerText = country.name;
            country_name.classList.add('country-name');

            const country_info = document.createElement('div');
            country_info.classList.add('country-info');

            const country_population = document.createElement('h2');
            country_population.innerText = numberWithCommas(country.population);
            country_population.classList.add('country-population');

            const country_popupation_text = document.createElement('h5');
            country_popupation_text.innerText = 'Population';
            country_popupation_text.classList.add('country-population-text');

            country_info.appendChild(country_population);
            country_info.appendChild(country_popupation_text);

            li.appendChild(country_flag);
            li.appendChild(country_name);
            li.appendChild(country_info);

            ul.appendChild(li);
        });

    results.appendChild(ul);
};

showCountries();

search_input.addEventListener('input', e => {
    search_term = e.target.value;
    showCountries();
});

// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

The CSS

Finally, let's add some styling to our little app:

@import url('https://fonts.googleapis.com/css?family=Roboto:300,500&display=swap');

* {
    box-sizing: border-box;
}

body {
    background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    font-family: 'Roboto', sans-serif;

    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;

    min-height: 100vh;
}

.countries {
    padding: 0;
    list-style-type: none;
    width: 480px;
}

.country-item {
    background-color: #fff;
    border-radius: 3px;
    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 10px;
    margin: 10px 0;
}

.country-item:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.country-flag {
    width: 40px;
}

.country-name {
    flex: 2;
    font-weight: normal;
    letter-spacing: 0.5px;
    margin: 0 5px;
    text-align: center;
}

.country-info {
    border-left: 1px solid #aaa;
    color: #777;
    padding: 0 15px;
    flex: 1;
}

.country-population {
    font-weight: 300;
    line-height: 24px;
    margin: 0;
    margin-bottom: 12px;
}

.country-population-text {
    font-weight: 300;
    letter-spacing: 1px;
    margin: 0;
    text-transform: uppercase;
}

input {
    font-family: 'Roboto', sans-serif;
    border-radius: 3px;
    border: 1px solid #ddd;
    padding: 15px;
    width: 480px;
}

Because it's nothing fancy I'm not going into details about the CSS, but if you have any questions regarding it feel free to contact me and I'll be happy to answer your questions! 😄

Conclusion

As mentioned above, this small app could probably be done much simpler with React, Vue or Angular, and you are free to do so if you want for your submission, but I wanted to play around with Vanilla JS and it was a fun experience for me! 😉

As always, make sure you share what you're going to create!

Happy Coding! 😇

✅ 30s ad

☞ JavaScript programming: JavaScript for beginners

☞ Projects In JavaScript & JQuery

☞ Javascript for Beginners Learn by Doing Practical Exercises

☞ Learn How To Become a JavaScript Developer from Scratch

☞ Javascript - From Beginner to Pro! - Build real world apps

Making a Calendar in Vanilla Javascript

Making a Calendar in Vanilla Javascript

Arguably, time is the best and worst built-in function in Javascript. For my most recent project, I had the idea to make a bastardized Google calendars. I naively figured that making a general, functional calendar would be straightforward and allow me plenty of time to build out my site. I so was wrong.

Arguably, time is the best and worst built-in function in Javascript. For my most recent project, I had the idea to make a bastardized Google calendars. I naively figured that making a general, functional calendar would be straightforward and allow me plenty of time to build out my site. I so was wrong.

Where to Start?

Pretty early on, with guidance from my instructor, I decided to hard code a month into the HTML. This allowed me to build out the general structure and style I wanted for my calendar. There was conflicting literature on whether using or would be better practice. I ultimately decided to go with a table.

If you have ever taken the time to really study a month calendar, the structure is pretty simple. There is a header at the top, usually, that indicates the month and year. Below that are 7 columns outlining the individual days of the week. Finally, there is a maximum of 6 rows to populate the number of days for a given month.

Below is a snapshot of my hardcoded HTML.

Again, this allowed me to mess with the CSS style sheet to render the overall look and feel I wanted for my calendar.

Harnessing the Power of Time

Now came the hard part. I needed to use the built-in time function to populate the accurate number of days in a given month and year. After doing some research, I learned that Javascript will return a number that corresponds to a months relative index in a year: i.e. January is 0, February is 1, etc. This can be called using the getMonth() function built-in to Javascript.

Javascript also does the same thing with days of the week and starts with Sunday. That makes Sunday - 0, Monday - 1, etc. This is called using the getDay() function from Javascript.

So, the question became how do I use this two crucial pieces of information: 1. How do I figure out what day of the week is the start of the month? 2. How do I calculate how many days are in a month?

Answering the first questions was simple enough. Javascript literaturehelped outline the various options for built-in functions. Miraculously, new Date(year, month) is incredibly powerful and will automatically render the first day of a given year and month argument. Using the .getDay() function on this allowed me to get the day index for the start of the month.

Next, I needed to get the number of days in a given month. Again, I used the all-powerful new Date() to get me started, and using some high school algebra, I reverse engineered a way to calculate the total days. The new Date() function can accept a large number of arguments, down to the millisecond. I did not need to get granular with my calendar, but thought I could use the month, year and day arguments. Given that the maximum number of days in any month is 31, putting in 32 days into new Date()would give me the relative date that would actually be in the next month. For example, July(index 6 of a year) has 31 days in a month. If I entered new Date(2019, 6, 32) into my console, I would expect the console to return August 1, 2019.

The new Date() function also has a getDate() function that will return the day number from a given date. Using this returned number, I subtracted this from 32 to get the accurate number of days in a given month.

To further prove my concept, I used February 2019 in my console. Passing in 2019 for year, 1 for month, and 32 for days, I should expect the above equation to return 28, as there were 28 days in February 2019.

One hurdle down, now I had to use this data to populate and render my table.

Populating the Beast

After removing the hardcoded HTML data from my table, I needed to populate the month span and the year span with the currently rendered month and year. This was fairly straightforward as I left a majority of my HTML code in the header. After finding the individual span elements using document.findElementById(), I changed the textContent to the given monthand year.

After grabbing the table element, again using document.getElementById(), I then needed to add some for loops to render my rows and columns. I also knew that I would need to print the actual day number on the calendar. For obvious reasons, I started the count at 1 and assigned this 1 to a usable variable called renderNum. (Note: This variable will be incremented up by one with each column loop. But I’ll get to that in a bit)

Next, I generated the row for loop, as this was going to hold all the individual date tiles. (To be more proper, I will append my row with my table data elements.) Since I knew that I would need at maximum 6 rows, I started my for loop at the traditional 0 and had it stop when ireached 6. Seeing as there was no text content for the row, all I needed was to create the `````` element and assign this to a usable variable.

As stated before, I wanted to append each row with 7 table data elements. This meant that I needed a nested for loop. This 2nd for loop also started at 0 and ended when the count (c in this case) reached 7. This was simple enough, but the next step took some logical reasoning. Remembering that the new Date(month, year).getDay() gave me the index of day of the week, I needed to setup empty ``````s so that the count and calendar rendering started on the correct day. To do this, I added an if statement in my column for loop that would check if: 1. The loop was on the first row (aka i===0), and 2. The value of count loop was less than the new Date(month, year).getDay() value (aka c < startOfMonth).

If both those conditions were true, I wanted the loop to create a element, add an *empty* class to the newly rendered and append this to the current row element.

Next, I wanted to make sure that I was populating the correct day number on each one of the new table data elements. Modifying my empty td elementmethod, I added a `````` element for each new day, added the textContent, and appended the row. The textContent in this case would be the renderNum variable defined earlier. To make sure that the renderNum printed the correct date, I incremented the variable by 1.

Using the power of truthiness, I used an else if statement to stop the calendar from incrementing and adding data past the last day of the month.

Once I reached the break and was out of the for loops, I needed to make sure that to append the table body with the newly formed and populated row. (I did rearrange and group the code according to variables, and my personal preference. Obviously, this is not necessary. It was just a personal preference.)

Finally, I added EventListeners on the click of the arrows to toggle to the month before and after a calendar snapshot. Given the length of this post already, I will spare you. But there is plenty of literature on [EventListeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener "EventListeners")that I recommend reading if you have trouble with that step.

Below is a snapshot of the rendered calendar. I will be sure to update this post with the github link, once the project is complete.

Next up, appointments, time zones and scheduling. Wish me luck!

How does tinder make money?

How does tinder make money?

Essential information regarding how do dating apps make money and [how does tinder make money](https://www.gurutechnolabs.com/12-ways-to-make-money-through-dating-app/ "how does tinder make money"). Moreover, we present unique ways to make money...

Essential information regarding how do dating apps make money and how does tinder make money. Moreover, we present unique ways to make money through dating apps.