<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ instant search - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ instant search - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 28 Jul 2026 03:52:49 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/instant-search/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Instant Search with Vanilla JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ By Florin Pop Originally posted on www.florin-pop.com The theme for week #15 of the Weekly Coding Challenge is: Instant Search We live in a fast world and we want everything to be FAST, including search results, this is why instant search functionali... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/instant-search-with-vanilla-javascript/</link>
                <guid isPermaLink="false">66d45f0b182810487e0ce192</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ instant search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WeeklyCodingChallenge ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 25 Jun 2019 02:14:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/Week--15_-Instant-Search.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Florin Pop</p>
<p><em>Originally posted on <a target="_blank" href="https://www.florin-pop.com/blog/2019/06/vanilla-javascript-instant-search/">www.florin-pop.com</a></em></p>
<p>The <strong>theme</strong> for week #15 of the <a target="_blank" href="https://florin-pop.com/blog/2019/03/weekly-coding-challenge/">Weekly Coding Challenge</a> is:</p>
<h2 id="heading-instant-search">Instant Search</h2>
<p>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.</p>
<p>In this article we're going to build this <a target="_blank" href="https://codepen.io/FlorinPop17/full/qzNxGa/">feature</a>, but only using Vanilla JavaScript :smiley:.</p>
<p>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:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/FlorinPop17/embed/qzNxGa/" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p><strong>Note</strong>: 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. ?</p>
<h2 id="heading-the-html">The HTML</h2>
<p>We'll need 2 things in our HTML:</p>
<ol>
<li>A <code>search</code> field</li>
<li>A <code>results</code> div where we'll display the search results</li>
</ol>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search for a Country"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"results"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>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. ?</p>
<h2 id="heading-the-javascript">The JavaScript</h2>
<p>Let's make a plan before we actually type any code. The things that we need to do are:</p>
<ol>
<li>Gather a list of all the countries in the world</li>
<li>Display the list of countries</li>
<li>Update the results based on the search query</li>
</ol>
<p>Pretty awesome, eh? ?</p>
<h3 id="heading-step-one-getting-the-data">Step one - getting the data</h3>
<p>I found a nice API we can use to get the list of countries we need. It is: <a target="_blank" href="https://restcountries.eu/">RestCountries.eu</a>.</p>
<p>We're going to use the built in <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a> in order to retrieve all the countries, and we're going to store them in a variable: <code>countries</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> countries;

<span class="hljs-keyword">const</span> fetchCountries = <span class="hljs-keyword">async</span> () =&gt; {
    countries = <span class="hljs-keyword">await</span> fetch(
        <span class="hljs-string">'https://restcountries.eu/rest/v2/all?fields=name;population;flag'</span>
    ).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json());
};
</code></pre>
<p>As you can see, we created an async function; You can read more about this <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">here</a>.</p>
<p>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 <code>fields</code> query parameter.</p>
<h3 id="heading-step-two-displaying-the-data">Step two - displaying the data</h3>
<p>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 (<code>ul</code>, <code>li</code>, headings, etc) inside of a function and we'll insert them into the <code>results</code> div we declared in our HTML.</p>
<p>We're also going to call our <code>fetchCountries</code> function here because we want to loop over the countries in order to create the corresponding elements:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'results'</span>);

<span class="hljs-keyword">const</span> showCountries = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-comment">// getting the data</span>
    <span class="hljs-keyword">await</span> fetchCountries();

    <span class="hljs-keyword">const</span> ul = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'ul'</span>);
    ul.classList.add(<span class="hljs-string">'countries'</span>);

    countries.forEach(<span class="hljs-function"><span class="hljs-params">country</span> =&gt;</span> {
        <span class="hljs-comment">// creating the structure</span>
        <span class="hljs-keyword">const</span> li = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>);
        li.classList.add(<span class="hljs-string">'country-item'</span>);

        <span class="hljs-keyword">const</span> country_flag = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'img'</span>);
        <span class="hljs-comment">// Setting the image source</span>
        country_flag.src = country.flag;
        country_flag.classList.add(<span class="hljs-string">'country-flag'</span>);

        <span class="hljs-keyword">const</span> country_name = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h3'</span>);
        country_name.innerText = country.name;
        country_name.classList.add(<span class="hljs-string">'country-name'</span>);

        <span class="hljs-keyword">const</span> country_info = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
        country_info.classList.add(<span class="hljs-string">'country-info'</span>);

        <span class="hljs-keyword">const</span> country_population = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h2'</span>);
        country_population.innerText = numberWithCommas(country.population);
        country_population.classList.add(<span class="hljs-string">'country-population'</span>);

        <span class="hljs-keyword">const</span> country_popupation_text = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h5'</span>);
        country_popupation_text.innerText = <span class="hljs-string">'Population'</span>;
        country_popupation_text.classList.add(<span class="hljs-string">'country-population-text'</span>);

        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);
};

<span class="hljs-comment">// display initial countries</span>
showCountries();

<span class="hljs-comment">// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">numberWithCommas</span>(<span class="hljs-params">x</span>) </span>{
    <span class="hljs-keyword">return</span> x.toString().replace(<span class="hljs-regexp">/\B(?=(\d{3})+(?!\d))/g</span>, <span class="hljs-string">','</span>);
}
</code></pre>
<p>There is a "little" bit of code above, so let's break it down. ?</p>
<p>First, we have our list (<code>ul</code>) with the <code>li</code>s that are created in the <code>forEach</code> loop.</p>
<p>All the <code>li</code>s have three children:</p>
<ol>
<li>The flag - <code>img</code></li>
<li>The name of the country heading - <code>h3</code></li>
<li>A <code>div</code> which holds: (a) the <code>population</code> number - <code>h2</code> - and (b) The <code>'Population'</code> text - <code>h5</code></li>
</ol>
<p>We organized them in this manner because it'll be easier in the CSS to align everything using <strong>flexbox</strong>.</p>
<p>Alongside that, we added a <code>class</code> for each element because we want to style them individually in the CSS and then we used the <code>appendChild</code> to add these elements into the DOM at the end of the <code>forEach</code> function.</p>
<p>And lastly, we have a <code>numberWithComma</code> function from StackOverflow which will add a comma as a thousand separator for the <code>population</code> number.</p>
<h3 id="heading-step-3-update-the-view-based-on-the-search-query">Step 3 - update the view based on the search query</h3>
<p>In this final step we're going to get the search query from the <code>input</code> by attaching an <code>eventListener</code> on it, and we're going to modify our <code>showCountries</code> function so that it will <code>filter</code> out the values we don't want to be displayed. Let's see how we can do that:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> search_input = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'search'</span>);

<span class="hljs-keyword">let</span> search_term = <span class="hljs-string">''</span>;

search_input.addEventListener(<span class="hljs-string">'input'</span>, <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
    <span class="hljs-comment">// saving the input value</span>
    search_term = e.target.value;

    <span class="hljs-comment">// re-displaying countries based on the new search_term</span>
    showCountries();
});

<span class="hljs-keyword">const</span> showCountries = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-comment">// clear the results</span>
    results.innerHTML = <span class="hljs-string">''</span>;

    <span class="hljs-comment">// see code above at Step 2.</span>

    countries
        .filter(<span class="hljs-function"><span class="hljs-params">country</span> =&gt;</span>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(<span class="hljs-function"><span class="hljs-params">country</span> =&gt;</span> {
            <span class="hljs-comment">// see code above at Step 2.</span>
        });

    <span class="hljs-comment">// see code above at Step 2.</span>
};
</code></pre>
<p>As you can see we added two new things in the <code>showCountries</code> function:</p>
<ol>
<li>We are clearing the previous <code>results</code> by setting the <code>innerHTML</code> to an empty string</li>
<li>We are filtering the <code>countries</code> by checking if the entered <code>search_term</code> is <code>included</code> in the <code>name</code> of the country, and we're also converting these two values <code>toLowerCase</code> as the user might type in upperCase letters and we still want to display the corresponding country</li>
</ol>
<h2 id="heading-the-entire-js-code">The entire JS Code</h2>
<p>Below you can find the entire JS code in case you want to copy it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> search_input = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'search'</span>);
<span class="hljs-keyword">const</span> results = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'results'</span>);

<span class="hljs-keyword">let</span> search_term = <span class="hljs-string">''</span>;
<span class="hljs-keyword">let</span> countries;

<span class="hljs-keyword">const</span> fetchCountries = <span class="hljs-keyword">async</span> () =&gt; {
    countries = <span class="hljs-keyword">await</span> fetch(
        <span class="hljs-string">'https://restcountries.eu/rest/v2/all?fields=name;population;flag'</span>
    ).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json());
};

<span class="hljs-keyword">const</span> showCountries = <span class="hljs-keyword">async</span> () =&gt; {
    results.innerHTML = <span class="hljs-string">''</span>;

    <span class="hljs-keyword">await</span> fetchCountries();

    <span class="hljs-keyword">const</span> ul = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'ul'</span>);
    ul.classList.add(<span class="hljs-string">'countries'</span>);

    countries
        .filter(<span class="hljs-function"><span class="hljs-params">country</span> =&gt;</span>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(<span class="hljs-function"><span class="hljs-params">country</span> =&gt;</span> {
            <span class="hljs-keyword">const</span> li = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>);
            li.classList.add(<span class="hljs-string">'country-item'</span>);

            <span class="hljs-keyword">const</span> country_flag = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'img'</span>);
            country_flag.src = country.flag;
            country_flag.classList.add(<span class="hljs-string">'country-flag'</span>);

            <span class="hljs-keyword">const</span> country_name = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h3'</span>);
            country_name.innerText = country.name;
            country_name.classList.add(<span class="hljs-string">'country-name'</span>);

            <span class="hljs-keyword">const</span> country_info = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
            country_info.classList.add(<span class="hljs-string">'country-info'</span>);

            <span class="hljs-keyword">const</span> country_population = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h2'</span>);
            country_population.innerText = numberWithCommas(country.population);
            country_population.classList.add(<span class="hljs-string">'country-population'</span>);

            <span class="hljs-keyword">const</span> country_popupation_text = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'h5'</span>);
            country_popupation_text.innerText = <span class="hljs-string">'Population'</span>;
            country_popupation_text.classList.add(<span class="hljs-string">'country-population-text'</span>);

            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(<span class="hljs-string">'input'</span>, <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
    search_term = e.target.value;
    showCountries();
});

<span class="hljs-comment">// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">numberWithCommas</span>(<span class="hljs-params">x</span>) </span>{
    <span class="hljs-keyword">return</span> x.toString().replace(<span class="hljs-regexp">/\B(?=(\d{3})+(?!\d))/g</span>, <span class="hljs-string">','</span>);
}
</code></pre>
<h2 id="heading-the-css">The CSS</h2>
<p>Finally, let's add some styling to our little app:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@import</span> url(<span class="hljs-string">'https://fonts.googleapis.com/css?family=Roboto:300,500&amp;display=swap'</span>);

* {
    <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">135deg</span>, #f5f7fa <span class="hljs-number">0%</span>, #c3cfe2 <span class="hljs-number">100%</span>);
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Roboto'</span>, sans-serif;

    <span class="hljs-attribute">display</span>: flex;
    <span class="hljs-attribute">align-items</span>: center;
    <span class="hljs-attribute">justify-content</span>: center;
    <span class="hljs-attribute">flex-direction</span>: column;

    <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
}

<span class="hljs-selector-class">.countries</span> {
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">list-style-type</span>: none;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">480px</span>;
}

<span class="hljs-selector-class">.country-item</span> {
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">3px</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">3px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.3</span>);
    <span class="hljs-attribute">display</span>: flex;
    <span class="hljs-attribute">justify-content</span>: space-between;
    <span class="hljs-attribute">align-items</span>: center;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span> <span class="hljs-number">10px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">10px</span> <span class="hljs-number">0</span>;
}

<span class="hljs-selector-class">.country-item</span><span class="hljs-selector-pseudo">:hover</span> {
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">8px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.4</span>);
}

<span class="hljs-selector-class">.country-flag</span> {
    <span class="hljs-attribute">width</span>: <span class="hljs-number">40px</span>;
}

<span class="hljs-selector-class">.country-name</span> {
    <span class="hljs-attribute">flex</span>: <span class="hljs-number">2</span>;
    <span class="hljs-attribute">font-weight</span>: normal;
    <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">0.5px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> <span class="hljs-number">5px</span>;
    <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-class">.country-info</span> {
    <span class="hljs-attribute">border-left</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#aaa</span>;
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#777</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">15px</span>;
    <span class="hljs-attribute">flex</span>: <span class="hljs-number">1</span>;
}

<span class="hljs-selector-class">.country-population</span> {
    <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">300</span>;
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">24px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">12px</span>;
}

<span class="hljs-selector-class">.country-population-text</span> {
    <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">300</span>;
    <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">1px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">text-transform</span>: uppercase;
}

<span class="hljs-selector-tag">input</span> {
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Roboto'</span>, sans-serif;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">3px</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">480px</span>;
}
</code></pre>
<p>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! ?</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>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! ?</p>
<p>As always, make sure you share what you're going to create!</p>
<p>Happy Coding! ?</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
