How to detect all the component while reusing the component within a page?


#1

Hi, 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


#2

The direct answer to your question is to have each dropdown component register itself with a service, so that you have access to a list of all dropdown components.

Dropdowns are hard, however. Have you considered an addon like ember-power-select?