javascript - Hide unordered list when losing parent focus -


i have input field. when user focuses on input unordered list appears beneath input.

when user clicks on 1 of list children data inserted input , unordered list hidden.

current problem

if user clicks on input , doesn't choose of options , click somewhere else in document unordered list remain shown.

i don't if there's kind of event i'm missing use solve this.

$('body').on('focus blur click', '.autocomplete input , .autocomplete ul,  .autocomplete li' , function() {    if (event.type === 'focus' && event.target.nodename == 'input') {     $(this).siblings('ul').show();   } else if ((event.type === 'blur' || event.type === 'click' ) && event.target.nodename == 'li') {    $(this).parent('ul').hide();   }    });      $('body').on('click' ,'li' ,function() {      $('#p1_first_name').val($(this).attr('data-value'));    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>  <div class="input__container autocomplete">      <div class="input__label__container">          <label for="p1_first_name" tabindex="999">autocomplete</label>      </div>      <input type="text" id="p1_first_name" class="text_field" autocomplete="off" value="">      <ul for="p1_first_name" style="display: none;">          <li tabindex="1" data-value="mad">madder</li>          <li tabindex="1" data-value="sad">sandy</li>      </ul>  </div>

notes

  • you can use object .on() pass in multiple event handlers. don't use if/else switch between different behaviors different events.
  • don't hard-code id of element want set js code. use data- attribute (see targetselector below).
  • work .closest() navigate correct elements.
  • use css positioning <ul> not push down content below.

$('body')      .on({          'focus': function() {              var $ul = $(this).closest('.autocomplete').find('ul');              $ul.width( $(this).width() ).show();          },          'blur': function() {              var $ul = $(this).closest('.autocomplete').find('ul');              settimeout(function () { $ul.fadeout('fast'); }, 250);          }      }, '.autocomplete input')      .on('click', '.autocomplete li', function() {          var targetselector = $(this).closest('ul').data('for');          $(targetselector).val( $(this).data('value') );          $(this).closest('ul').fadeout('fast');      });
.autocomplete {    position: relative;  }  .autocomplete ul {    display: none;    position: absolute;    margin: 0;    padding: 0;    list-style: none;    background-color: white;    box-shadow: 4px 4px 5px -2px rgba(0,0,0,0.59);    border: 1px solid #efefef;  }  .autocomplete ul li {    padding: 3px;    cursor: pointer;  }  .autocomplete ul li:hover {    background-color: #fcf3cf;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <div class="input__container autocomplete">      <div class="input__label__container">          <label for="p1_first_name" tabindex="999">autocomplete</label>      </div>      <input type="text" id="p1_first_name" class="text_field" autocomplete="off" value="">      <ul data-for="#p1_first_name">          <li data-value="mad">madder</li>          <li data-value="sad">sandy</li>      </ul>  </div>  <p>content below content below content below content below content below</p>


Comments