70611

How to implement search feature using vanilla javascript?

Question:

I have made a contact list app which shows the contact details. I want to implement search feature based on name. Now when I type in someone's name it should dynamically change the contact list.

index.html :

<pre class="snippet-code-js lang-js prettyprint-override">var array = []; function Person(fullName, number, group) { this.fullName = fullName; this.number = number; this.group = group; array.push(this); } Person.prototype.getFullName = function() { return this.fullName+' '+this.number+' '+this.group; } var p1 = new Person("Jonathan Buell",5804337551,"family"); var p2 = new Person("Patrick Daniel",8186934432,"work"); console.log(array); /* function save() { localStorage.setItem("array", JSON.stringify(array)); } function submitToDb() { var person = new Person(nameInput.value, numberInput.value, groupInput.value); // refresh(); } var storedArray = JSON.parse(localStorage.getItem("array")); function loadLocalStorage() { for(var i in storedArray){ array[i] = storedArray[i]; } // refresh(); } loadLocalStorage(); */ function showContacts() { for(var i in array){ var id = i; contactlist.innerHTML += ` <ul> <div>

Name: `+ array[i].fullName +`

Number: `+ array[i].number +`

Group: `+ array[i].group +`

<button type="button" class="btn btn-warning" onclick="editContact(`+ id +`)">Edit</button> <button type="button" class="btn btn-danger">Delete</button> </div> ` } } showContacts(); function addNew() { document.getElementById("search").style.display = 'none'; document.getElementById("contactlist").style.display = 'none'; document.getElementById("editcontact").style.display = 'none'; document.getElementById("addnewcontact").style.display = ''; document.getElementById("addnewcontact").innerHTML = ` <form> <div class="form-group"> <label for="inputName">Name</label> <input type="text" class="form-control" id="inputName" aria-describedby="namehelp" placeholder="Enter Name"> </div> <div class="form-group"> <label for="inputNumber">Number</label> <input type="text" class="form-control" id="inputNumber" aria-describedby="numberhelp" placeholder="Enter Number"> </div> <div class="form-group"> <label for="inputGroup">Group</label> <input type="text" class="form-control" id="inputGroup" aria-describedby="grouphelp" placeholder="Enter Group"> </div> <button type="submit" class="btn btn-primary" onclick="submittoDB()">Submit</button> </form> `; } function editContact(id) { document.getElementById("search").style.display = 'none'; document.getElementById("contactlist").style.display = 'none'; document.getElementById("editcontact").style.display = ''; document.getElementById("editcontact").innerHTML = ` <form> <div class="form-group"> <label for="InputName2">Name</label> <input type="text" class="form-control" id="inputName2" aria-describedby="namehelp" value="`+array[id].fullName+`" > </div> <div class="form-group"> <label for="InputNumber2">Number</label> <input type="text" class="form-control" id="inputNumber2" value="`+array[id].number+`"> </div> <div class="form-group"> <label for="InputGroup2">Group</label> <input type="text" class="form-control" id="inputGroup2" value="`+array[id].group+`"> </div> <button type="submit" class="btn btn-primary" onclick="saveMe(`+id+`)">Submit</button> </form> `; } /* function saveMe(id) { array[id].fullName = document.getElementById("nameInput2").value; array[id].number = document.getElementById("numberInput2").value; array[id].group = document.getElementById("groupInput2").value; } */ function deleteMe(id) { array.splice(id, 1); // refresh(); // save(); }
<pre class="snippet-code-css lang-css prettyprint-override">.header{ display:flex; } .header>div{ float: left; } .header .title{ padding-left: 400px; } .header .dropdown{ padding-top: 20px; padding-left: 20px; } .header .button{ padding-left: 500px; padding-top: 5px; } .glyphicon-plus-sign{ font-size: 50px; } #search form .input-group{ padding-left: 30px; padding-right: 30px; padding-bottom: 10px; } .input-group{ padding-top: 20px; } .form-group{ padding-left: 30px; padding-right: 30px; } form .btn-primary{ margin-left: 30px; } <pre class="snippet-code-html lang-html prettyprint-override"><!DOCTYPE html> <html> <head> <title>Contact List App</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <link rel="stylesheet" type="text/css" href="index.css"> <script type="text/javascript" src="app.js"></script> </head> <body> <div class="header"> <div id="dropdown"> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Sort by Group <span class="caret"></span></button> <ul class="dropdown-menu"> <li><a href="#">All</a></li> <li><a href="#">Work</a></li> <li><a href="#">Family</a></li> </ul> </div> </div> <div class="title"> <h2>All Contacts</h2> </div> <div class="button" id="addButton">

<a href="#"> <span class="glyphicon glyphicon-plus-sign" onclick="addNew()"></span> </a>

</div> </div> <div id="search"> <form> <div class="input-group"> <input type="text" class="form-control" placeholder="Search"> <div class="input-group-btn"> <button class="btn btn-default" type="submit"> <i class="glyphicon glyphicon-search"></i> </button> </div> </div> </form> </div> <div id="contactlist" > </div> <div id="addnewcontact"> </div> <div id="editcontact"> </div> </body> </html>

Currently I am dynamically populating 3 div tag with id="contactlist" , id="editcontact" id="addnewcontact"

App live demo : <a href="https://jsfiddle.net/ap8xvoo7/" rel="nofollow">https://jsfiddle.net/ap8xvoo7/</a>

screenshot of app: <a href="https://i.stack.imgur.com/JsV3E.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/JsV3E.png" data-original="https://i.stack.imgur.com/JsV3E.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Answer1:

Lot of irrelevant code in your snippets. But, generally, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter" rel="nofollow">Array.filter</a> is your friend:

const contacts = [ { fullName: 'Jonathan Buell', number: 5804337551, group: 'family' }, { fullName: 'Joey Whatever', number: 5454355351, group: 'family' }, { fullName: 'Patrick Daniel', number: 8186934432, group: 'work' } ]; contacts.filter(contact => contact.fullName.startsWith('Jo')); /* Result: [ { fullName: 'Jonathan Buell', number: 5804337551, group: 'family' }, { fullName: 'Joey Whatever', number: 5454355351, group: 'family' } ] */

…but startsWith is case-sensitive, it would return an empty array for lowercase 'jo'.

One solution is to use regex instead:

contacts.filter(contact => contact.fullName.match(/^jo/i)); contacts.filter(contact => contact.fullName.match(/^Jo/i)); /* The 'i' flag makes matching case-insensitive. Result is the same as above in both cases. */

You can create a filtering function easily:

const filterContacts = (startLetters, contacts) => contacts.filter(contact => contact.fullName.match(new RegExp(`^${startLetters}`, 'i')) );

…and use it like this:

filterContacts('jo', contacts); /* Result: [ { fullName: 'Jonathan Buell', number: 5804337551, group: 'family' }, { fullName: 'Joey Whatever', number: 5454355351, group: 'family' } ] */ filterContacts('pat', contacts); /* Result: [ { fullName: 'Patrick Daniel', number: 8186934432, group: 'work' } ] */

…and of course bind it to search input change:

searchInput.addEventListener('input', function(event) { const startLetters = event.target.value; const filteredContacts = filterContacts(startLetters, contacts); // …and display filteredContacts in your template });

Working snippet (requires a modern browser with ES2015 support):

<pre class="snippet-code-js lang-js prettyprint-override">document.addEventListener('DOMContentLoaded', function() { const contacts = [ { fullName: 'Jonathan Buell', number: 5804337551, group: 'family' }, { fullName: 'Joey Whatever', number: 5454355351, group: 'family' }, { fullName: 'Patrick Daniel', number: 8186934432, group: 'work' } ]; const filterContacts = (startLetters, contacts) => contacts.filter(contact => contact.fullName.match(new RegExp(`^${startLetters}`, 'i')) ); // populate the list with all contacts after the page is loaded: const contactList = document.querySelector('ul'); contactList.innerHTML = contacts .map(contact => `<li>${contact.fullName}, ${contact.number}</li>`) .join(''); // filter contacts when user types something into input, and replace the list contents with filtered contacts: document.querySelector('input').addEventListener('input', function(event) { const startLetters = event.target.value; const filteredContacts = filterContacts(startLetters, contacts); contactList.innerHTML = filteredContacts .map(contact => `<li>${contact.fullName}, ${contact.number}</li>`) .join(''); }); }); <pre class="snippet-code-html lang-html prettyprint-override"><input /> <ul></ul>

A small bonus: if you want to search anywhere, not just from the start (so <em>'ni'</em> would match <em>'Patrick Da<strong>ni</strong>el'</em>), just remove ^ from the regex.

Recommend

  • Error as Element is not clickable at point in selenium
  • How to implement search feature using vanilla javascript?
  • jQuery | Getting display of value when there is multiple of the same ID
  • Using email address from external HTML file to send email via google apps script
  • Get popover width in jquery
  • Symfony 2 form validation
  • Convert Javascript onkeypress to knockoutjs to call on enter
  • Page selector (block development)
  • EmberJS hasMany relationship and Fixtures
  • Eclipselink 2.4 + JPA + ManyToMany with additional column
  • error: constructor Player in class Player cannot be applied to given types;
  • Instead of adding another element It is landing to a another page
  • Dropdown menu with the dropdown-menu-right class does not align to the right
  • bootstrap 3 modal in meteor not showing
  • Bootstrap modal closes when dropdownlist inside fires selected index changed event
  • Change navbar in bootstrap if user login
  • xcode don't localize specific strings
  • Swift: Switch statement fallthrough behavior
  • Java Scanner input dilemma. Automatically inputs without allowing user to type
  • java.lang.NoClassDefFoundError: com.parse.Parse$Configuration$Builder on below Lollipop versions
  • Nant, Vault & Windows Integrated Authentication
  • Bug in WPF DataGrid
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • MySQL WHERE-condition in procedure ignored
  • Which linear programming package should I use for high numbers of constraints and “warm starts” [clo
  • what is the difference between the asp.net mvc application and asp.net web application
  • jQuery tmpl and DataLink beta
  • Web-crawler for facebook in python
  • How can I estimate amount of memory left with calling System.gc()?
  • Matrix multiplication with MKL
  • SQL merge duplicate rows and join values that are different
  • trying to dynamically update Highchart column chart but series undefined
  • Proper way to use connect-multiparty with express.js?
  • How to set the response of a form post action to a iframe source?
  • Binding checkboxes to object values in AngularJs
  • java string with new operator and a literal