3

Binding a click event on the item list, the box keeps disappearing. Any idea why click event not working on item-list > div.

The idea is to fetch the text(from item-list) that is being clicked and put it in the input field ?

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');
    $(".item-list div").click(function() {
      var inputValue = $('.input-msg');
      var data = $(this).text();
      inputValue.val(data);
    });
  }).blur(function() {
    $(".item-list").css('display', 'none');
  });
})();
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
  </div>
</div>

4
  • 1
    your question is not clear? what you exactly want to achieve? and what problem you are facing? Commented Jul 22, 2017 at 5:04
  • 1
    please explain what you're trying to do, because from reading your code, i am still not sure what you're trying to do. Commented Jul 22, 2017 at 5:07
  • Don't attach click listener in the focus handler, you end up to add a new listener every time the element gets the focus. Commented Jul 22, 2017 at 5:11
  • on click on the item list, its doen't insert the text, click function doesn't work ? also hide the item-list on body click Commented Jul 22, 2017 at 5:18

4 Answers 4

4

I think I got your Problem:-

1.remove blur code. (because it's hiding div immediately when focus out from the input-box)

2.Put click outside of focus. (register listener only one-time which is enough)

3.Inside click do the hide code. (if you want to hide div after clicking on it's text div's)

Working snippet:-

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');
    
  });
  $(".item-list div").click(function() {
      var inputValue = $('.input-msg');
      var data = $(this).text();
      inputValue.val(data);
      $('.item-list').hide();
  });
})();
$(document).mouseup(function(e) {
  if (!$(e.target).is('.item-list') && !$(e.target).is('.input-msg')) {
    $('.item-list').hide(1000);
  }
});
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item Two</div>
    <div>This is item Three</div>
    <div>This is item Four</div>
  </div>
</div><br>

Sign up to request clarification or add additional context in comments.

1 Comment

on click outside of the div , does not hide the div container , any idea why ?
1

Take a look at this.

(function() {
  $(".item-list div").click(function() {
    var inputValue = $('.input-msg');
    var data = $(this).text();
    inputValue.val(data);
    $('.item-list').fadeOut('fast');
  });
  $(".input-msg").focus(function() {
    $(".item-list").fadeIn('fast');        
  })
  $(document).mouseup(function(e) {
    if (!$(e.target).is('.item-list') && !$(e.target).is('.input-msg')) {
      $('.item-list').fadeOut('fast');
    }
  });
})();
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item two</div>
    <div>This is item three</div>
    <div>This is item four</div>
  </div>
</div>

3 Comments

@webmansa and Kira San why again $(".item-list div").click(function() { inside focus event handler. its really bad practice to register a listener every-time on focus of an element. Put it outside. We have already mentioned that in our answers
@AlivetoDie Thanks for pointing that out, I was on a hurry and didn't notice that.
@KiraSan now the answer is perfect. so +1
1

The item list disappears, because on a blur event triggered by the input box, the list is cleared. I've commented out the code that is hiding the list, and moved it down to happen on the item list click.

I've also moved the list click handler from inside your blur handler. This will prevent the click handler from being mounted again and again.

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');

  }).blur(function() {
 
    // THIS IS YOUR ISSUE.
    // We're going to move this line down to the 
    // `item-list` click handler.
    // $(".item-list").css('display', 'none');

  });

  // You want to register this listener once,
  // not every time user focuses on input box.
  $(".item-list div").click(function() {
    var inputValue = $('.input-msg');
    var data = $(this).text();
    inputValue.val(data);
  });

  $('.main-wrapper').children().not('.input-wrapper').click(function(){
    // Hide the item list on body click.
    // This was moved here from the `blur` handler above.
    $(".item-list").css('display', 'none');
  });

})();
.main-wrapper {
  float: left;
  width: 600px;
}
  
.other-wrapper {
 float: left;
 width: 300px;
}

.input-wrapper {
  float: left;
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-wrapper">
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
  </div>
</div>
<div class="other-wrapper">Other stuff.</div>
<div>

3 Comments

on blur , i also want to hide the item list ?
i mean on body click , outside of the item-list div hide the div ? do you understand ?
i think so, try it now.
0
const input = $("input")
const itemList = $(".item-list")
const items = $(".item-list > div")
const overlay = $(".overlay")

addClickTo(input, () => display(itemList, overlay))
addClickTo(items, (e) => {
  const itemText = e.currentTarget.textContent
  setValueOf(input, itemText)
  dontDisplay(itemList, overlay)
})
addClickTo(overlay, () => dontDisplay(itemList, overlay))


// helpers
function dontDisplay(...elements) { elements.forEach((element) => element.style.display = "none") }
function display(...elements) { elements.forEach((element) => element.style.display = "block") }
function $(selector) {
  const matchedElements = document.querySelectorAll(selector)
  return matchedElements && matchedElements.length > 1
  ? matchedElements
  : matchedElements[0]
}
function addClickTo(elements, handler) {
  elements.forEach || (elements = [elements])
  elements.forEach((element) => element.addEventListener("click", handler))
}
function setValueOf(input, text) {
    input.value = text
}

const input = $("input")
const itemList = $(".item-list")
const items = $(".item-list > div")
const overlay = $(".overlay")

addClickTo(input, () => display(itemList, overlay))
addClickTo(items, (e) => {
  const itemText = e.currentTarget.textContent
  setValueOf(input, itemText)
  dontDisplay(itemList, overlay)
})
addClickTo(overlay, () => dontDisplay(itemList, overlay))


// helpers
function dontDisplay(...elements) { elements.forEach((element) => element.style.display = "none") }
function display(...elements) { elements.forEach((element) => element.style.display = "block") }
function $(selector) {
  const matchedElements = document.querySelectorAll(selector)
  return matchedElements && matchedElements.length > 1
  ? matchedElements
  : matchedElements[0]
}
function addClickTo(elements, handler) {
  elements.forEach || (elements = [elements])
  elements.forEach((element) => element.addEventListener("click", handler))
}
function setValueOf(input, text) {
	input.value = text
}
.item-list {
  display: none;
  position: relative;
  cursor: pointer;
}

input {
  position: relative;
}

.overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<div class="input-wrapper">
  <div class="overlay"></div>
  <input type="text" class="input-msg" placeholder="click me">

  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item two</div>
    <div>This is item three</div>
    <div>This is item four</div>
  </div>
</div>

https://jsfiddle.net/dvekrebv/6/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.