Project

General

Profile

1
import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core';
2
import {Observable}       from 'rxjs/Observable';
3
import {Location} from '@angular/common';
4
import { Filter, Value} from './searchHelperClasses.class';
5
import {SearchResult}     from '../../utils/entities/searchResult';
6
import {SearchFields} from '../../utils/properties/searchFields';
7

    
8
@Component({
9
    selector: 'search-page',
10
    template: `
11

    
12
    <div class="container">
13
      <div class="page-header">
14
          <h1>{{pageTitle}}</h1>
15
      </div>
16
      <div>
17
        <div *ngIf="showRefine" class="row row-offcanvas row-offcanvas-right">
18
          <div class="col-xs-12 col-sm-3">
19
            <a *ngIf="isFiltered()" (click)="clearFilters()" > Clear Filters</a>
20
            <p *ngFor="let filter of filters " >
21
              <search-filter [filter]="filter"  [showResultCount]=showResultCount (change)="filterChanged($event)"></search-filter>
22
             </p>
23
          </div>
24

    
25
          <div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar">
26
            <search-form [(keyword)]="keyword" (keywordChange)="keywordChanged($event)"></search-form>
27
            <search-download [totalResults]="totalResults" (downloadClick)="downloadClicked($event)"></search-download>
28
            <search-paging [(page)] = "page" [(size)] = "size" [(results)] = "results" [(baseUrl)] = "baseURLWithParameters"  [(totalResults)] = "totalResults" ></search-paging>
29
             <search-result [results]="results" [totalResults]="totalResults" [status]=status [page]="page"></search-result>
30
          </div>
31
        </div>
32
        <div *ngIf="!showRefine" >
33

    
34
            <search-form [(keyword)]="keyword" (keywordChange)="keywordChanged($event)"></search-form>
35
            <search-paging [(page)] = "page" [(size)] = "size" [(results)] = "results" [(baseUrl)] = "baseURLWithParameters"  [(totalResults)] = "totalResults" ></search-paging>
36
             <search-result [results]="results" [totalResults]="totalResults" [status]=status [page]="page"></search-result>
37

    
38
        </div>
39
      </div>
40
    </div>
41

    
42
    `
43
})
44
export class SearchPageComponent {
45
  @Input() pageTitle = "";
46
  @Input() results = [];
47
  @Input() filters = [];
48
  @Input() type;
49
  @Input() page:number = 1;
50
  @Input() size: number = 10;
51
  @Input() status: number;
52
  @Input() totalResults: number = 0;
53
  @Input() keyword: string = '';
54
  @Output() queryChange  = new EventEmitter();
55
  @Output() downloadClick = new EventEmitter();
56
  @Input() baseUrl:string = '';
57
  @Input() showResultCount:boolean = true;
58
  @Input() showRefine:boolean = true;
59
  @Input() refineFields = [];
60
  public indexIdsMap: { [key:string]:string } ;
61
  public fieldIdsMap:  { [key:string]:{ name:string, operator:string, type:string, indexField:string }};
62
  private searchFieldsHelper:SearchFields = new SearchFields();
63
  private queryParameters: Map<string, string>  = new Map<string,string>();
64
  private baseURLWithParameters:string = '';
65
  private sub: any;
66

    
67
  constructor (private location: Location ) {
68
      console.info("constructor of SearchPage");
69
   }
70

    
71
  ngOnInit() {
72
      console.info("ngOnInit of SearchPage");
73
  }
74
  ngAfterViewChecked(){
75

    
76
  }
77
  public getQueryParametersFromUrl(params){
78
    var parameters = "";
79

    
80
    for(var i=0; i< this.refineFields.length ; i++){
81
         var filterId =  this.refineFields[i];
82

    
83
          if(params[filterId] != undefined) {
84
            if(this.queryParameters == undefined){
85
              this.queryParameters = new Map<string,string>();
86
            }
87
             this.queryParameters[filterId]=decodeURIComponent(params[filterId]);
88
             let values = decodeURIComponent(this.queryParameters[filterId]).split(",");
89
             var countvalues = 0
90
             for(let value of values) {
91
               countvalues++;
92
               var paramId = this.indexIdsMap[filterId];
93
              parameters+='&' + paramId+ '='+ value+"&" + this.fieldIdsMap[paramId].operator + "="+((countvalues == 1)?"and":"or");
94

    
95
             }
96
         }
97
   }
98
   var keyword = params['keyword'];
99
   return (keyword && keyword.length > 0?'q='+keyword+"&op=and":'')+parameters;
100
 }
101
 public getIndexQueryParametersFromUrl(params){
102
   var parameters = "";
103

    
104
   for(var i=0; i< this.refineFields.length ; i++){
105
        var filterId =  this.refineFields[i];
106

    
107
         if(params[filterId] != undefined) {
108
           if(this.queryParameters == undefined){
109
             this.queryParameters = new Map<string,string>();
110
           }
111
            this.queryParameters[filterId]=decodeURIComponent(params[filterId]);
112
            let values = decodeURIComponent(this.queryParameters[filterId]).split(",");
113
            var countvalues = 0
114
            for(let value of values) {
115
              countvalues++;
116
              parameters+= ((countvalues == 1)?" and (":" or ")+ filterId+ '='+ value;
117

    
118
            }
119
            parameters+= " ) "
120
        }
121
  }
122
  var keyword = params['keyword'];
123
  parameters += (keyword && keyword.length > 0?' and '+keyword+' ':'');
124
  return parameters;
125
}
126
 /*
127
 * Mark as check the new filters that are selected, when you get them from search
128
 */
129
  public checkSelectedFilters(filters:Filter[]){
130
       for(var i=0; i< filters.length ; i++){
131
            var filter:Filter = filters[i];
132
              if(this.queryParameters[filter.filterId] != undefined) {
133
                let values = decodeURIComponent(this.queryParameters[filter.filterId]).split(",");
134
                for(let value of values) {
135
                    for(let filterValue of filter.values) {
136
                        if(filterValue.id == value) {
137
                            filterValue.selected = true;
138
                            filter.countSelectedValues++;
139
                         }
140
                    }
141
                }
142
            }
143
        }
144

    
145
        return filters;
146
  }
147
  /*
148
  * Update the url with proper parameters. This is used as base url in Paging Component
149
  */
150
  public updateBaseUrlWithParameters(filters:Filter[]){
151
    this.baseURLWithParameters = this.baseUrl + this.createUrlParameters(filters,false);
152
  }
153
  /*
154
  *
155
  */
156
  private createUrlParameters(filters:Filter[], includePage:boolean){
157
    var allLimits="";//location.search.slice(1);
158
    for (let filter of filters){
159
      var filterLimits="";
160
      if(filter.countSelectedValues > 0){
161
        for (let value of filter.values){
162
          if(value.selected == true){
163
            filterLimits+=((filterLimits.length == 0)?'':',') + encodeURIComponent(value.id);
164
           }
165
        }
166
        this.queryParameters[filter.filterId]=filterLimits;
167
        allLimits+=((filterLimits.length == 0 )?'':"&" +filter.filterId + '='+ filterLimits) ;
168
      }
169
    }
170
    if(this.keyword.length > 0 ){
171
       allLimits+='&keyword=' + this.keyword;
172
    }
173
    if(this.page != 1 && includePage){
174
       allLimits+=((allLimits.length == 0)?'':'&') + 'page=' + this.page;
175
    }
176
    return allLimits;
177
  }
178
  /*
179
  *
180
  */
181
  private createSearchQueryParameters(filters:Filter[]){
182
    var allLimits="";
183
    for (let filter of filters){
184
      if(filter.countSelectedValues > 0){
185
        var filterLimits="";
186
        var count_selected=0;
187
        var fieldId = this.indexIdsMap[filter.filterId];
188
        for (let value of filter.values){
189
          if(value.selected == true){
190
              count_selected++;
191
              filterLimits+='&' + fieldId+ '='+ value.id+"&" + this.fieldIdsMap[fieldId].operator + "="+((count_selected == 1)?"and":filter.filterOperator);
192

    
193
           }
194
        }
195
        allLimits += filterLimits;
196
      }
197
    }
198

    
199
    return (this.keyword.length > 0?'q='+this.keyword+"&op=and":'')+allLimits;
200
  }
201
  private createIndexQueryParameters(filters:Filter[]){
202
    var allLimits="";
203
    for (let filter of filters){
204
      if(filter.countSelectedValues > 0){
205
        var filterLimits="";
206
        var count_selected=0;
207
        var fieldId = this.indexIdsMap[filter.filterId];
208
        for (let value of filter.values){
209
          if(value.selected == true){
210
              count_selected++;
211
              filterLimits+=((count_selected == 1)?" and (":" "+filter.filterOperator+" ") + filter.filterId+ '='+ value.id;
212

    
213
           }
214
        }
215
        filterLimits+=(filterLimits.length > 0 )?' ) ':'';
216
        allLimits += filterLimits;
217
      }
218
    }
219
     allLimits += (this.keyword && this.keyword.length > 0?' and '+this.keyword+' ':'');
220
    return allLimits;
221
  }
222
  //
223
  private isFiltered(){
224
    var filtered=false;
225
    for (let filter of this.filters){
226
       if(filter.countSelectedValues > 0){
227
           filtered = true;
228
           break;
229
       }
230
     }
231
    if(this.keyword.length > 0 ){
232
      filtered = true;
233
    }
234
    return filtered;
235
  }
236
  clearFilters(){
237
    for (let filter of this.filters){
238
      if(filter.countSelectedValues > 0){
239
         for (let value of filter.values){
240
          if(value.selected == true){
241
            value.selected = false;
242
           }
243
        }
244
        filter.countSelectedValues = 0;
245
      }
246
    }
247
    if(this.keyword.length > 0 ){
248
      this.keyword ='';
249
    }
250
    this.location.go(location.pathname);
251
    this.goTo(1);
252
  }
253

    
254
  goTo(page:number = 1){
255
    this.page = page;
256
    this.queryParameters = new Map<string,string>();
257
    var urlParameters = this.createUrlParameters(this.filters,true);
258
    this.updateBaseUrlWithParameters(this.filters);
259
    var queryParameters = this.createSearchQueryParameters(this.filters);
260
    var indexQuery = this.createIndexQueryParameters(this.filters);
261
    
262
    this.location.go(location.pathname,urlParameters);
263

    
264
    this.queryChange.emit({
265
        value: queryParameters,
266
        index:indexQuery
267

    
268
    });
269

    
270
  }
271
  filterChanged($event){
272
       this.goTo(1);
273
  }
274
  keywordChanged($event) {
275
       this.keyword = $event.value;
276
       this.goTo(1);
277
  }
278

    
279
	downloadClicked($event) {
280
		if($event.value == true) {
281
		    var queryParameters = this.createSearchQueryParameters(this.filters);
282

    
283
		    this.downloadClick.emit({
284
		        value: queryParameters
285
		    });
286
		}
287
	}
288

    
289
  /*
290
  * Get A sub-array of this.refineFields array, which contains the ids of the selected filters
291
  */
292
  public getSelectedFilters():string[] {
293
    var selected:string[] = [];
294
    for(var i=0; i <  this.filters.length; i++){
295
      var filter:Filter = this.filters[i];
296
      if(filter.countSelectedValues > 0){
297
          selected.push(filter.filterId);
298
      }
299
    }
300
    return selected;
301
  }
302
  /*
303
  * Get A sub-array of this.refineFields array, which contains the ids of the selected parameters
304
  */
305
  private getSelectedParameters():string[] {
306
    var selected:string[] = [];
307
    var params:string[] = Object.keys(this.queryParameters);
308
    for(var i=0; i <  params.length; i++){
309
       if(this.refineFields.indexOf(params[i]) > -1){
310
          selected.push(params[i]);
311
      }
312
    }
313
    return selected;
314
  }
315
  /*
316
  * Get A sub-array of this.refineFields array, which hides hidden fields (e.g Funding level 0,1,2,..), and contains those that depend on another fields (e.g  Funding level 0 if Funder is selected )
317
  */
318
  public getFields():string[] {
319
    var selected_filters:string[] = this.getSelectedFilters();
320
    if(selected_filters.length == 0){
321
      selected_filters = this.getSelectedParameters();
322
    }
323
    var fields:string[] = [];
324
    for(var i =0 ; i < this.refineFields.length;i++){
325
      var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]];
326

    
327
      //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected
328
      if(this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1 || (selected_filters.indexOf(dependentTo) != -1) ){
329
          fields.push(this.refineFields[i]);
330
       }
331
    }
332
    return fields;
333
  }
334
  /*
335
  * Get a query  string of all fields, that want to get from search (e.g. &fields=funderid&fields=projectstartyear&...))
336
  */
337
  public getRefineFieldsQuery():string{
338

    
339
    var fields:string[] = this.getFields();
340
    var fieldsStr = ""
341
    for(var i =0 ; i < fields.length  ;i++){
342
        fieldsStr+="&fields="+fields[i];
343
    }
344
    return "&refine=true"+fieldsStr;
345
  }
346

    
347

    
348
}
(7-7/9)