Project

General

Profile

1
import {Component, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange} from '@angular/core';
2
import {Value} from '../../searchPages/searchUtils/searchHelperClasses.class';
3
import {ISVocabulariesService} from './ISVocabularies.service';
4
import {RefineFieldResultsService} from '../../services/refineFieldResults.service';
5
//Usage example
6
//<static-autocomplete [(filtered)] =filtered [(selected)] =selected placeHolderMessage = "Search for countries" title = "Countries:" (keywordChange)="keywordChanged($event)"></static-autocomplete>
7

    
8
@Component({
9
    selector: 'static-autocomplete',
10
    styleUrls:  ['../autoComplete.component.css'],
11
    host: {
12
       '(document:click)': 'handleClick($event)',
13
   },
14
    template: `
15
        <span class="custom-autocomplete uk-width-1-1">
16
            <span   *ngIf = "showSelected && selectedValue != ''">
17
              <span  class="uk-alert-default" data-uk-alert=""  *ngFor="let item of selected"  [title]="showItem(item)"> <span >{{showItem(item)}} </span>
18
                <span (click)="remove(item)" aria-hidden="true" title="Remove selection" > <span class="clickable uk-icon">
19
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="1"><path fill="none" stroke="#000" stroke-width="1.06" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.06" d="M16,4 L4,16"></path></svg>
20
</span> </span>
21
              </span>
22
            </span>
23
            <input *ngIf = "showInput " type="text" class="auto-complete-input validate filter-input input-sm form-control  -width-small " [placeholder]=placeHolderMessage [(ngModel)]=keyword (keyup)=filter()   >
24
            <!--span [style.display]="showLoading ? 'inline' : 'none'" class="uk-alert uk-alert-primary" data-uk-alert=""> <i class="uk-icon-spinner"></i> Loading... </span>
25
            <span *ngIf="warningMessage.length > 0" class="uk-alert uk-alert-warning" data-uk-alert=""> {{warningMessage}} <a href="" class="uk-alert-close uk-close"></a></span-->
26
            <div  *ngIf="focus && showInput"  class="uk-dropdown" aria-expanded="true" style="display:block" >
27
                  <ul class="uk-nav uk-nav-autocomplete uk-autocomplete-results" >
28
                      <li>
29
                      <span [style.display]="showLoading ? 'inline' : 'none'" class="uk-alert uk-alert-primary" data-uk-alert=""> <i class="uk-icon-spinner"></i> Loading... </span>
30
                      <span *ngIf="filtered.length > 0"  >  {{results}} results found:</span>
31
                      <span *ngIf="filtered.length == 0" class="uk-alert uk-alert-primary" data-uk-alert=""> No results found</span>
32
                      </li>
33
                      <li    *ngFor=" let item of filtered">
34
                          <a (click)="select(item)"  [title]="showItem(item)" style="text-overflow: ellipsis; ">{{showItem(item)}}</a>
35
                      </li>
36
                  </ul>
37
            </div>
38
        </span>
39

    
40
        `
41
})
42
export class StaticAutoCompleteComponent implements OnChanges{
43
    @Input() placeHolderMessage = "Search for entries";
44
    @Input() title = "Autocomplete";
45
    @Output() addItem = new EventEmitter(); // when selected list  changes update parent component
46
    @Output() selectedValueChanged = new EventEmitter(); // when changed  a method for filtering will be called
47
    @Output() listUpdated = new EventEmitter(); // when changed  a method for filtering will be called
48
    @Input() public list = []; // the entries resulted after filtering function
49
    @Input() public filtered = []; // the entries resulted after filtering function
50
    @Input() public selected = []; // the entries selected from user
51
    @Input() public keywordlimit = 3; // the minimum length of keyword
52
    @Input() public showSelected = true; // the minimum length of keyword
53
    @Input() public multipleSelections:boolean = true;
54
    @Input() public allowDuplicates:boolean = false;
55
    @Input() public selectedValue:string = '';
56
    @Input() public vocabularyId:string ;
57
    @Input() public fieldName:string ;
58
    @Input() public entityName:string ;
59
    @Input() public fieldId:string ;
60

    
61
    @Input() public keyword = '';
62
    @Input() public type = 'search' //search, result, context, project
63
    public warningMessage = "";
64
    public infoMessage = "";
65
    public showLoading:boolean = false;
66
    public tries = 0;
67
    public showInput = true;
68
    public sub;
69
    public done = false;
70
    public results = 0;
71
    public focus:boolean  = false;
72
    public currentFieldId: string ;
73
    constructor ( private _vocabulariesService: ISVocabulariesService,private _refineService: RefineFieldResultsService, private myElement: ElementRef) {
74
            this.currentFieldId=this.fieldId;
75

    
76
    }
77
    ngOnDestroy(){
78
      if(this.sub && this.sub != undefined){
79
        this.sub.unsubscribe();
80
      }
81
    }
82

    
83
    ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
84
         if(this.currentFieldId!=this.fieldId){ //this is going to be called when
85
          this.currentFieldId=this.fieldId;
86
          this.initialize();
87
        }
88
    }
89
    private initialize(){
90

    
91
      this.showInput = true;
92
      if(this.list == undefined || this.list.length == 0){
93
        this.showLoading = true;
94

    
95
       if(this.vocabularyId){
96
        // this.list = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName);
97
        // this.afterListFetchedActions();
98
        this.sub = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName).subscribe(
99
            data => {
100
                this.list  = data;
101
                this.afterListFetchedActions();
102

    
103
            },
104
            err => {
105
                console.log(err);
106
                this.warningMessage = "An Error occured..."
107
            }
108
        );
109
      }else if(this.fieldName && this.entityName){
110
        // this.list = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName);
111
        this.sub = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName).subscribe(
112
            data => {
113
                this.list  = data;
114
                this.afterListFetchedActions();
115

    
116
            },
117
            err => {
118
                console.log(err);
119
                this.warningMessage = "An Error occured..."
120
            }
121
        );
122
      }else{
123
        this.showLoading = false;
124

    
125
      }
126
    }else{
127
      this.afterListFetchedActions();
128
    }
129

    
130
    }
131
    public updateList(list){ // used in claim context autocomplete
132
      this.list = list;
133
      this.afterListFetchedActions()
134
    }
135
    private afterListFetchedActions(){
136
      this.showLoading = false;
137
      this.getSelectedNameFromGivenId();
138
      this.listUpdated.emit({
139
          value: this.list
140
      });
141
      if(this.list == null || this.list.length == 0 ){
142
        this.warningMessage = "No results available";
143
        return;
144
      }
145
      this.done = true;
146
      if(this.keyword != ""){
147
        this.filter();
148
      }
149

    
150
    }
151
    filter() {
152
      this.focus = true;
153
      if(this.done){
154
        this.infoMessage = "";
155
        this.filtered = [];
156
        if(this.keyword == ""){
157
          var cut = 10;
158
          if(this.list.length < 5){
159
            cut = this.list.length;
160
          }
161
          this.results = this.list.length;
162
          this.filtered =this.list.slice(0, cut);
163
          this.tries = 0;
164
          this.warningMessage = "";
165
        // } else if(this.keyword && this.keyword.length < this.keywordlimit){
166
        //   this.tries++;
167
        //   if(this.tries == this.keywordlimit -1 ){
168
        //     this.warningMessage = "Type at least " + this.keywordlimit + " characters";
169
        //     this.tries = 0;
170
        //   }
171
        }else{
172
          this.tries = 0;
173
          this.warningMessage = "";
174
           this.filtered = this.list.filter(function(el){
175
              return el.label.toLowerCase().indexOf(this.keyword.toLowerCase()) > -1;
176
          }.bind(this));
177
          var cut = 10;
178
          if(this.filtered .length < 5){
179
            cut = this.list.length;
180
          }
181
          this.results = this.filtered.length;
182
           this.filtered =this.filtered.slice(0, cut);
183
        }
184
      }
185
    }
186
    remove(item:any){
187
      var index:number =this.checkIfExists(item,this.selected);
188
       if (index > -1) {
189
          this.selected.splice(index, 1);
190
      }
191
      if(!this.multipleSelections && this.selected.length == 0 ){
192
        this.showInput = true;
193
        this.selectedValue = "";
194
        this.selectedValueChanged.emit({
195
            value: this.selectedValue
196
        });
197

    
198

    
199
      }
200
    }
201
    select(item:any){
202
      // console.log("select"+this.selected.length  + item.id + " "+ item.label);
203

    
204
        if(this.multipleSelections){
205
          var index:number =this.checkIfExists(item,this.selected);
206
           if (index > -1 && !this.allowDuplicates) {
207
              this.keyword = "";
208
              this.filtered.splice(0, this.filtered.length);
209
              return;
210
          }
211
          else{
212
              this.selected.push(item);
213
              this.keyword = "";
214
              this.filtered.splice(0, this.filtered.length);
215
              this.addItem.emit({
216
                  value: item
217
              });
218
          }
219
      }else{
220
        this.selected.splice(0, this.selected.length);
221
        this.selected.push(item);
222
        this.filtered.splice(0, this.filtered.length);
223
        this.keyword = "";
224
        this.showInput = false;
225
        this.selectedValue = item.id;
226
        this.selectedValueChanged.emit({
227
            value: this.selectedValue
228
        });
229

    
230
      }
231

    
232
    }
233
    private checkIfExists(item:any,list):number{
234

    
235
       if(item.concept && item.concept.id ){
236

    
237
        for (var _i = 0; _i < list.length; _i++) {
238
            let itemInList = list[_i];
239
            if(item.concept.id == itemInList.concept.id){
240
                 return _i;
241
            }
242
         }
243
      }else if(item.id){
244
        for (var _i = 0; _i < list.length; _i++) {
245
            let itemInList = list[_i];
246
             if(item.id == itemInList.id){
247
                 return _i;
248
            }
249
         }
250
      }
251
      return -1;
252

    
253
    }
254
    showItem(item:any):string{
255

    
256
     if (item.name){ //search
257
         return item.name;
258
      }else if( item.concept && item.concept.label){ //context
259
         return item.concept.label;
260
      }else if (item.label){ //simple
261
         return item.label;
262
      }
263

    
264
    }
265
    truncate(str:string, size:number):string{
266
      if(str == null){return "";}
267
      return (str.length > size)?str.substr(0,size)+'...':str;
268
    }
269
    private getSelectedNameFromGivenId(){
270
      if(this.list == null ){
271
        return;
272
      }
273
      this.showInput = true;
274
      for( var i = 0; i < this.list.length; i++){
275
        if(this.list[i].id == this.selectedValue){
276
          this.selectedValue = this.list[i].label;
277
          this.selected.push(this.list[i]);
278
          this.showInput = false;
279
          return;
280

    
281
        }
282
      }
283
    }
284

    
285
    handleClick(event){
286
     var clickedComponent = event.target;
287
     var inside = false;
288
     do {
289
         if (clickedComponent === this.myElement.nativeElement) {
290
             inside = true;
291
         }
292
        clickedComponent = clickedComponent.parentNode;
293
     } while (clickedComponent);
294
      if(!inside){
295
          this.focus =false;
296
          this.filtered.splice(0, this.filtered.length);
297
      }
298
  }
299

    
300
}
(2-2/3)