I have created a custom component which allows user to type and also select from a dropdown. The dropdown is a dynamic div. I have managed to close all the open dropdown on clicking outside of the dropdown.But if i click a component dropdown while the other component if the dropdown is open is not getting closed. I tried to make a common model/variable and enable it only on click but it dint work. Below are my HBS and JS files
custom-dropdown.hbs
<div class="custom-dropdown">
<div class="cus-drop-text">
{{input type=type value=inputValue id=dropdownTF class="editableDDText" }}
</div>
<div class="cus-drop-img" {{action 'showList'}}>
<div class="overlapDiv" >
</div>
<select id={{dropdownDD}} class="pull-left editableDDSelect">
{{#if hidealways}}
<option value="" hidden></option>
{{/if}}
</select>
</div>
{{#if showList}}
<div class="cus-drop-list {{isShowing}}" id="cus-drop-list">
{{#each optionlist as |option|}}
{{#if (eq selectedValue option)}}
<span class='active cus-drop-list-item' {{action 'onOptionChange' option}} data-value={{option}}>{{option}}</span>
{{else}}
<span class='cus-drop-list-item' {{action 'onOptionChange' option}} data-value={{option}}>{{option}}</span>
{{/if}}
{{/each}}
</div>
{{/if}}
custom-dropdown.js
import Ember from 'ember';
export default Ember.Component.extend({
inputName:"",
dropdownDD: "",
dropdownTF: "",
classNameBindings: ['isShowing'],
isShowing: 'visible',
showList:false,
hidealways:false,
isActive:false,
selectedValue: "",
inputValue:"",
didInsertElement() {
var self=this;
var clickFunction = function (event) {
var target = Ember.$(event.target);
if(target.context.className !== "overlapDiv"){
if(!self.isDestroyed){
self.set('showList',false);
}
}
};
window.addEventListener("click", clickFunction, false);
},
didReceiveAttrs() {
this.set('inputName',this.get('inputID'));
this.set('dropdownName',this.get('dropdownID'));
this.set('dropdownTF',this.get('inputName')+"TF");
this.set('dropdownDD',this.get('dropdownName')+"DD");
this.set('inputValue',this.get('value'));
},
keyPress(event){
this.validateInput(event);
},
validateInput(event) {
switch(this.get('allowedText')){
case "numOnly":
// Allow: backspace, delete, tab, escape, enter and numbers
if (Ember.$.inArray(event.keyCode, [8, 9, 13, 27, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]) !== -1 ||
// Allow: Ctrl+A, Command+A
(event.keyCode === 65 && (event.ctrlKey === true || event.metaKey === true))) {
// let it happen, don't do anything
if(Ember.$("#"+this.elementId+"TF").val().length < this.get('allowedCharLen')+1){
return;
}
else{
event.preventDefault();
}
}
else{
event.preventDefault();
}
break;
}
},
actions:{
focusOutFire:function(){
var self =this;
self.set('showList',false);
},
onOptionChange:function(selectedValue){
var self = this;
self.set('selectedValue',selectedValue);
self.set('showList',false);
self.set('inputValue',"");
self.set('inputValue',selectedValue);
},
showList:function(){
var self =this;
var showDropdown = true;
// To check if the dropdown is enabled or disabled
if(Ember.$("#"+this.get('dropdownID')+"DD").is(":disabled")){
showDropdown = false;
}
else{
showDropdown = true;
}
if(showDropdown){
if(self.get('showList')){
// Disabled Dropdown so don't show the list on click
self.set('showList',false);
}
else{
// Dropdown is enabled
self.set('showList',true);
}
}
}
}
});
Check the attached image. I want to close the already opened dropdown when clicking the other dropdown. Also suggest best practice to improve my ember coding in this component. Thank you for your help
My Problem is solved by calling the click function again using Jquery Also using mousedown is not effective in my case so im sticking to click event. This component allows user to type and also select a value from dropdown also able to select already selected value in dropdown. My final code is as below
Custom-dropdown.hbs component-hbs
<div class="custom-dropdown">
<div class="cus-drop-text">
{{input type=type value=inputValue id=dropdownTF class="editableDDText" }}
</div>
<div class="cus-drop-img" {{action 'showList'}}>
<div class="overlapDiv" >
</div>
<select id={{dropdownDD}} class="pull-left editableDDSelect">
{{#if hidealways}}
<option value="" hidden></option>
{{/if}}
</select>
</div>
{{#if displayList}}
<div class="cus-drop-list" id="cus-drop-list">
{{#each optionlist as |option|}}
{{#if (eq selectedValue option)}}
<span class='active cus-drop-list-item' {{action 'onOptionChange' option}} data-value={{option}}>{{option}}</span>
{{else}}
<span class='cus-drop-list-item' {{action 'onOptionChange' option}} data-value={{option}}>{{option}}</span>
{{/if}}
{{/each}}
</div>
{{/if}}
Custom-dropdown.js - component-js
import Ember from 'ember';
export default Ember.Component.extend({
inputName:"",
dropdownDD: "",
dropdownTF: "",
displayList:false,
hidealways:false,
isActive:false,
selectedValue: "",
inputValue:"",
didInsertElement() {
var self=this;
var clickFunction = function (event) {
var target = Ember.$(event.target);
if(target.context.className !== "overlapDiv"){
if(!self.isDestroyed){
self.set('displayList',false);
}
}
};
window.addEventListener("click", clickFunction);
},
didReceiveAttrs() {
this.set('inputName',this.get('inputID'));
this.set('dropdownName',this.get('dropdownID'));
this.set('dropdownTF',this.get('inputName')+"TF");
this.set('dropdownDD',this.get('dropdownName')+"DD");
this.set('inputValue',this.get('value'));
},
didDestroyElement(){
window.removeEventListener( 'click', clickFunction);
},
keyPress(event){
this.validateInput(event);
},
validateInput(event) {
switch(this.get('allowedText')){
case "numOnly":
// Allow: backspace, delete, tab, escape, enter and numbers
if (Ember.$.inArray(event.charCode, [8, 9, 13, 27, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]) !== -1 ||
// Allow: Ctrl+A, Command+A
(event.charCode === 65 && (event.ctrlKey === true || event.metaKey === true))) {
// let it happen, don't do anything
if(Ember.$("#"+this.elementId+"TF").val().length < this.get('allowedCharLen')+1){
return;
}
else{
event.preventDefault();
}
}
else{
event.preventDefault();
}
break;
}
},
actions:{
onOptionChange:function(selectedValue){
var self = this;
self.set('selectedValue',selectedValue);
self.set('displayList',false);
self.set('inputValue',"");
self.set('inputValue',selectedValue);
},
showList:function(){
var self =this;
var showDropdown = true;
// To check if the dropdown is enabled or disabled
if(Ember.$("#"+this.get('dropdownID')+"DD").is(":disabled")){
showDropdown = false;
}
else{
showDropdown = true;
}
// Dropdown is enabled so show the list
if(showDropdown){
if(self.get('displayList')){
// Hide the Dropdown list
self.set('displayList',false);
}
else{
// Hide all the open dropdown
Ember.$("body").click();
// Show the Dropdown list
self.set('displayList',true);
}
}
}
}
});
Component usage in HBS
{{custom-dropdown type="text" value=model.priceLessThan dropdownID="openingPrice" inputID="openingPrice" id="openingPrice" optionlist=content.opening allowedCharLen=5 allowedText="numOnly" actionName="opnPriceLessChange"}}