4

I have styled a select field with a custom dropdown icon using this css on the select:

appearance: none;       /* remove default arrow */

And then using an absolutely positioned icon.

Now I want that icon when clicked to trigger the click event on the select field. I have tried using ViewChild to get the select element ref and trigger a click on it's nativeElement property but nothing happens.

@ViewChild('customInput') input: ElementRef;
click() {
  const ele = this.input.nativeElement as HTMLElement;
  ele.click();
  this.cd.detectChanges();
}

I have also tried template references:

<select #customInput>

<div class="arrow" (click)="customInput.click()"></div>

EDIT:

it is also worth noting that both approaches using .focus() instead does focus the element, but does not cause the dropdown list to appear.

Craig
  • 1,648
  • 1
  • 20
  • 45
  • https://stackoverflow.com/questions/46204003/trigger-click-in-typescript-property-click-does-not-exist-on-type-element – NnN Dec 03 '18 at 12:59
  • @NnN that posts deals with a typescript compilation error. The object is the same whether I infer it as Element or HtmlElement since after compilation that distinction does not exist. Therefore this is not the same problem. – Craig Dec 03 '18 at 13:01
  • https://stackoverflow.com/questions/430237/is-it-possible-to-use-js-to-open-an-html-select-to-show-its-option-list You cant get js to open a select dropdown... – Craig Dec 03 '18 at 13:24
  • @Craig can you tell about your problem in more clear way... we are confused what exactly you want to acheive – programoholic Dec 03 '18 at 13:26
  • And to be sure we talk about the same thing, consider providing a [mcve] on https://stackblitz.com –  Dec 03 '18 at 13:30
  • @programoholic I am attempting to get the select options to display programatically by clicking another element. – Craig Dec 03 '18 at 14:45

4 Answers4

2

I got there in the end.

It turns out that javaScript is unable to make a select field open in a normal way and so I rethought the problem and ended up using a background image positioned where the custom styled arrow would be. This is obviously slower as before I was using a material icon so it was just a font, now it is an image that it has to render - but the performance hit is so small i dont think it matters.

since the dropdown icon is now just a background image it is part of the select so when you click it you really click the select itself and that causes it to open correctly.

Craig
  • 1,648
  • 1
  • 20
  • 45
1

Craig, Here is a sample guide how you can open a select box programatically :

let openStatus = false;

function openSelect(){
openStatus = !openStatus;
var element = document.getElementById('names');
if(openStatus){
element.size = element.length;  
 } 
 else {
 element.size = 1;   
  }
}

function handleChange(){
 alert('element slected ... closed');
 openSelect();
 }
<select id="names" onchange="handleChange()">
    <option>Foso</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
    <option>Bar</option>
</select>


<button onClick="openSelect()"> open Select </button>

When you click on the button it opens the select box. and when you click again on the button or select any element , the select box gets closed. I have used raw html and JS to explain the workaround . You can implement the same technique in angular too. Let me know if you face any issue.

programoholic
  • 4,830
  • 5
  • 20
  • 59
  • This is a great answer however there are some problems with this approach that makes it not usable for me: 1. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select claims that browser support is patchy 2. this opens the select in a very strange way - the options are contained within the select. Thank you for the answer though it was very interesting. – Craig Dec 03 '18 at 14:43
  • https://www.w3schools.com/tags/att_select_size.asp w3schools also claims issues with size 2 and size 3 on some browsers however I dont know it that is true. – Craig Dec 03 '18 at 14:46
0

Try This

Your HTML

 <select #customInput (click)="SelectClick()">
   <option value="1">Option</option>
 </select>
 <div class="arrow" (click)="click()">Click Here</div>

Component

@ViewChild('customInput') input: ElementRef;
click() {
  alert('Div click');
  const ele = this.input.nativeElement as HTMLElement;
  ele.click();
 }
 SelectClick()
 {
  alert("Select Click");
 }
programoholic
  • 4,830
  • 5
  • 20
  • 59
Mohan Singh
  • 1,142
  • 3
  • 15
  • 30
0

If you are using mat-select from Material so just replace the below a line

const ele = this.input.nativeElement as HTMLElement;

with

const ele = this.input['trigger'].nativeElement as HTMLElement;