Ensure user selects item from filtered <UL> in an html form

28 Views Asked by At

I have an html form with multiple <input> tags (Name, date, time, ordernumber, task, notes are the main inputs). In the ordernumber input, when the user starts typing, a <ul> appears and is filtered based on what the user types into the ordernumber input. I want them to select from the list before moving to the next field. This is for data validation reasons. So if they type mee in the input, MEETINGS will appear in the list. mee is not valid data for when the form is submitted.

onblur=function() doesn't work - it shows the list without being filtered when the form is loaded. document.getElementById('myInput').addEventListener('blur', function() {} along with document.getElementById('myUL').orderlistElement.querySelector('li.active') sort of works as it detects that a selection hasn't been made. It tells the user (via an alert()) that they have left the input box without making a selection, but they have to leave the box to make the selection so it comes up everytime.

I perform validation on the form inputs upon submission, but I will like to bring the issue to attention of the user at the point it occurs.

I can't even think of the logic, before I even attempt the code. Maybe there is an industry term for what I am trying to achieve.

It's something like:

  1. check user has left the <input>,
  2. set a status variable,
  3. if next operation is selection from list then great otherwise show error message and focus back on order <input>.

I guess my question is simply, what is the logic? Hopefully I have included sufficient information.

The code to solve my problem is below. It was made easier by only having to apply it to one field. (Having said that I need to do some more testing as it probably won't work if they user goes back to the hours or dateworked inputs.).

document.addEventListener('DOMContentLoaded', function() {
      var myInputField = document.getElementById("myInput");
      var notesTextarea = document.getElementById("notes");
      var myList = document.getElementById("myUL");

      notesTextarea.addEventListener('focus', function() {
        var inputValue = myInputField.value;

        // Check if the list is currently displayed
        var computedStyle = window.getComputedStyle(myList);   // this gets the properties of the CSS stylings for the id myList, which is the variable of the id "myInput"
        var isListDisplayed = computedStyle.getPropertyValue('display') !== 'none';


        // Display the appropriate alert message
        if (isListDisplayed) {
            // return focus to order number input
            myInputField.focus(); 
            alert("You haven't made a selection.") ;
        }
        // If not displayed, do nothing
      });
    });
1

There are 1 best solutions below

4
Chad Phillips On

When the input has focus and it has a value, display the filtered results. When one of the filtered results is selected, set the value of the input equal to the the selected item.

Selecting a value will trigger the blur event for the input. On the blur event for this input, call a function that waits a beat (avoiding the race condition between onblur firing and the value being set) and then tests to see if the input value is equal to any of the values in the list. If not, tell the user they need to enter/select a value and add focus back to the input.