0

I'm trying to figure out how to direct the focus on these objects to get auto complete to go away when it's not needed.

I'll post the code and then explain what I've tried. The only issue with writing too much is that it scares some people away so I'll be brief yet thorough!

This is the library I'm using http://complete-ly.appspot.com/

jQuery

var autocontainer = link.siblings('.food-input-div');
       autocontainer.show();
       link.hide();

       var autoobj = completely(autocontainer[0]);
       autoobj.options = ['chicken', 'cheese', 'chobani', 'chocolate', 'chum', 'cherries', 'coka-cola', 'coconut', 'crack', 'cocain', 'creme brule'];
       autoobj.repaint();

       autoobj.input.focus();
       
       var wrapper = $(autoobj.wrapper);
       
       console.log(wrapper);
       console.log(document.activeElement);

       wrapper.attr("tabindex", "0");
       wrapper.focusout(function() {
           autocontainer.hide();
           link.show();
           this.remove();
       });            

      

The DOM

<td class="left">
    <a class="add-food-link">+ Add food</a>
    <div class="food-input-div" style="display:none;"></div>
</td> 

Complete.ly adds code similar to this directly inside the 'food-input-div' element

<div>
<div>
<input>
<input>
<div>
<div>list item</div>
<div>list item</div>
<div>list item</div>
<div>list item</div>
</div>
</div>
</div>

My jQuery gives the first 'wrapper' element of complelys code a tabindex of 0 so that it is able to having a focus.

The issue is this:

When I click the link:

  • Link is removed
  • completely box is rendered
  • completely wrapper input has focus

When a item from the dropdown is clicked:

  • Everything is removed and link is rendered

I don't understand why this is happening because focusout is bound to those individual element's parent element.

I toyed around with the assumption that children elements receive focus here and found that is false. http://jsfiddle.net/adiakritos/nU988/

So now I need to get it so that only when ANY element outside of "food-input-div" is clicked, said element and it's children are removed, and the link is redisplayed.

How do I do this?


Playing with this right now:

Use jQuery to hide a DIV when the user clicks outside of it


This is the code I have working nicely right now. Except I still can't click list items.

   $(document).mouseup(function (e){

     if (!wrapper.is(e.target) && wrapper.has(e.target).length === 0){

       autocontainer.hide();
       link.show();
       autoobj.wrapper.remove();
       console.log(e);

     };
   }); 

Now when I get click the drop down e.target returns the element directly under the div I'm clicking.

So if I click "cheese" and there's a h4 element that is part of the layout under it, e.target returns that h4 instead of the drop down div list item.


Implementing Dropped.On.Caprica's Code

var showFoodSearch = function(link) {
   var autocontainer = link.siblings('.food-input-div');
   autocontainer.show();
   link.hide();

   var autoobj = completely(autocontainer[0]);
   autoobj.options = ['chicken', 'cheese', 'chobani', 'chocolate', 'chum', 'cherries', 'coka-cola', 'coconut', 'crack', 'cocain', 'creme brule'];
   autoobj.repaint();
   autoobj.input.focus();

   var wrapper = $(autoobj.wrapper);
    
    wrapper.on('blur', 'input', function(){

       autocontainer.hide();
       link.show();
       autoobj.wrapper.remove();
       $(document).mouseup(function(e){
            console.log(e.target);
       });

    });

};      

Same exact behavior as described above this try.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nick Res
  • 2,154
  • 5
  • 30
  • 48
  • A couple tips to help you get some responses. What validation plugin are you using? I see the `completely()` call, but I can't find any library with that name. Why are you using `div`'s instead of input fields? You also might play with using `.on()` events set on the wrapper. If you are dynamically adding/ removing items events won't be set on new elements added. Hope that helps! – AlbertEngelB Feb 11 '14 at 19:53
  • Thanks so much! I added the link to the library at the top of question. The food-input-div is just a wrapper. The inputs are inserted by complete.ly. The final link I posted referencing to someone else's answer it helpful, but now I need to make sure that the if statement is including all the children and not just the direct children of the wrapper. – Nick Res Feb 11 '14 at 20:04
  • So do me a favor and try this: `$().on('blur', 'input', function() { });` – AlbertEngelB Feb 11 '14 at 20:13
  • The behavior is exactly the same. It works as intended when I click the body. But when I click the list item elements only the elements under then are returned. I'll post the code in my question so you see what I'm doing. – Nick Res Feb 11 '14 at 20:19

1 Answers1

0

This is how I got the JS to work exactly how I wanted it to:

       var autocontainer = link.siblings('.autocomplete');
       autocontainer.show();
       link.hide();

       var autoobj = completely(autocontainer[0]);
       autoobj.options = ['chicken', 'cheese', 'chobani', 'chocolate', 'chum', 'cherries', 'coka-cola', 'coconut', 'crack', 'cocain', 'creme brule'];
       autoobj.repaint();
       autoobj.input.focus();

       var wrapper = $(autoobj.wrapper);

       $(document).click(function() {
           var focus = document.activeElement;
           if ( focus === document.body ) {
               autocontainer.hide();
               link.show();
               autoobj.wrapper.remove();
           }
       });  

The $(document).click(function() { part checks for any clicks to the main doc element... then it determines what the focus is... if it's on the body (where users normally click to close out of something) it'll hide the drop down.

Nick Res
  • 2,154
  • 5
  • 30
  • 48