1
\$\begingroup\$

I am using the code below trying to replicate the mobile phone feature that displays one or more contact names according to the numbers typed.

This code is intended to be used on a JavaScript course I am teaching, so I try to keep it as simple as possible in order to walk the students through a possible scenario and the required steps to implement a solution programmatically.

I would like to hear any suggestions for changes or comments before moving this example to class.

Thank you very much!

(You can find the full code, along with some pretty styling at this codepen link)

HTML:

<div class="tryout">
  <p>Numbers to try:</p>
  <p><span></span></p>
</div>
<div class="mobile">
  <label for="number">Send SMS</label>
  <input type="text" id="number" name="number" placeholder="Enter telephone number">  
</div>

<div class="found"></div>

JAVASCRIPT:

const contacts = {
  kostas: 6986100100,
  maria: 6986100200,
  george: 6986300300,
  sofia: 6986300400,
  chris: 6987500500,
  marina: 6944600600
}

const input = document.querySelector("#number");
const found = document.querySelector(".found");

input.addEventListener( "keyup", handleKeyUp );

function handleKeyUp( e ){

  found.innerHTML = "";

  Object.entries(contacts).map((contact)=>{

    let [ key, value ] = contact;
    let inputValue = e.target.value;
    value = String( value );
    if ( value.indexOf( inputValue ) === 0 ){
      found.innerHTML += `
        <p id="${key}">
          <strong>${key}</strong>: 
          ${value.replace( inputValue, `<span>${ inputValue }</span>` )}
        </p>
      `;

    }

  })
}

NOTES: Since this is intended for an audience of beginners, best practices, code organization and probably performance considerations are of great importance here.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Is this all in global scope? it depends how far down the rabbit hole you go with this, obviously having functions and variables in global scope is bad practice but this may not be something you tackle with beginners? \$\endgroup\$
    – mbx-mbx
    Oct 16, 2019 at 12:16
  • \$\begingroup\$ Yep, that is a nice addition @Magrangs. Will definitely update my code. I got to excited when I got the inspiration while I was texting a friend, so I ended up coding this without realizing I was in global scope. Thanks! :) \$\endgroup\$ Oct 16, 2019 at 13:09

1 Answer 1

2
\$\begingroup\$

Here's a few suggestions:

I would model the contacts list as an array of objects, like this:

const contacts = [
  { name: 'kostas', number: '6986100100' },
  { name: 'maria', number: '6986100200' },
  { name: 'george', number: '6986300300' },
  { name: 'sofia', number: '6986300400' },
  { name: 'chris', number: '6987500500' },
  { name: 'marine', number: '6944600600' }
];

If you use your contacts' first name as object keys, you can't have two contacts with the same name. Moreover, if each contact is represented by an object, you can add additional information to the contact in the future. I would also write the phone numbers as a string, not a number, since phone numbers can contain non-digit characters (like '+') or leading zeros.

The search returns a list of corresponding contacts, so you might as well replace the results div with a list, a <ul class="found"></ul> for example.

Searching for and displaying the matches becomes easy now:

function handleKeyUp(e) {
  const inputValue = e.target.value.trim();

  if (inputValue) {
    found.innerHTML = contacts
      .filter(contact => contact.number.startsWith(inputValue))
      .map(
        contact =>
          `<li><strong>${contact.name}</strong>: ${contact.number.replace(
            inputValue,
            `<span>${inputValue}</span>`
          )}</li>`
      )
      .join('');
  } else {
    found.innerHTML = '';
  }
}

No need to convert the input value to a string, it's a string already. Notice how there's only one call to found.innerHTML. Your code updated the dom once for each found match, but dom operations are expensive and should be minimized.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.