Today I am trying to make a custom select dropdown with Angular 7 and it's working fine when i putting static value in select options. But problem is when I am trying to use Angular *ngFor loop or *ngIf, Then the customisation is not working. Please see my HTML, CSS and Javascript code below.
HTML Working
<select class="selectOp" id="creator">
<option value="hide">Select Creator</option>
<option value="2010">Adam</option>
<option value="2011">Imran</option>
<option value="2012">Salma</option>
<option value="2013">Noor</option>
<option value="2014">Jamal</option>
<option value="2015">Hasan</option>
</select>
HTML Not Working in Angular *ngFor
<select class="selectOp">
<option *ngFor="let contentype of dataScoruc.contentype">
{{contentype}}
</option>
</select>
TS
ngOnInit() {
this.dropDownFunc();
}
dropDownFunc(){
$('.selectOp').each(function(){
var $this = $(this), numberOfOptions = $(this).children('option').length;
$this.addClass('select-hidden');
$this.wrap('<div class="select"></div>');
$this.after('<div class="select-styled"></div>');
var $styledSelect = $this.next('div.select-styled');
$styledSelect.text($this.children('option').eq(0).text());
var $list = $('<ul />', {
'class': 'select-options'
}).insertAfter($styledSelect);
for (var i = 0; i < numberOfOptions; i++) {
$('<li />', {
text: $this.children('option').eq(i).text(),
rel: $this.children('option').eq(i).val()
}).appendTo($list);
}
var $listItems = $list.children('li');
$styledSelect.click(function(e) {
e.stopPropagation();
$('div.select-styled.active').not(this).each(function(){
$(this).removeClass('active').next('ul.select-options').hide();
});
$(this).toggleClass('active').next('ul.select-options').toggle();
});
$listItems.click(function(e) {
e.stopPropagation();
$styledSelect.text($(this).text()).removeClass('active');
$this.val($(this).attr('rel'));
$list.hide();
//console.log($this.val());
});
$(document).click(function() {
$styledSelect.removeClass('active');
$list.hide();
});
});
}
CSS
.select-hidden {
display: none;
visibility: hidden;
padding-right: 10px;
}
.select {
cursor: pointer;
display: inline-block;
position: relative;
font-size: 14px;
color: #4d4d4d;
width: 100%;
height: auto;
}
.select-styled {
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: white;
padding: 4px 15px;
border: 1px solid #dfdfdf;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
}
.select-styled:after {
content:"";
width: 0;
height: 0;
border: 5px solid transparent;
border-color: #4D4D4D transparent transparent transparent;
position: absolute;
top: 14px;
right: 10px;
}
.select-options {
display: none;
position: absolute;
top: 100%;
right: 0;
left: 0;
z-index: 999;
margin: 0;
padding: 0;
list-style: none;
background-color: #ffffff;
border: 1px solid #dededf;
border-radius: 4px;
}
.select-options li {
margin: 0;
padding: 4px 0;
text-indent: 15px;
font-size: 12px;
font-weight: 500;
}
.select-options li:hover {
color: #000000;
font-weight: 500;
font-style: italic;
}
.select-options li [rel="hide"] {
display: none;
}
Please everybody check it and put your suggestion please.
The JQuery code is executing before angular rendering its option
tags
you need to call this.dropDownFunc()
after angular finish it's rendering job, so you can call it from ngAfterViewInit
instead of ngOnInit
in order to use ngAfterViewInit
you may need to import its interface from @angular/core
import { Component , AfterViewInit} from '@angular/core';
and implements it with AppComponent
class
export class AppComponent extends Component implements AfterViewInit{
Here full source code
import { Component , AfterViewInit} from '@angular/core';
import $ from "jquery";
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent extends Component implements AfterViewInit{
dataScoruc={
contentype:[
'AAAAA',
'BBBB',
'CCCC',
'DDDD',
'EEEE',
'FFFFF',
]
}
ngOnInit() {
// this.dropDownFunc();
}
ngAfterViewInit(){
this.dropDownFunc();
}
dropDownFunc(){
$('.selectOp').each(function(){
var $this = $(this), numberOfOptions = $(this).children('option').length;
$this.addClass('select-hidden');
$this.wrap('<div class="select"></div>');
$this.after('<div class="select-styled"></div>');
var $styledSelect = $this.next('div.select-styled');
$styledSelect.text($this.children('option').eq(0).text());
var $list = $('<ul />', {
'class': 'select-options'
}).insertAfter($styledSelect);
for (var i = 0; i < numberOfOptions; i++) {
$('<li />', {
text: $this.children('option').eq(i).text(),
rel: $this.children('option').eq(i).val()
}).appendTo($list);
}
var $listItems = $list.children('li');
$styledSelect.click(function(e) {
e.stopPropagation();
$('div.select-styled.active').not(this).each(function(){
$(this).removeClass('active').next('ul.select-options').hide();
});
$(this).toggleClass('active').next('ul.select-options').toggle();
});
$listItems.click(function(e) {
e.stopPropagation();
$styledSelect.text($(this).text()).removeClass('active');
$this.val($(this).attr('rel'));
$list.hide();
//console.log($this.val());
});
$(document).click(function() {
$styledSelect.removeClass('active');
$list.hide();
});
});
}
}
and working demo (https://stackblitz.com/edit/angular-jq-dummy-select)