javascript novice
javascript novice

Reputation: 777

DropDown component CSS issue

I am building the below drop-down component using Angular-2.

My dropdown has autocomplete as well and it works well as of now. My problem is with the CSS. The requirement is that when the user types in the characters, they should appear greyed out and all the characters printed should appear greyed out in the autocomplete options suggestions as well.

In this image, as the user types opt, the characters are greyed out and all the autocomplete options listed also have opt greyed out. I am not sure how to implement this. My code: Plunker:https://plnkr.co/edit/13RV3khyFt56eVkuw8ww?p=preview

HTML:

  <input #input type="text" [(ngModel)]="query" (keyup)="filter($event)">
  <button  (click)="showAll(input)">
    <span class="tn icon-icon_Dropdown_Arrow tn-dropdown-icon"></span>
    <i aria-hidden="true"></i>
  </button>

  <ul id="list-group" *ngIf="filteredList.length > 0">
      <li *ngFor="let item of filteredList" [id]="item.selected" [class.selected]="item.selected" (click)="select(item)">
        {{ item.option}}
      </li>
  </ul>
  <div *ngIf="queryError">{{errorMsg}}</div>

Code for filtering (relevant parts):

filterQuery() {
     this.filteredList = this.items.filter((el: any) => {
       //return el.option.toLowerCase().substr(0,this.query.length) === this.query.toLowerCase();

   return el.option.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
 });

 if(this.query.length>1){
   if(!this.filteredList.length){
     this.queryError =true;
     //console.log("Query length",this.query.length);
   }
   else{
      this.queryError =false;
   }
 }
 else{
   this.queryError =false;
 }

}

filter(event: any) {

 if (this.query !== '') {
   if (this.opened) {
     if ((event.keyCode >= 48 && event.keyCode <= 57) ||
       (event.keyCode >= 65 && event.keyCode <= 90) ||
       (event.keyCode == 8)) {

       this.pos = 0;
       this.filterQuery();

     } else if (event.keyCode != 38 && event.keyCode != 40 && event.keyCode != 13) {
       this.filteredList = this.items;

     }
   } else {
     this.filterQuery();

   }
 } else {
   if (this.opened) {
     this.filteredList = this.items;

   } else {
     this.filteredList = [];
   }
 }

 for (let i = 0; i < this.filteredList.length; i++) {
   this.filteredList[i].selected = false;
 }

 if (this.selectedItem) {
   this.filteredList.map((i) => {
     if (i.id == this.selectedItem.id) {
       this.pos = this.filteredList.indexOf(i);
     }
   })
   this.selectedItem = null;
 }

 // Arrow-key Down
 if (event.keyCode == 40) {
   if (this.pos + 1 != this.filteredList.length)
     this.pos++;
 }
 //console.log(this.pos)

 // Arrow-key Up
 if (event.keyCode == 38) {
   if (this.pos > 0)
     this.pos--;
 }

 if (this.filteredList[this.pos] !== undefined)

   this.filteredList[this.pos].selected = true;

 //enter
 if (event.keyCode == 13) {
   if (this.filteredList[this.pos] !== undefined) {
     this.select(this.filteredList[this.pos]);
   }
 }

 // Handle scroll position of item
 let listGroup = document.getElementById('list-group');
 //console.log("listGroup",listGroup);
 let listItem = document.getElementById('true');
 //console.log("listItem",listItem)
 if (listItem) {
   listGroup.scrollTop = (listItem.offsetTop - 200);
 }

}

 select(item: any) {


   this.selectedItem = item;

   this.query = item.option;
   this.filteredList = [];
  // this.opened = false;
 }

showAll(input: any) { input.select();

 if (this.filteredList.length > 0) {
   this.opened = false;
   this.filteredList = [];
 } else {
   this.opened = true;
   this.filteredList = this.items;
 }
 if (this.query === '') {
   this.clearAll();
 }

 this.clearSelects();

}

Upvotes: 0

Views: 151

Answers (1)

shyammakwana.me
shyammakwana.me

Reputation: 5752

Well, it's not just a css issue. Because there is simple text populating in <li>'s adding a Pipe to your application will work, which will match typed query and then wrap around a span, and then we can do CSS work.

Demo

Added JS and CSS

CSS

.matching , .input-list {
  color: #ccc;

}

JS - src/autocomplete.ts

Add this after first line in your src/autocomplete.ts

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: string, query: string): string {  
    return value.split(query).join('<span class="matching">' + query + '</span>');
  }   
} 

Change LI in template to this

<li *ngFor="let item of filteredList" [class.active]="item.selected" [id]="item.selected" class="list-group-item item-list" (click)="select(item)"  [innerHTML]="item.name | exponentialStrength:query"></li>

Add below code to @Component

pipes: [ExponentialStrengthPipe]   

Demo image just for reference

Demo image just for reference

Upvotes: 1

Related Questions