2
votes

I have a simple Emberjs component, It consist of a single input field and a collection of divs iterating over items.

Initially, the items div is display: none when the input field is focused, the items div gets display: block.

Each item in the collection has an action handler that hits selectItem. With this CSS, clicking the item doesn't hit the action.

However, if the css rule: .items{ display: none; } is taken out (line 18 in CSS on the JS fiddle) then click gets through to the action.

Here's a JS fiddle http://jsfiddle.net/dylanjha/NQKvy/959/

A simple component:

App.DropDownComponent = Ember.Component.extend({
    selectedName: null,
    items: [{id: 1, name: 'one'}, {id: 2, name: 'two'}],
    actions: {
        selectItem: function(item){
            alert('Selected ' + item.name);
            this.set('selectedName', item.name);
        }
    }
});

And the component's template:

<script type="text/x-handlebars" id="components/drop-down">
  <h1>Drop Down</h1>
  <div>
   {{ input value=selectedName id="form-input" }}
    <div class='items'>
      {{#each item in items}}
        <div class='item' {{action 'selectItem' item}}>
           {{ item.name }}
        </div>
      {{/each}}
    </div>
  </div>
</script>

Some simple CSS styling the input and the items div

#form-input{
    width:200px;
    font-size:20px;
    padding:5px;
}
#form-input:focus + .items{
    opacity:1;
    display:block;
}
.items{
    font-size:20px;
    -webkit-transition:opacity .2s ease;
    width:200px;
    display:none;
}
1

1 Answers

2
votes

The problem is when you lose focus from your input box you are hiding the drop down. So even though it may look like you are clicking on the element, really you are clicking on nothing.

That being said, you'll need to keep the div in view until the action has been clicked (or whatever other reasons).

For that I'd probably use Ember.TextField and hook up to the focusIn event triggering the options, then close when it's been selected.

Custom TextField

App.TextField = Ember.TextField.extend({
  focusOut: function(evt) {
    this.sendAction('focus-out');
  },
  focusIn: function(){
    this.sendAction('focus-in');   
  }
});

Template

{{view App.TextField value=selectedName id='form-input' focus-in='open'}}
<div {{bind-attr class=':items visible:showItems:hideItems'}}>
  {{#each item in items}}
    <div class='item' {{action 'selectItem' item}}>
       {{ item.name }}
    </div>
  {{/each}}
</div>

Modified component

App.DropDownComponent = Ember.Component.extend({
    selectedName: null,
    visible: false,
    items: [{id: 1, name: 'one'}, {id: 2, name: 'two'}],
    actions: {
        selectItem: function(item){
            alert('Selected ' + item.name);
            this.set('selectedName', item.name);
            this.set('visible', false);
        },
        open: function(){
            this.set('visible', true);
        }
    }
});

http://jsfiddle.net/w7e9c/