[Trunk | Library]: Filters according to new UI/UX design.

1. utils/rangeFilter/: range filters added to describe year range queries (currently used in types: result & project).
2. utils/properties/searchFields.ts: 
	'uniqueValue: boolean' changed to 'filterType: string' with value among: null (if this is not a range/refine filter), radio, checkbox, range.
	RANGE_FIELDS added for each type needed.
	'fieldHasUniqueValue()' method renamed to 'getFieldFilterType()' method.
	'getFieldParam()' method added.
3. utils/properties/searchFields.ts & services/servicesUtils/refineResults.class.ts & searchPages/searchUtils/searchHelperClasses.class.ts
   & searchPages/dataProviders/ & searchPages/searchDataProviders.component.ts & searchPages/searchOrganizations.component.ts: 'filterType' field is used.
4. searchPages/searchProjects.component.ts & searchPages/searchResearchResults.component.ts: Initialize and use in calculations range filters.
5. searchPages/searchUtils/searchFilter.component: Update filters to match redesign & use them everywhere (not special case if search or deposit).
6. searchPages/searchUtils/newSearchPage.component: Update filters to match redesign and add range filters.


git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@58105 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
konstantina.galouni 2020-02-17 14:19:14 +00:00
parent c004a7939f
commit 64df17d834
25 changed files with 884 additions and 375 deletions

View File

@ -194,7 +194,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -250,7 +250,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: filter_valueIsExact[i], valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: filter_valueIsExact[i], filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -184,7 +184,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -255,7 +255,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: filter_valueIsExact[i], valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: filter_valueIsExact[i], filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -188,7 +188,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -210,7 +210,7 @@ properties:EnvProperties;
var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false}
values.push(value);
}
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, valueIsUnique: false };
var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or', valueIsExact: true, filterType: "checkbox" };
filters.push(filter);
}
return filters;

View File

@ -112,7 +112,7 @@ export class SearchDataProvidersComponent {
this.searchPage.fieldIds = this.fieldIds;
this.selectedFields =[];
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params, "datasource");
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], this.fieldIdsMap,this.customFilter,params, "datasource");
// this.searchPage.selectedFields = this.selectedFields;
// this.searchPage.fieldIdsMap = this.fieldIdsMap;
@ -152,7 +152,7 @@ export class SearchDataProvidersComponent {
if (refine) {
this.filters = this.searchPage.prepareFiltersToShow(data[2]);
}else{
this.searchPage.buildPageURLParameters(this.filters, false);
this.searchPage.buildPageURLParameters(this.filters, [], false);
}
// this.searchPage.updateBaseUrlWithParameters();
//var errorCodes:ErrorCodes = new ErrorCodes();

View File

@ -114,7 +114,7 @@ public resourcesQuery = "(oaftype exact organization)";
// this.searchPage.fieldIdsMap = this.fieldIdsMap;
// this.searchPage.customFilter = this.customFilter;
// this.searchPage.getSelectedFiltersFromUrl(params);
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params, "organization");
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], this.fieldIdsMap,this.customFilter,params, "organization");
this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, refine, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
@ -150,7 +150,7 @@ public resourcesQuery = "(oaftype exact organization)";
if (refine) {
this.filters = this.searchPage.prepareFiltersToShow(data[2]);
}else{
this.searchPage.buildPageURLParameters(this.filters, false);
this.searchPage.buildPageURLParameters(this.filters, [],false);
}
// this.searchPage.updateBaseUrlWithParameters();
//var errorCodes:ErrorCodes = new ErrorCodes();

View File

@ -8,6 +8,7 @@ import {SearchFields} from '../utils/properties/searchFields';
import {SearchCustomFilter, SearchUtilsClass} from './searchUtils/searchUtils.class';
import {EnvProperties} from '../utils/properties/env-properties';
import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component";
import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class";
@Component({
selector: 'search-projects',
@ -27,8 +28,8 @@ import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component";
[(openaireLink)]=openaireLink
[piwikSiteId]=piwikSiteId [hasPrefix]="hasPrefix"
searchFormClass="projectSearchForm"
[(filters)]="filters"
[rangeFilters]="rangeFilters" [rangeFields]="rangeFields"
[simpleView]="simpleView" formPlaceholderText="Search by title, author, doi, abstract content..."
>
</new-search-page>
@ -43,12 +44,14 @@ export class SearchProjectsComponent {
@Input() customFilter:SearchCustomFilter= null;
public results =[];
public filters =[];
public rangeFilters: RangeFilter[] = [];
public searchUtils:SearchUtilsClass = new SearchUtilsClass();
public searchFields:SearchFields = new SearchFields();
public fieldIds: string[] = this.searchFields.PROJECT_ADVANCED_FIELDS;
public fieldIdsMap = this.searchFields.PROJECT_FIELDS;
public rangeFields:string[][] = this.searchFields.PROJECT_RANGE_FIELDS;
public selectedFields:AdvancedField[] = [];
properties:EnvProperties;
@ -114,13 +117,13 @@ export class SearchProjectsComponent {
this.searchPage.fieldIds = this.fieldIds;
this.selectedFields = [];
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params, "project");
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.fieldIdsMap,this.customFilter,params, "project");
// this.selectedFields =[];
// this.searchPage.selectedFields = this.selectedFields;
// this.searchPage.fieldIdsMap = this.fieldIdsMap;
// this.searchPage.customFilter = this.customFilter;
// this.searchPage.getSelectedFiltersFromUrl(params);
this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, refine, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, refine, this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
firstLoad = false;
});
}
@ -156,9 +159,11 @@ export class SearchProjectsComponent {
if (refine) {
this.filters = this.searchPage.prepareFiltersToShow(data[2]);
}else{
this.searchPage.buildPageURLParameters(this.filters, false);
this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false);
}
//var errorCodes:ErrorCodes = new ErrorCodes();
this.rangeFilters = this.searchPage.prepareRangeFiltersToShow();
//var errorCodes:ErrorCodes = new ErrorCodes();
this.searchUtils.status = this.errorCodes.DONE;
if(this.searchUtils.totalResults == 0 ){
this.searchUtils.status = this.errorCodes.NONE;

View File

@ -8,6 +8,7 @@ import {SearchFields} from '../utils/properties/searchFields';
import {SearchCustomFilter, SearchUtilsClass} from './searchUtils/searchUtils.class';
import {EnvProperties} from '../utils/properties/env-properties';
import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component";
import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class";
@Component({
@ -30,6 +31,7 @@ import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component";
searchFormClass="publicationsSearchForm"
[(sort)]=sort
[(filters)]="filters" [quickFilter]="quickFilter"
[rangeFilters]="rangeFilters" [rangeFields]="rangeFields"
[simpleView]="simpleView" formPlaceholderText="Search by title, author, doi, abstract content..."
>
</new-search-page>
@ -49,12 +51,14 @@ export class SearchResearchResultsComponent {
@Input() hasPrefix: boolean = true;
public results = [];
public filters = [];
public rangeFilters: RangeFilter[] = [];
public searchUtils: SearchUtilsClass = new SearchUtilsClass();
public searchFields: SearchFields = new SearchFields();
public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS;
public fieldIdsMap = this.searchFields.RESULT_FIELDS;
public rangeFields:string[][] = this.searchFields.RESULT_RANGE_FIELDS;
public selectedFields: AdvancedField[] = [];
public resourcesQuery = "((oaftype exact result) and (resulttypeid exact " + this.resultType + "))";
public csvParams: string;
@ -85,7 +89,7 @@ export class SearchResearchResultsComponent {
}
ngOnInit() {
console.log(this.quickFilter)
console.log(this.quickFilter);
//TODO add checks about which result types are enabled!
this.route.data.subscribe((data: { envSpecific: EnvProperties }) => {
this.properties = data.envSpecific;
@ -124,10 +128,18 @@ export class SearchResearchResultsComponent {
}
this.selectedFields = [];
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter);
this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
firstLoad = false;
// <<<<<<< .mine
this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter);
this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
// ||||||| .r58066
// this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params);
// this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRefineFields(params));
// =======
// this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter);
// this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
// firstLoad = false;
//
// >>>>>>> .r58095
});
}
@ -157,11 +169,13 @@ export class SearchResearchResultsComponent {
data => {
this.searchUtils.totalResults = data[0];
this.results = data[1];
if (refine) {
this.filters = this.searchPage.prepareFiltersToShow(data[2]);
}else{
this.searchPage.buildPageURLParameters(this.filters, false);
this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false);
}
this.rangeFilters = this.searchPage.prepareRangeFiltersToShow();
this.searchUtils.status = this.errorCodes.DONE;
if (this.searchUtils.totalResults == 0) {

View File

@ -32,7 +32,7 @@
<div id="tm-main" class=" tm-middle">
<div uk-grid>
<div class="tm-main uk-width-1-1@s uk-width-1-1@m uk-width-1-1@l uk-row-first ">
<div class="uk-container">
<div class="uk-container uk-container-large">
<div>
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0" [texts]="pageContents['top']"></helper>
@ -59,31 +59,62 @@
class="uk-width-1-2" [loadPaging]="loadPaging" [oldTotalResults]="oldTotalResults" [(searchUtils)] = "searchUtils" [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults">
</search-download>
<div *ngIf="selectedFilters>0" class="uk-margin-small-bottom">
<div class="uk-grid uk-margin-bottom uk-margin-top">
<span class="uk-text-bold uk-text-large">Filters</span>
<a *ngIf="selectedFilters>1" (click)="clearFilters()" [class]="((disableForms)?'uk-disabled uk-link-muted':'')+' portal-link ' + 'uk-width-1-2'">
<div *ngIf="selectedRangeFilters > 0 || selectedFilters > 0" class="uk-margin-small-bottom">
<!-- <div class="uk-grid uk-margin-bottom uk-margin-top">-->
<!-- <span class="uk-text-bold uk-text-large">Filters</span>-->
<!-- <a *ngIf="selectedFilters>1" (click)="clearFilters()" [class]="((disableForms)?'uk-disabled uk-link-muted':'')+' portal-link ' + 'uk-width-1-2'">-->
<!-- Clear All-->
<!-- </a>-->
<!-- </div>-->
<div class="uk-grid uk-flex uk-flex-bottom uk-margin-top">
<h5 class="uk-text-bold">Filters</h5>
<a *ngIf="(selectedRangeFilters+selectedFilters)>1" (click)="clearFilters()" [class]="((disableForms)?'uk-disabled uk-link-muted':'')+' portal-link ' + 'uk-width-1-2'">
Clear All
</a>
</div>
</div>
<span *ngIf = "searchUtils.keyword.length > 0"><span class="uk-text-bold">Keywords:</span>
<a (click) = "clearKeywords() " title="Remove keywords" [class]="((disableForms)?' uk-disabled':' ')+' uk-margin-small-right portal-color '"><span class=" clickable " aria-hidden="true"><span class="uk-icon ">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span></span></a>
<span [innerHtml]="searchUtils.keyword"></span>
</span>
<div *ngFor="let filter of filters " >
<span *ngIf = "filter.countSelectedValues > 0"> <span class="uk-text-bold">{{filter.title}}:</span>
<span *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; " >
<a [title]="'Remove '+value.name"(click) = "removeFilter(value, filter) " [class]="((disableForms)?' uk-disabled':' ')+' portal-color '"><span class=" clickable" aria-hidden="true"><span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span></span></a>
<span [innerHtml]="(value.name.length > 25)?value.name.substring(0,25)+'...':value.name" [title]="value.name"></span><span *ngIf="!end" class=" ">, </span>
<div *ngIf="selectedRangeFilters > 0 || selectedFilters>0" class="uk-margin-medium-bottom uk-grid uk-grid-small uk-text-small" uk-grid>
<ng-container *ngIf="selectedRangeFilters > 0">
<ng-container *ngFor="let filter of rangeFilters " >
<ng-container *ngIf = "filter.selectedFromAndToValues">
<span [title]="'Remove '+ filter.selectedFromAndToValues" (click) = "removeRangeFilter(filter) " >
<span class="selectedFilterLabel ">
<a [class]="((disableForms)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left">{{filter.selectedFromAndToValues}}</span>
</a>
</span>
</span>
</div>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngFor="let filter of filters " >
<ng-container *ngIf = "filter.countSelectedValues > 0">
<!-- <span class="uk-text-bold">{{filter.title}}:</span>-->
<!-- uk-margin-small-top uk-margin-small-right--> <!-- if no grid on the div above, add it -->
<!-- uk-label -->
<span *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; "
[title]="'Remove '+value.name" (click) = "removeFilter(value, filter) " >
<!-- if no grid on the div above, remove it and move class 'selectedFilterLabel' on top span -->
<span class="selectedFilterLabel ">
<a [class]="((disableForms)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left" [innerHtml]="(value.name.length > 34)?value.name.substring(0,34)+'...':value.name"></span>
</a>
</span>
</span>
</ng-container>
</ng-container>
</div>
@ -96,10 +127,18 @@
<div *ngIf="filters.length === 0 && searchUtils.keyword.length === 0 && results.length > 0" class="uk-margin-top">
<span class="uk-text-meta">No filters available</span>
</div>
<div *ngIf="!showUnknownFilters">
<div class="uk-text-large">Filter By:</div>
<search-filter *ngFor="let filter of filters " [addShowMore]=false [isDisabled]="disableForms" [filter]="filter" [showResultCount]=showResultCount (onFilterChange)="filterChanged($event)" ></search-filter>
</div>
<ul *ngIf="!showUnknownFilters" class="uk-list uk-list-divider">
<ng-container *ngFor="let filter of rangeFilters">
<li>
<range-filter [isDisabled]="disableForms" [filter]="filter" (onFilterChange)="filterChanged($event)"></range-filter>
</li>
</ng-container>
<ng-container *ngFor="let filter of filters ">
<li *ngIf= "filter.values.length >0">
<search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline" [isDisabled]="disableForms" [filter]="filter" [showResultCount]=showResultCount (onFilterChange)="filterChanged($event)" ></search-filter>
</li>
</ng-container>
</ul>
</div>
</div>
@ -122,34 +161,55 @@
class="uk-width-1-2" [loadPaging]="loadPaging" [oldTotalResults]="oldTotalResults" [(searchUtils)] = "searchUtils" [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults">
</search-download>
<div class="uk-width-1-1 uk-margin-small-bottom ">
<div *ngIf="selectedFilters>0" class="uk-grid uk-margin-bottom uk-margin-top">
<span class="uk-text-bold uk-text-large">Filters</span>
<a *ngIf="selectedFilters>1" (click)="clearFilters()" [class]="((disableForms)?'uk-disabled uk-link-muted':'')+' portal-link ' + 'uk-width-1-2'">
<div *ngIf="selectedRangeFilters > 0 || selectedFilters > 0" class="uk-grid uk-flex uk-flex-bottom uk-margin-top">
<h5 class="uk-text-bold">Filters</h5>
<a *ngIf="(selectedRangeFilters+selectedFilters)>1" (click)="clearFilters()" [class]="((disableForms)?'uk-disabled uk-link-muted':'')+' portal-link ' + 'uk-width-1-2'">
Clear All
</a>
</div>
<!-- uk-grid uk-grid-small" uk-grid-->
<!-- uk-margin-left-->
<div *ngIf="selectedRangeFilters > 0 || selectedFilters>0" class="uk-margin-medium-bottom uk-grid uk-grid-small uk-text-small" uk-grid>
<ng-container *ngIf="selectedRangeFilters > 0">
<ng-container *ngFor="let filter of rangeFilters " >
<ng-container *ngIf = "filter.selectedFromAndToValues">
<span [title]="'Remove '+ filter.selectedFromAndToValues" (click) = "removeRangeFilter(filter) " >
<span class="selectedFilterLabel ">
<a [class]="((disableForms)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left">{{filter.selectedFromAndToValues}}</span>
</a>
</span>
</span>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngFor="let filter of filters " >
<ng-container *ngIf = "filter.countSelectedValues > 0">
<div *ngIf=" selectedFilters>0" class="uk-margin-small-bottom">
<!-- <span *ngIf = "searchUtils.keyword.length > 0"><span class="uk-text-bold">Keywords:</span>
<a (click) = "clearKeywords() " title="Remove keywords" [class]="((disableForms)?' uk-disabled':' ')+' portal-color '"><span class=" clickable " aria-hidden="true"><span class="uk-icon ">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span></span></a>
<span [innerHtml]="searchUtils.keyword"></span>
</span>-->
<div *ngFor="let filter of filters " >
<span *ngIf = "filter.countSelectedValues > 0" > <span class="uk-text-bold">{{filter.title}}:</span>
<label *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; "
[title]="'Remove '+value.name" (click) = "removeFilter(value, filter) ">
<a [class]="((disableForms)?' uk-disabled':' ')+' portal-color '"><span class=" clickable" aria-hidden="true"><span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span></span>
</a>
<span [innerHtml]="(value.name.length > 25)?value.name.substring(0,25)+'...':value.name"></span><span *ngIf="!end" class=" ">, </span>
</label>
</span>
</div>
<!-- <span class="uk-text-bold">{{filter.title}}:</span>-->
<!-- uk-margin-small-top uk-margin-small-right--> <!-- if no grid on the div above, add it -->
<!-- uk-label -->
<span *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; "
[title]="'Remove '+value.name" (click) = "removeFilter(value, filter) " >
<!-- if no grid on the div above, remove it and move class 'selectedFilterLabel' on top span -->
<span class="selectedFilterLabel ">
<a [class]="((disableForms)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left" [innerHtml]="(value.name.length > 34)?value.name.substring(0,34)+'...':value.name"></span>
</a>
</span>
</span>
</ng-container>
</ng-container>
</div>
<!-- <div class="uk-margin-small-bottom uk-margin-small-top uk-grid">-->
@ -159,9 +219,18 @@
<div *ngIf="filters.length === 0 && results.length > 0" class="uk-margin-top">
<span class="uk-text-meta">No filters available</span>
</div>
<div *ngIf="!showUnknownFilters">
<search-filter *ngFor="let filter of filters " [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline" [isDisabled]="disableForms" [filter]="filter" [showResultCount]=showResultCount (onFilterChange)="filterChanged($event)" ></search-filter>
</div>
<ul *ngIf="!showUnknownFilters" class="uk-list uk-list-divider">
<ng-container *ngFor="let filter of rangeFilters">
<li>
<range-filter [isDisabled]="disableForms" [filter]="filter" (onFilterChange)="filterChanged($event)"></range-filter>
</li>
</ng-container>
<ng-container *ngFor="let filter of filters ">
<li *ngIf= "filter.values.length >0">
<search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline" [isDisabled]="disableForms" [filter]="filter" [showResultCount]=showResultCount (onFilterChange)="filterChanged($event)" ></search-filter>
</li>
</ng-container>
</ul>
</div>
<div class="uk-width-expand@m uk-with-1-1@s">
<div *ngIf="openaireLink"> <a class="uk-margin-top uk-button uk-button-text" [href]=openaireLink target="_blank" >Results in OpenAIRE</a></div>

View File

@ -16,6 +16,7 @@ import {SEOService} from '../../sharedComponents/SEO/SEO.service';
import {HelperService} from "../../utils/helper/helper.service";
import {SearchFields} from "../../utils/properties/searchFields";
import {RefineResultsUtils} from "../../services/servicesUtils/refineResults.class";
import {RangeFilter} from "../../utils/rangeFilter/rangeFilterHelperClasses.class";
@Component({
selector: 'new-search-page',
@ -45,18 +46,22 @@ export class NewSearchPageComponent {
@Input() sort: boolean = false;
@Input() searchFormClass: string = "searchForm";
//From simple:
@Input() rangeFilters: RangeFilter[] = [];
@Input() rangeFields: string[][] = [];
@Input() refineFields = [];
@Input() filters = [];
selectedFilters: number = 0;
selectedRangeFilters: number = 0;
private searchFieldsHelper: SearchFields = new SearchFields();
@Input() newQueryButton: boolean = true;
public showUnknownFilters: boolean = false; // when a filter exists in query but has no results, so no filters returned from the query
URLCreatedFilters: Filter[] = [];
URLCreatedRangeFilters: RangeFilter[] = [];
@Input() showRefine: boolean = true;
@Input() tableViewLink: string;
@Input() usedBy: string = "search";
@Input() showResultCount: boolean = true;
@Input() showMoreFilterValuesInline: boolean = false;
@Input() showMoreFilterValuesInline: boolean = true;
@Input() filterValuesNum: number = 5;
@Input() keywordFields = [];
@Input() simpleView: boolean = true;
@ -170,16 +175,26 @@ export class NewSearchPageComponent {
}
}
this.selectedFilters = 0;
//<<<<<<< .mine
for(let i = 0; i < this.rangeFilters.length; i++) {
this.rangeFilters[i].selectedFromValue = null;
this.rangeFilters[i].selectedToValue = null;
}
this.selectedRangeFilters = 0;
//||||||| .r58066
//=======
if (this.quickFilter) {
this.removeValueFromQuickFilter();
}
//>>>>>>> .r58095
this.goTo(1);
// this.clearKeywords();
}
goTo(page: number = 1) {
this.searchUtils.page = page;
this.buildPageURLParameters(this.filters, true);
this.buildPageURLParameters(this.filters, this.rangeFilters, true);
this.router.navigate([this.searchUtils.baseUrl], {queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)});
/* Code For Piwik*/
if (typeof localStorage !== 'undefined') {
@ -319,6 +334,69 @@ export class NewSearchPageComponent {
return filters;
}
/*
* Mark as check the new range filters that are selected
*/
public checkSelectedRangeFilters(filters: RangeFilter[]) {
//console.log("checkSelectedRangeFilters: parameterNames.length: "+this.parameterNames.length);
this.rangeFilters = filters;
for (let i = 0; i < filters.length; i++) {
let filter: RangeFilter = filters[i];
if (this.parameterNames.indexOf(filter.filterId) != -1) {
//console.log(filter.filterId + " "+this.parameterNames.indexOf(filter.filterId) );
let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1);
let operators: string [] = (StringUtils.URIDecode(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1);
if (values.length == operators.length) {
for (let j = 0; j < values.length; j++) {
if (this.fieldIdsMap[filter.originalFilterIdFrom+"-range-"+filter.originalFilterIdTo].filterType == "range") {
let value: string = StringUtils.unquote(values[j]);
let validDates: boolean = true;
let years: string[] = (value.substring(5)).split(":");
let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null);
let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null);
//console.log("checkSelectedRangeFilters: yearFrom: " + yearFrom + " - yearTo: "+yearTo);
if(yearFrom) {
filter.selectedFromValue = yearFrom;
filter.selectedFromAndToValues = yearFrom;
}
if(yearFrom && yearTo) {
filter.selectedFromAndToValues += "-";
}
if(yearTo) {
filter.selectedToValue = yearTo;
filter.selectedFromAndToValues += yearTo;
}
if(!yearFrom && !yearTo) {
validDates = false;
}
// if (value.length < 14) {
// validDates = false;
// console.log("not valid (length<14)");
// } else {
// if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) {
// validDates = false;
// console.log("not valid years");
// } else {
// filter.selectedFromValue = value.substring(5, 9);
// filter.selectedToValue = value.substring(10, 14);
// console.log(filter);
// }
// }
}
}
}
} else {
filter.selectedFromValue = null;
filter.selectedToValue = null;
}
}
return this.rangeFilters;
}
/*
* For Funder filters - if funder selected
*/
@ -367,6 +445,16 @@ export class NewSearchPageComponent {
return this.selectedFilters;
}
public countSelectedRangeFilters(rangeFilters: RangeFilter[]) : number {
this.selectedRangeFilters = 0;
for(let filter of rangeFilters) {
if(filter.selectedFromValue || filter.selectedToValue) {
this.selectedRangeFilters++;
}
}
return this.selectedRangeFilters;
}
private clearKeywords() {
if (this.searchUtils.keyword.length > 0) {
this.searchUtils.keyword = '';
@ -374,7 +462,7 @@ export class NewSearchPageComponent {
this.goTo(1);
}
private removeFilter(value: Value, filter: Filter) {
public removeFilter(value: Value, filter: Filter) {
filter.countSelectedValues--;
this.selectedFilters--;
if (value.selected == true) {
@ -384,7 +472,12 @@ export class NewSearchPageComponent {
this.removeValueFromQuickFilter();
}
this.goTo(1);
}
public removeRangeFilter(filter: RangeFilter) {
filter.selectedFromValue = null;
filter.selectedToValue = null;
this.goTo(1);
}
getSelectedValues(filter): any {
@ -401,7 +494,7 @@ export class NewSearchPageComponent {
}
filterChanged($event) {
if (this.quickFilter) {
if (this.quickFilter && this.quickFilter.filter) {
this.removeValueFromQuickFilter();
}
this.goTo(1);
@ -644,13 +737,114 @@ export class NewSearchPageComponent {
}
/**
* Create Search API query based on the filters of refine fields
* @param URLparams
*/
getSearchAPIQueryForRangeFields(URLparams) {
let allFqs = "";
for (let i = 0; i < this.rangeFields.length; i++) {
let filterId = this.rangeFields[i][0]+"-range-"+this.rangeFields[i][1];
let filterParam = this.searchFieldsHelper.getFieldParam(filterId, this.entityType);
if (URLparams[filterParam] != undefined) {
let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterParam]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1);
var countvalues = 0;
var fq = "";
var fqFrom = "";
var fqTo = "";
let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId);
for (let value of values) {
if (this.fieldIdsMap[filterId].filterType == "range") {
let selectedFromValue;
let selectedToValue;
let years: string[] = (value.substring(5)).split(":");
let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null);
//(Number.isInteger(parseInt(years[0], 10)) ? years[0] : null);
let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null);
//console.log("getSearchAPIQueryForRangeFields: yearFrom: " + yearFrom + " - yearTo: "+yearTo);
if(yearFrom) {
selectedFromValue = yearFrom;
}
if(yearTo) {
selectedToValue = yearTo;
}
if(yearFrom || yearTo) {
// if (value.length <= 14) {
// if(Dates.isValidYear(value.substring(5, 9))) {
// selectedFromValue = value.substring(5, 9);
// }
// if(Dates.isValidYear(value.substring(10, 14))) {
// selectedToValue = value.substring(10, 14);
// }
if(this.rangeFields[i][0] == this.rangeFields[i][1]) {
//console.log(selectedFromValue + " - "+selectedToValue);
if (selectedFromValue && selectedToValue) {
let equalityOp = this.fieldIdsMap[filterId].equalityOperator;
fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + " " + selectedToValue + "\"";
fq = "&fq=" + StringUtils.URIEncode(fq);
} else if (selectedFromValue) {
let equalityOp = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator;
if(equalityOp == " = ") {
equalityOp = " >= ";
}
fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + "\"";
fq = "&fq=" + StringUtils.URIEncode(fq);
} else if (selectedToValue) {
let equalityOp = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator;
if(equalityOp == " = ") {
equalityOp = " <= ";
}
fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedToValue + "\"";
fq = "&fq=" + StringUtils.URIEncode(fq);
}
} else {
let equalityOpFrom = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator;
let equalityOpTo = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator;
if (selectedFromValue) {
fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOpFrom + "\"" + selectedFromValue + "\"";
// fq = "&fq=" + StringUtils.URIEncode(fq);
}
if (selectedToValue) {
fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][1] + equalityOpTo + "\"" + selectedToValue + "\"";
// fq = "&fq=" + StringUtils.URIEncode(fq);
}
if(selectedFromValue || selectedToValue) {
fq = "&fq=" + StringUtils.URIEncode(fq);
}
}
}
}
}
allFqs += fq +fqFrom + fqTo;
}
}
return allFqs;
}
/**
* Sets parameterNames and parameterValues arrays
* used in paging, advanced search link, Goto()
* @param filters either query filters or filters defined by the URL parameters
* @param rangeFilters defined by the URL parameters
* @param includePage
*/
buildPageURLParameters(filters: Filter[], includePage: boolean) {
//<<<<<<< .mine
buildPageURLParameters(filters:Filter[], rangeFilters: RangeFilter[], includePage: boolean) {
//console.log("buildPageURLParameters");
// ||||||| .r58066
// buildPageURLParameters(filters:Filter[],includePage: boolean) {
// =======
// buildPageURLParameters(filters: Filter[], includePage: boolean) {
// >>>>>>> .r58095
this.parameterNames.splice(0, this.parameterNames.length);
this.parameterValues.splice(0, this.parameterValues.length);
var fields: { [key: string]: { values: string[], operators: string[] } } = {};
@ -710,6 +904,26 @@ export class NewSearchPageComponent {
}
}
}
for (let filter of rangeFilters) {
var filterLimits = "";
let yearFrom: string = (Dates.isValidYear(filter.selectedFromValue) ? filter.selectedFromValue : null);
let yearTo: string = (Dates.isValidYear(filter.selectedToValue) ? filter.selectedToValue : null);
if(yearFrom || yearTo) {
this.parameterNames.push(filter.filterId);
this.parameterValues.push("range" + (yearFrom ? yearFrom : "") + ":" + (yearTo ? yearTo : ""));
}
// if (filter.countSelectedValues > 0) {
// for (let value of filter.values) {
// if (value.selected == true) {
// filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + (value.id) + '"';
// }
// }
// if (filterLimits.length > 0) {
// this.parameterNames.push(filter.filterId);
// this.parameterValues.push(filterLimits);
// }
// }
}
if (this.searchUtils.keyword.length > 0) {
this.parameterNames.push("keyword");
this.parameterValues.push(this.searchUtils.keyword);
@ -785,7 +999,7 @@ export class NewSearchPageComponent {
if (this.quickFilter) {
if (this.entityType == "result" && (URLparams[this.quickFilter.filterId] == undefined) && (URLparams["qf"] == undefined || URLparams["qf"] == "true")) {
let filter = new Filter();
filter.title = fields.getFieldName(this.quickFilter.filterId, "publication");
filter.title = fields.getFieldName(this.quickFilter.filterId, this.entityType);
filter.filterId = this.quickFilter.filterId;
filter.originalFilterId = this.quickFilter.filterId;
filter.values = [];
@ -823,6 +1037,74 @@ export class NewSearchPageComponent {
this.URLCreatedFilters = filters;
}
/**
* create range filters based on URL params
* @param URLparams
*/
getRangeFiltersFromURL(URLparams) {
let fields = new SearchFields();
let filters: RangeFilter[] = [];
for (let i = 0; i < this.rangeFields.length; i++) {
let filterId = this.rangeFields[i][0]+"-range-"+this.rangeFields[i][1];
let filterParam = fields.getFieldParam(filterId, this.entityType);
//console.log("rangeFilter (from url): filterId - filterParam");
//console.log(filterId + " - "+ filterParam);
if (URLparams[filterParam] != undefined) {
let filter = new RangeFilter();
filter.title = fields.getFieldName(filterId, this.entityType);
filter.filterId = filterParam;
filter.originalFilterIdFrom = this.rangeFields[i][0];
filter.originalFilterIdTo = this.rangeFields[i][1];
let values = (decodeURIComponent(URLparams[filterParam])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1);
for (let j = 0; j < values.length; j++) {
if (this.fieldIdsMap[filterId].filterType == "range") {
let value: string = StringUtils.unquote(values[j]);
let validDates: boolean = true;
// if (value.length < 14) {
// validDates = false;
// } else {
// if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) {
// validDates = false;
// } else {
// filter.selectedFromValue = value.substring(5, 9);
// filter.selectedToValue = value.substring(10, 14);
// }
// }
let years: string[] = (value.substring(5)).split(":");
let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null);
let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null);
//console.log("getRangeFiltersFromURL: yearFrom: " + yearFrom + " - yearTo: "+yearTo);
if(yearFrom) {
filter.selectedFromValue = yearFrom;
//filter.selectedFromAndToValues = yearFrom;
}
/*if(yearFrom && yearTo) {
filter.selectedFromAndToValues += "-";
}*/
if(yearTo) {
filter.selectedToValue = yearTo;
//filter.selectedFromAndToValues += yearTo;
}
//console.log("filter.selectedFromAndToValues: "+filter.selectedFromAndToValues);
if(!yearFrom && !yearTo) {
validDates = false;
}
}
}
//console.log(filters);
filters.push(filter)
}
}
// console.log("Empty Filters");
// console.log(filters);
this.URLCreatedRangeFilters = filters;
// return filters;
}
/**
* Checks if query has no results, display Filters from URL parameters
* Mark checked the selected filters
@ -830,6 +1112,7 @@ export class NewSearchPageComponent {
* @param filters
*/
public prepareFiltersToShow(filters: Filter[]): Filter[] {
//console.log("prepareFiltersToShow");
if (this.URLCreatedFilters.length > 0 && this.searchUtils.totalResults == 0) {
this.showUnknownFilters = true;
this.filters = this.URLCreatedFilters;
@ -837,12 +1120,26 @@ export class NewSearchPageComponent {
this.showUnknownFilters = false;
this.filters = filters;
}
this.buildPageURLParameters(this.URLCreatedFilters, true);
this.buildPageURLParameters(this.URLCreatedFilters, this.URLCreatedRangeFilters, true);
//this.checkSelectedRangeFilters(this.rangeFilters);
this.checkSelectedFilters(this.filters);
this.countSelectedFilters(this.filters);
return this.filters;
}
/**
* Mark checked the selected range filters
*/
public prepareRangeFiltersToShow() {
this.rangeFilters = RangeFilter.parse(this.rangeFields, this.entityType); // OK
//this.buildPageURLRangeParameters(this.rangeFilters, true);
this.checkSelectedRangeFilters(this.rangeFilters);
this.countSelectedRangeFilters(this.rangeFilters);
return this.rangeFilters;
}
/**
* Used to set the variables and search page, and prepare it before the getResults query
* @param fieldIds
@ -852,15 +1149,40 @@ export class NewSearchPageComponent {
* @param customFilter
* @param params
*/
prepareSearchPage(fieldIds, selectedFields, refineFields, fieldIdsMap, customFilter, params, entityType, quickFilter=null) {
//<<<<<<< .mine
prepareSearchPage(fieldIds, selectedFields, refineFields, rangeFields, fieldIdsMap, customFilter, params, entityType, quickFilter=null){
//console.log("prepareSearchPage");
this.entityType = entityType;
this.fieldIds = fieldIds;
this.selectedFields = selectedFields;
this.refineFields = refineFields;
this.rangeFields = rangeFields;
this.fieldIdsMap = fieldIdsMap;
this.customFilter = customFilter;
this.quickFilter = quickFilter;
this.getRangeFiltersFromURL(params);
this.getRefineFiltersFromURL(params);
this.createAdvancedSearchSelectedFiltersFromURLParameters(params);
// ||||||| .r58066
// prepareSearchPage(fieldIds, selectedFields, refineFields,fieldIdsMap, customFilter, params){
// this.fieldIds = fieldIds;
// this.selectedFields = selectedFields;
// this.refineFields = refineFields;
// this.fieldIdsMap = fieldIdsMap;
// this.customFilter = customFilter;
// this.getRefineFiltersFromURL(params);
// this.createAdvancedSearchSelectedFiltersFromURLParameters(params);
// =======
// prepareSearchPage(fieldIds, selectedFields, refineFields, fieldIdsMap, customFilter, params, entityType, quickFilter=null) {
// this.entityType = entityType;
// this.fieldIds = fieldIds;
// this.selectedFields = selectedFields;
// this.refineFields = refineFields;
// this.fieldIdsMap = fieldIdsMap;
// this.customFilter = customFilter;
// this.quickFilter = quickFilter;
// this.getRefineFiltersFromURL(params);
// this.createAdvancedSearchSelectedFiltersFromURLParameters(params);
}
//>>>>>>> .r58095
}

View File

@ -6,6 +6,7 @@ import { RouterModule } from '@angular/router';
import{NewSearchPageComponent} from './newSearchPage.component';
import{SearchFormModule} from './searchForm.module';
import {SearchFilterModule} from './searchFilter.module';
import {RangeFilterModule} from 'app/openaireLibrary/utils/rangeFilter/rangeFilter.module';
import{LoadingModalModule} from '../../utils/modal/loadingModal.module';
import {ReportsServiceModule} from '../../services/reportsService.module';
import{SearchPagingModule} from './searchPaging.module';
@ -28,7 +29,8 @@ import {AdvancedSearchFormModule} from "./advancedSearchForm.module";
imports: [
CommonModule, FormsModule, RouterModule, SearchFormModule, SearchResultsModule, CommunitySearchResultsModule,
LoadingModalModule, ReportsServiceModule, SearchDataproviderMapModule,
SearchPagingModule, SearchResultsPerPageModule, SearchSortingModule, SearchDownloadModule, ModalModule, SearchFilterModule,
SearchPagingModule, SearchResultsPerPageModule, SearchSortingModule, SearchDownloadModule, ModalModule,
SearchFilterModule, RangeFilterModule,
PiwikServiceModule, HelperModule, Schema2jsonldModule, SEOServiceModule, SearchResultsModule,
SearchResultsInDepositModule, AdvancedSearchFormModule
],

View File

@ -1,137 +1,97 @@
<ul *ngIf= "filter.values.length >0" class="uk-list">
<li class="uk-open">
<h5 class="uk-margin-bottom-remove searchFilterTitle">{{_formatTitle(filter.title,filter.values.length)}}
</h5>
<div *ngIf= "filter.values.length >0" class="uk-margin-small-bottom">
<div class="uk-margin-small-top uk-margin-bottom uk-grid uk-flex uk-flex-bottom">
<h5 class="uk-margin-bottom-remove">{{_formatTitle(filter.title,filter.values.length)}}</h5>
<a *ngIf="filter.countSelectedValues>0" (click)="clearFilter()" class="portal-link">
Clear
</a>
</div>
<div aria-expanded="false">
<div [class]="showMoreInline ? '' : 'searchFilterBoxValues' ">
<div *ngFor = "let value of getSelectedValues(filter,'num')" class="uk-animation-fade filterItem">
<div title = "{{value.name}}">
<input *ngIf="!filter.valueIsUnique" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId checked/>
{{' '+_formatName(value)}}
<span *ngIf = "showResultCount === true" >
{{' ('+(value.number|number)+')'}}</span>
</div>
</div>
<!-- <hr *ngIf="filter.countSelectedValues > 0 && (filter.values.length-filter.countSelectedValues ) > 0 " class="uk-grid-divider uk-margin-small"-->
<div>
<ng-container *ngIf="!isOpen">
<div *ngFor = "let value of getSelectedValues(filter,'num')" class="uk-animation-fade filterItem searchFilterItem uk-text-small">
<div title = "{{value.name}}">
<ng-container *ngIf="filter.filterType == 'checkbox' || filter.filterType == 'radio'">
<input *ngIf="filter.filterType == 'checkbox'" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.filterType == 'radio'" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId checked/>
{{' '+_formatName(value)}}
<span *ngIf = "showResultCount === true" >
{{' ('+(value.number|number)+')'}}</span>
</ng-container>
</div>
</div>
<div *ngFor = "let value of getNotSelectedValues(filter,'num').slice(0,(!addShowMore?getNotSelectedValues(filter,'num').length:filterValuesNum-getSelectedValues(filter,'num').length))" class = "uk-animation-fade filterItem">
<div title = "{{value.name}}" [class]="(isDisabled || (showResultCount && value.number === 0))?'uk-text-muted':''" >
<input *ngIf="!filter.valueIsUnique" [disabled]="isDisabled || (showResultCount && value.number === 0)" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" [disabled]="isDisabled || (showResultCount && value.number === 0)" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId value=false />
{{' '+ _formatName(value) }}
<span *ngIf = "showResultCount === true" [class]="(isDisabled || value.number === 0)?'uk-text-muted':''" >
{{' ('+(value.number|number)+')'}}
</span>
</div>
</div>
<div *ngFor = "let value of getNotSelectedValues(filter,'num').slice(0,(!addShowMore?getNotSelectedValues(filter,'num').length:filterValuesNum-getSelectedValues(filter,'num').length))" class = "uk-animation-fade filterItem searchFilterItem uk-text-small">
<div title = "{{value.name}}" [class]="(isDisabled || (showResultCount && value.number === 0))?'uk-text-muted':''" >
<input *ngIf="filter.filterType == 'checkbox'" [disabled]="isDisabled || (showResultCount && value.number === 0)" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.filterType == 'radio'" [disabled]="isDisabled || (showResultCount && value.number === 0)" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId value=false />
{{' '+ _formatName(value) }}
<span *ngIf = "showResultCount === true" [class]="(isDisabled || value.number === 0)?'uk-text-muted':''" >
{{' ('+(value.number|number)+')'}}
</span>
</div>
</div>
</ng-container>
<div *ngIf=" addShowMore && showMoreInline && (filter.values.length) > filterValuesNum">
<a [class]="(isDisabled)?'uk-disabled uk-link-muted ':''"
[attr.uk-toggle]="'target: #toggle-'+filter.filterId">View
<span *ngIf="filter.values.length >= 99">more</span>
<span *ngIf="filter.values.length < 99">all</span>
<div *ngIf=" addShowMore && (filter.values.length) > filterValuesNum">
<a *ngIf="!isOpen"
[class]="((isDisabled)?'uk-disabled uk-link-muted ':' portal-link ') + ' uk-margin-small-top'"
[attr.uk-toggle]="'target: #toggle-'+filter.filterId" (click)="toggle()">
+ View more
</a>
<div hidden [id]="'toggle-'+filter.filterId">
<!-- <div *ngIf="filter.values.length >= 99" class="uk-alert uk-alert-primary uk-text-center uk-margin-right uk-margin-left uk-margin-small-top uk-margin-small-bottom ">Showing top {{filter.values.length}} values. </div>-->
<div hidden [id]="'toggle-'+filter.filterId" class="uk-text-small uk-margin-small-bottom">
<div class="">
<span *ngIf="filter.values.length >= 99">* only the Top 100 values are shown</span>
<input class="uk-input uk-margin-small-bottom uk-width-1-1 " name="filter-keyword" placeholder="Search for {{filter.title}}" type="text" [(ngModel)]="keyword">
<select *ngIf = "showResultCount === true" [(ngModel)]="sortBy"
class="uk-text-muted uk-select uk-margin-small-bottom uk-width-1-1" name="select_order" (ngModelChange)="sortByChanged = true;" >
<option value="num">Sorted by results number</option>
<option value="name">Sorted by name</option>
</select>
<span *ngIf = "showResultCount === true" class="uk-width-5-6@m uk-width-1-1@s uk-align-right uk-margin-small-bottom">
<span class="uk-width-1-4"> Sort by:</span>
<select [(ngModel)]="sortBy"
class="uk-select uk-width-3-4@m uk-width-auto"
id="form-horizontal-select" name="select_order">
<option value="num">Results number</option>
<option value="name">Name</option>
</select>
</span>
</div>
<div class="uk-modal-body uk-overflow-auto uk-height-small uk-padding-remove
uk-margin-small-left uk-margin-small-right uk-margin-small-top uk-margin-bottom">
<div class="uk-modal-body uk-overflow-auto uk-height-max-small uk-padding-remove
uk-margin-small-left uk-margin-small-right uk-margin-small-top">
<ng-container *ngFor = "let value of getSelectedValues(filter, sortBy)">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem searchFilterItem">
<div title = "{{value.name}}">
<input *ngIf="!filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="close(); filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" [disabled]="isDisabled" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId checked/>
<input *ngIf="filter.filterType == 'checkbox'" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.filterType == 'radio'" [disabled]="isDisabled" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId checked/>
{{' ' + _formatName(value) + ' '}}
<span class="filterNumber" *ngIf = "showResultCount === true" > ({{value.number|number}})</span>
</div>
</div>
</ng-container>
<hr *ngIf="filter.countSelectedValues > 0 && (filter.values.length-filter.countSelectedValues ) > 0 " class="uk-grid-divider uk-margin-small">
<ng-container *ngFor = "let value of getNotSelectedValues(filter, sortBy)">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem searchFilterItem">
<div title = "{{value.name}}">
<input *ngIf="!filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="close(); filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" [disabled]="isDisabled" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId value=false />
<input *ngIf="filter.filterType == 'checkbox'" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterChange(value.selected)" />
<input *ngIf="filter.filterType == 'radio'" [disabled]="isDisabled" type="radio" (click)="uniqueFilterChange(value)"
[name]=filter.filterId value=false />
{{' ' + _formatName(value) + ' '}}
<span *ngIf = "showResultCount === true" > ({{value.number|number}})</span>
</div>
</div>
</ng-container>
</div>
</div>
<a [class]="(isDisabled)?'uk-disabled uk-link-muted ':' portal-link '"
[attr.uk-toggle]="'target: #toggle-'+filter.filterId" (click)="toggle()">
<span *ngIf="isOpen">- View less</span>
</a>
</div>
<a *ngIf=" addShowMore && !showMoreInline&& (filter.values.length) > filterValuesNum" (click)="open()"
[class]="(isDisabled)?'uk-disabled uk-link-muted':''">View more
</a>
<div *ngIf="addShowMore && !showMoreInline" [class]="(!isOpen)?'uk-modal ':'uk-modal uk-open uk-animation-fade'" uk-modal [open]="!isOpen" id="modal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" bg-close="true">
<div class="filtersModal uk-modal-dialog uk-small-1-2 uk-width-medium-1-3 uk-width-1-3 uk-padding-small uk-padding-remove-top uk-padding-remove-horizontal">
<button type="button" class="uk-modal-close-default" uk-close (click)="close()"></button>
<h5 class="uk-margin-remove uk-padding uk-padding-remove-bottom uk-text-center">
{{filter.title}}
</h5>
<div *ngIf="filter.values.length >= 99" class="uk-alert uk-alert-primary uk-text-center uk-margin-right uk-margin-left uk-margin-small-top uk-margin-small-bottom ">Showing top {{filter.values.length}} values. </div>
<div class="uk-grid uk-margin-left uk-margin-right">
<input class="uk-input uk-margin-small-bottom uk-width-1-2 " name="filter-keyword" placeholder="Search for {{filter.title}}" type="text" [(ngModel)]="keyword">
<select *ngIf = "showResultCount === true" [(ngModel)]="sortBy" class="uk-select uk-margin-small-bottom uk-width-1-2 uk-padding-remove" name="select_order" (ngModelChange)="sortByChanged = true;" >
<option value="num" >Sort by results number</option>
<option value="name" >Sort by name</option>
</select>
</div>
<div class="uk-modal-body uk-overflow-auto uk-height-medium uk-padding-remove
uk-margin-medium-left uk-margin-medium-right uk-margin-small-top uk-margin-bottom">
<ng-container *ngFor = "let value of getSelectedValues(filter, sortBy)">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem">
<div title = "{{value.name}}">
<input *ngIf="!filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="close(); filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="radio" [name]=filter.filterId (ngModelChange)="close(); filterChange(value.selected)" />
{{' ' + (value.name) + ' '}}
<span *ngIf = "showResultCount === true" > ({{value.number|number}})</span>
</div>
</div>
</ng-container>
<hr *ngIf="filter.countSelectedValues > 0 && (filter.values.length-filter.countSelectedValues ) > 0 " class="uk-grid-divider uk-margin-small">
<ng-container *ngFor = "let value of getNotSelectedValues(filter, sortBy)">
<div *ngIf="filterKeywords(value.name)" class = "uk-animation-fade filterItem">
<div title = "{{value.name}}">
<input *ngIf="!filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="close(); filterChange(value.selected)" />
<input *ngIf="filter.valueIsUnique" [disabled]="isDisabled" [(ngModel)]="value.selected" type="radio" [name]=filter.filterId (ngModelChange)="close(); filterChange(value.selected)" />
{{' ' + (value.name) + ' '}}
<span *ngIf = "showResultCount === true" > ({{value.number|number}})</span>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>

View File

@ -1,8 +1,5 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
import {Observable} from 'rxjs';
import {Component, Input, Output, EventEmitter, ViewChild, ElementRef} from '@angular/core';
import { Filter, Value} from './searchHelperClasses.class';
import {Open} from '../../utils/modal/open.component';
@Component({
selector: 'search-filter',
@ -11,44 +8,36 @@ import {Open} from '../../utils/modal/open.component';
export class SearchFilterComponent {
@Input() filter:Filter;
@Input() showResultCount:boolean = true;
@Input() isDisabled:boolean = false;
@Input() addShowMore:boolean = true;
@Input() showMoreInline: boolean = false;
@Input() filterValuesNum: number = 5;
public showAll:boolean = false;
public _maxCharacters:number =28;
@Input() filter:Filter;
@Input() showResultCount:boolean = true;
@Input() isDisabled:boolean = false;
@Input() addShowMore:boolean = true;
@Input() showMoreInline: boolean = true;
@Input() filterValuesNum: number = 4;
public showAll:boolean = false;
public _maxCharacters:number =28;
@Output() toggleModal = new EventEmitter();
@Output() toggleModal = new EventEmitter();
@Output() modalChange = new EventEmitter();
@Output() onFilterChange = new EventEmitter();
keyword = "";
sortBy = "num";
@Output() modalChange = new EventEmitter();
@Output() onFilterChange = new EventEmitter();
keyword = "";
sortBy = "num";
public isOpen:boolean=false;
public isOpen:boolean=false;
// filterModalChange() {
// console.info("Modal Changed");
// this.modalChange.emit({
// value: true
// });
// //this.close();
// }
constructor () {
constructor () {
}
ngOnInit() {
ngOnInit() {}
}
public _formatTitle(title,length){
return (((title+" ("+length+")").length >this._maxCharacters)?(title.substring(0,(this._maxCharacters - (" ("+length+")").length - ('...').length))+"..."):title+" ("+((length >= 99)?length+"+":length)+")")
}
public _formatName(value){
let maxLineLength = 24;
//let maxLineLength = 24;
let maxLineLength = 35;
//1 space after checkbox
//3 space before number + parenthesis
if(!this.showResultCount && value.name.length+1 > maxLineLength ){
@ -59,15 +48,7 @@ export class SearchFilterComponent {
}
return value.name;
//(((value.name+" ("+value.number+")").length >this._maxCharacters)?(value.name.substring(0,(this._maxCharacters - (" ("+value.number+")").length - ('...').length))+"..."):value.name)
}
// toggleShowAll(){
// this.showAll = !this.showAll;
// if(this.showAll == false) {
// this.reorderFilterValues();
// }
// }
filterKeywords(value){
if(this.keyword.length > 0){
@ -78,13 +59,10 @@ export class SearchFilterComponent {
return true;
}
filterChange(selected:boolean){
//console.info("filter change: "+selected);
if(selected){
this.filter.countSelectedValues++;
// this.reorderFilterValues();
}else{
this.filter.countSelectedValues--;
// this.reorderFilterValues();
}
this.onFilterChange.emit({
value: this.filter
@ -104,6 +82,15 @@ export class SearchFilterComponent {
value: this.filter
});
}
clearFilter() {
for (var i=0; i < this.filter.values.length; i++){
this.filter.values[i].selected = false;
}
this.filter.countSelectedValues = 0;
this.onFilterChange.emit({
value: this.filter
});
}
getSelectedValues(filter, sortBy:string = "num"):any{
var selected = [];
if(filter.countSelectedValues >0){
@ -132,15 +119,11 @@ export class SearchFilterComponent {
}
getNotSelectedValues(filter, sortBy:string = "num"):any{
var notSselected = [];
//if(filter.countSelectedValues >0){
for (var i=0; i < filter.values.length; i++){
if(!filter.values[i].selected){
notSselected.push(filter.values[i]);
}
for (var i=0; i < filter.values.length; i++){
if(!filter.values[i].selected){
notSselected.push(filter.values[i]);
}
//}else {
// notSselected = filter.values;
//}
}
if(sortBy == "name"){
@ -148,7 +131,6 @@ export class SearchFilterComponent {
if (n1.name > n2.name) {
return 1;
}
if (n1.name < n2.name) {
return -1;
}
@ -158,67 +140,14 @@ export class SearchFilterComponent {
}
return notSselected;
}
// reorderFilterValues() {
// for(let value of this.filter.values) {
// if(value.selected) {
// let index: number = this.filter.values.indexOf(value);
// let selectedValue:Value = this.filter.values[index];
//
// this.filter.values.splice(index, 1);
// this.filter.values.splice(0, 0, selectedValue);
// }
// }
// }
// sliceSelected() {
// let values: Value[] = [];
//
// for(let value of this.filter.values) {
// if(value.selected) {
// let index: number = this.filter.values.indexOf(value);
// let selectedValue:Value = this.filter.values[index];
//
// this.filter.values.splice(index, 1);
// this.filter.values.splice(0, 0, selectedValue);
// }
// }
// toggle() {
// this.toggleModal.emit({
// value: this.filter
// });
// }
open() {
this.isOpen = true;
toggle() {
this.isOpen = !this.isOpen;
}
close() {
this.isOpen = false;
}
// filterChange2(selected:boolean){
//
// console.info("filter change2");
// if(selected){
// this.filter.countSelectedValues++;
// // this.reorderFilterValues();
// }else{
// this.filter.countSelectedValues--;
// // this.reorderFilterValues();
// }
// this.close();
// }
getFilterName(value){
let name = value.name +" ("+ value.number.format()+")";
console.log(name)
// <span class="filterName"><div title = "{{value.name}}">
// <input [(ngModel)]="value.selected" type="checkbox" (ngModelChange)="filterModalChange(value.selected)">
// {{value.name}} </div></span>
// <span class="filterNumber" *ngIf = "showResultCount === true" > ({{value.number | number}})</span>
console.log(name);
return name;
}
}

View File

@ -7,7 +7,7 @@ export class Filter{
public values: Value[] = [];
public filterOperator: string ='or';
public valueIsExact: boolean = true; // for search table view, if value is contained or is equal with column entry
public valueIsUnique: boolean = false;
public filterType: string = "checkbox";
// public uniqueValueIdSelected: string;
}

View File

@ -18,9 +18,9 @@ export class RefineResultsUtils {
filter.title = searchFields.getFieldName(fields[j],entityType);
filter.filterId = fields[j];
filter.originalFilterId = fields[j];
filter.valueIsUnique = searchFields.fieldHasUniqueValue(fields[j], entityType, usedBy);
filter.filterType = searchFields.getFieldFilterType(fields[j], entityType, usedBy);
filter.filterOperator = searchFields.getFieldOperator(fields[j]);
//console.info("filter.title: "+filter.title+" filter.valueIsUnique: "+filter.valueIsUnique);
//console.info("filter.title: "+filter.title+" filter.filterType: "+filter.filterType);
let field = data[fields[j]];
if(field){
@ -36,7 +36,8 @@ export class RefineResultsUtils {
}
filters.push(filter);
filters.push(filter);
}
}
}

View File

@ -4,10 +4,14 @@ export class SearchFields {
//RESULTS
//Used for datasets and publications and software and orp
//In case Datasets or Software should display different fields, use seperate tables for fields
// "resultacceptanceyear",
public RESULT_RANGE_FIELDS = [
["resultacceptanceyear", "resultacceptanceyear"]
];
public RESULT_REFINE_FIELDS = [
"relfunder",
"relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id",
"relproject","resultacceptanceyear",
"relproject",
"resultbestaccessright", "instancetypename", "resultlanguagename", "community","resulthostingdatasource","collectedfrom" ];
public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","resultauthor", "authorid","resultdescription","resultsubject","resultpublisher",
@ -16,35 +20,38 @@ export class SearchFields {
"relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id",
"resultlanguagename", "relorganizationid", "pid","relprojectid", "instancetypename"];
public RESULT_FIELDS: { [key:string]:FieldDetails}={
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", uniqueValue: false},
["resulttitle"]:{name:"Title", type:"keyword", param:"title", operator: "tt", equalityOperator: "=", uniqueValue: false},
["resultauthor"]:{name:"Author", type:"keyword", param:"author", operator: "at", equalityOperator: "=", uniqueValue: false},
["authorid"]:{name:"Author ORCID", type:"keyword", param:"orcid", operator: "oc", equalityOperator: " exact ", uniqueValue: false},
["resultsubject"]:{name:"Subject", type:"keyword", param:"subject", operator: "sb", equalityOperator: "=", uniqueValue: false},
["resultdescription"]:{name:"Description", type:"keyword", param:"description", operator: "ds", equalityOperator: "=", uniqueValue: false},
["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", operator: "pb", equalityOperator: "=", uniqueValue: false},
["pid"]:{name:"PID", type:"keyword", param:"pid", operator: "pd", equalityOperator: " = ", uniqueValue: false},
["resulthostingdatasourceid"]:{name:"Hosting Content Provider", type:"entity", param:"hostedBy", operator: "hs", equalityOperator: " exact ", uniqueValue: false},
["resulthostingdatasource"]:{name:"Content Provider", type:"refine", param:"hostedBy", operator: "hs", equalityOperator: " exact ", uniqueValue: false},
["instancetypename"]:{name:"Type", type:"vocabulary", param:"type", operator: "tp", equalityOperator: " exact ", uniqueValue: false},
["resultlanguagename"]:{name:"Language", type:"vocabulary", param:"lang", operator: "ln", equalityOperator: " exact ", uniqueValue: false},
["community"]:{name:"Community", type:"refine", param:"community", operator: "cm", equalityOperator: " exact ", uniqueValue: false},
["relproject"]:{name:"Project", type:"refine", param:"project", operator: "po", equalityOperator: " exact ", uniqueValue: false},
["relprojectid"]:{name:"Project", type:"entity", param:"project", operator: "po", equalityOperator: " exact ", uniqueValue: false},
["relfunder"]:{name:"Funder", type:"refine", param:"funder", operator: "fn", equalityOperator: " exact ", uniqueValue: false},
["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", operator: "fn0", equalityOperator: " exact ", uniqueValue: false},
["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", operator: "fn1", equalityOperator: " exact ", uniqueValue: false},
["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", operator: "fn0", equalityOperator: " exact ", uniqueValue: false},
["resultacceptanceyear"]:{name:"Publication Date", type:"keyword", param:"year", operator: "ya", equalityOperator: " exact ", uniqueValue: false},
["resultdateofacceptance"]:{name:"Publication Date", type:"date", param:"date", operator: "dt", equalityOperator: " within ", uniqueValue: false},
["resultbestaccessright"]:{name:"Access Mode", type:"vocabulary", param:"access", operator: "ac", equalityOperator: " exact ", uniqueValue: false},
["collectedfrom"]:{name:"Collected From", type:"refine", param:"datasource", operator: "cl", equalityOperator: " exact ", uniqueValue: false},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", uniqueValue: false},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", uniqueValue: false}
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", filterType: null},
["resulttitle"]:{name:"Title", type:"keyword", param:"title", operator: "tt", equalityOperator: "=", filterType: null},
["resultauthor"]:{name:"Author", type:"keyword", param:"author", operator: "at", equalityOperator: "=", filterType: null},
["authorid"]:{name:"Author ORCID", type:"keyword", param:"orcid", operator: "oc", equalityOperator: " exact ", filterType: null},
["resultsubject"]:{name:"Subject", type:"keyword", param:"subject", operator: "sb", equalityOperator: "=", filterType: null},
["resultdescription"]:{name:"Description", type:"keyword", param:"description", operator: "ds", equalityOperator: "=", filterType: null},
["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", operator: "pb", equalityOperator: "=", filterType: null},
["pid"]:{name:"PID", type:"keyword", param:"pid", operator: "pd", equalityOperator: " = ", filterType: null},
["resulthostingdatasourceid"]:{name:"Hosting Content Provider", type:"entity", param:"hostedBy", operator: "hs", equalityOperator: " exact ", filterType: null},
["resulthostingdatasource"]:{name:"Content Provider", type:"refine", param:"hostedBy", operator: "hs", equalityOperator: " exact ", filterType: "checkbox"},
["instancetypename"]:{name:"Type", type:"vocabulary", param:"type", operator: "tp", equalityOperator: " exact ", filterType: "checkbox"},
["resultlanguagename"]:{name:"Language", type:"vocabulary", param:"lang", operator: "ln", equalityOperator: " exact ", filterType: "checkbox"},
["community"]:{name:"Community", type:"refine", param:"community", operator: "cm", equalityOperator: " exact ", filterType: "checkbox"},
["relproject"]:{name:"Project", type:"refine", param:"project", operator: "po", equalityOperator: " exact ", filterType: "checkbox"},
["relprojectid"]:{name:"Project", type:"entity", param:"project", operator: "po", equalityOperator: " exact ", filterType: null},
["relfunder"]:{name:"Funder", type:"refine", param:"funder", operator: "fn", equalityOperator: " exact ", filterType: "checkbox"},
["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", operator: "fn0", equalityOperator: " exact ", filterType: "checkbox"},
["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", operator: "fn1", equalityOperator: " exact ", filterType: "checkbox"},
["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", operator: "fn0", equalityOperator: " exact ", filterType: "checkbox"},
["resultacceptanceyear"]:{name:"Publication Date", type:"keyword", param:"year", operator: "ya", equalityOperator: " = ", filterType: null},
["resultdateofacceptance"]:{name:"Publication Date", type:"date", param:"date", operator: "dt", equalityOperator: " exact ", filterType: null},
["resultacceptanceyear-range-resultacceptanceyear"]:{name:"Published between", type:"keyword", param:"year", operator: "ya", equalityOperator: " within ", filterType: "range"},
["resultbestaccessright"]:{name:"Access Mode", type:"vocabulary", param:"access", operator: "ac", equalityOperator: " exact ", filterType: "radio"},
["collectedfrom"]:{name:"Collected From", type:"refine", param:"datasource", operator: "cl", equalityOperator: " exact ", filterType: "checkbox"},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", filterType: null},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", filterType: null}
};
//PROJECT
public PROJECT_RANGE_FIELDS = [
["projectendyear", "projectstartyear"]
];
public PROJECT_REFINE_FIELDS:string[] = ["funder","fundinglevel0_id","fundinglevel1_id",
"fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"];
public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords",
@ -52,23 +59,24 @@ export class SearchFields {
"projectstartdate","projectenddate","projectecsc39",
"projectcode_nt","relorganizationid", "collectedfromdatasourceid"];
public PROJECT_FIELDS: { [key:string]:FieldDetails}={
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", uniqueValue: false},
["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", operator: "ar", equalityOperator: "=", uniqueValue: false},
["projecttitle"]:{name:"Title", type:"keyword", param:"title", operator: "tt", equalityOperator: "=", uniqueValue: false},
["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", operator: "ky", equalityOperator: "=", uniqueValue: false},
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", filterType: null},
["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", operator: "ar", equalityOperator: "=", filterType: null},
["projecttitle"]:{name:"Title", type:"keyword", param:"title", operator: "tt", equalityOperator: "=", filterType: null},
["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", operator: "ky", equalityOperator: "=", filterType: null},
["funder"]:{name:"Funder", type:"refine", param:"funder", operator: "fn", equalityOperator: " exact ", uniqueValue: false},
["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", operator: "fn0", equalityOperator: " exact ", uniqueValue: false},
["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", operator: "fn1", equalityOperator: " exact ", uniqueValue: false},
["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", operator: "fn2", equalityOperator: " exact ", uniqueValue: false},
["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", operator: "sy", equalityOperator: " exact ", uniqueValue: false},
["projectendyear"]:{name:"End Year", type:"year", param:"endyear", operator: "ey", equalityOperator: " exact ", uniqueValue: false},
["projectstartdate"]:{name:"Start Date", type:"date", param:"startdate", operator: "sd", equalityOperator: " within ", uniqueValue: false},
["projectenddate"]:{name:"End Date", type:"date", param:"enddate", operator: "ed", equalityOperator: " within ", uniqueValue: false},
["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", operator: "sc", equalityOperator: " exact ", uniqueValue: false},
["projectcode_nt"]:{name:"Project Code", type:"keyword", param:"code", operator: "cd", equalityOperator: " exact ", uniqueValue: false},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", uniqueValue: false},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", uniqueValue: false}
["funder"]:{name:"Funder", type:"refine", param:"funder", operator: "fn", equalityOperator: " exact ", filterType: "checkbox"},
["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", operator: "fn0", equalityOperator: " exact ", filterType: "checkbox"},
["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", operator: "fn1", equalityOperator: " exact ", filterType: "checkbox"},
["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", operator: "fn2", equalityOperator: " exact ", filterType: "checkbox"},
["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", operator: "sy", equalityOperator: " <= ", filterType: "checkbox"},
["projectendyear"]:{name:"End Year", type:"year", param:"endyear", operator: "ey", equalityOperator: " >= ", filterType: "checkbox"},
["projectendyear-range-projectstartyear"]:{name:"Active years", type:"year", param:"year", operator: "ya", equalityOperator: " = ", filterType: "range"},
["projectstartdate"]:{name:"Start Date", type:"date", param:"startdate", operator: "sd", equalityOperator: " within ", filterType: null},
["projectenddate"]:{name:"End Date", type:"date", param:"enddate", operator: "ed", equalityOperator: " within ", filterType: null},
["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", operator: "sc", equalityOperator: " exact ", filterType: "radio"},
["projectcode_nt"]:{name:"Project Code", type:"keyword", param:"code", operator: "cd", equalityOperator: " exact ", filterType: null},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", filterType: null},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", filterType: null}
};
@ -81,20 +89,20 @@ export class SearchFields {
"datasourceodcontenttypes", "datasourcecompatibilityname","relorganizationid", "collectedfromdatasourceid"];
public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", uniqueValue: false},
["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", operator: "of", equalityOperator: "=", uniqueValue: false},
["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", operator: "eg", equalityOperator: "=", uniqueValue: false},
["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", operator: "sb", equalityOperator: "=", uniqueValue: false},
["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", uniqueValue: false},
["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", uniqueValue: false},
["datasourcetypename"]:{name:"Type", type:"vocabulary", param:"type", operator: "tp", equalityOperator: " exact ", uniqueValue: false},
["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", operator: "ln", equalityOperator: " exact ", uniqueValue: false},
["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", operator: "cn", equalityOperator: " exact ", uniqueValue: false},
["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"refine", param:"compatibility", operator: "cm", equalityOperator: " exact ", uniqueValue: false},
["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", operator: "cm", equalityOperator: " exact ", uniqueValue: false},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", uniqueValue: false},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", uniqueValue: false},
["country"]:{name:"Country", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", uniqueValue: false}
["q"]:{name:"All fields", type:"keyword", param:"q", operator: "op", equalityOperator: "=", filterType: null},
["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", operator: "of", equalityOperator: "=", filterType: null},
["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", operator: "eg", equalityOperator: "=", filterType: null},
["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", operator: "sb", equalityOperator: "=", filterType: null},
["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", filterType: null},
["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", filterType: "checkbox"},
["datasourcetypename"]:{name:"Type", type:"vocabulary", param:"type", operator: "tp", equalityOperator: " exact ", filterType: null},
["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", operator: "ln", equalityOperator: " exact ", filterType: "checkbox"},
["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", operator: "cn", equalityOperator: " exact ", filterType: "checkbox"},
["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"refine", param:"compatibility", operator: "cm", equalityOperator: " exact ", filterType: null},
["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", operator: "cm", equalityOperator: " exact ", filterType: "checkbox"},
["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", operator: "og", equalityOperator: " exact ", filterType: null},
["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", operator: "cl", equalityOperator: " exact ", filterType: null},
["country"]:{name:"Country", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", filterType: "checkbox"}
};
public DEPOSIT_DATASOURCE_KEYWORD_FIELDS: { "name": string, "equalityOperator": string} []= [
@ -109,11 +117,11 @@ export class SearchFields {
public DEPOSIT_DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "country", "datasourceodsubjects", "datasourceodcontenttypes", "datasourcecompatibilityname"];
public DEPOSIT_DATASOURCE_FIELDS: { [key:string]:FieldDetails}={
["datasourcetypeuiname"]:{name:"Repository type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", uniqueValue: true},
["country"]:{name:"Countries", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", uniqueValue: false},
["datasourceodsubjects"]:{name:"Subjects", type:"keyword", param:"subjects", operator: "sb", equalityOperator: "=", uniqueValue: false},
["datasourceodcontenttypes"]:{name:"Content type", type:"refine", param:"content", operator: "cn", equalityOperator: " exact ", uniqueValue: false},
["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", operator: "cm", equalityOperator: " exact ", uniqueValue: true},
["datasourcetypeuiname"]:{name:"Repository type", type:"refine", param:"type", operator: "tp", equalityOperator: " exact ", filterType: "radio"},
["country"]:{name:"Countries", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", filterType: "checkbox"},
["datasourceodsubjects"]:{name:"Subjects", type:"keyword", param:"subjects", operator: "sb", equalityOperator: "=", filterType: "checkbox"},
["datasourceodcontenttypes"]:{name:"Content type", type:"refine", param:"content", operator: "cn", equalityOperator: " exact ", filterType: "checkbox"},
["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", operator: "cm", equalityOperator: " exact ", filterType: "checkbox"},
};
public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityname"];
@ -126,10 +134,10 @@ export class SearchFields {
public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", "organizationlegalname","organizationlegalshortname","country"];
public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={
["q"]:{name:"All fields", type:"keyword", param:"q", operator:"op", equalityOperator: "=", uniqueValue: false},
["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", operator: "nm", equalityOperator: "=", uniqueValue: false},
["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", operator: "so", equalityOperator: "=", uniqueValue: false},
["country"]:{name:"Country", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", uniqueValue: false},
["q"]:{name:"All fields", type:"keyword", param:"q", operator:"op", equalityOperator: "=", filterType: null},
["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", operator: "nm", equalityOperator: "=", filterType: null},
["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", operator: "so", equalityOperator: "=", filterType: null},
["country"]:{name:"Country", type:"vocabulary", param:"country", operator: "cu", equalityOperator: "=", filterType: "checkbox"},
};
// public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"];
// public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"];
@ -173,24 +181,38 @@ export class SearchFields {
}
}
fieldHasUniqueValue(fieldId:string,fieldType:string,usedBy:string="search"):boolean{
getFieldFilterType(fieldId:string, fieldType:string, usedBy:string="search"):string{
if(fieldType == "publication" || fieldType == "dataset" || fieldType == "software" || fieldType == "other"|| fieldType == "result"){
return this.RESULT_FIELDS[fieldId].uniqueValue;
return this.RESULT_FIELDS[fieldId].filterType;
}else if(fieldType == "project"){
return this.PROJECT_FIELDS[fieldId].uniqueValue;
return this.PROJECT_FIELDS[fieldId].filterType;
}else if(fieldType == "organization"){
return this.ORGANIZATION_FIELDS[fieldId].uniqueValue;
return this.ORGANIZATION_FIELDS[fieldId].filterType;
}else if(fieldType == "datasource" || fieldType == "dataprovider"){
if(usedBy == "search") {
return this.DATASOURCE_FIELDS[fieldId].uniqueValue;
return this.DATASOURCE_FIELDS[fieldId].filterType;
} else if(usedBy == "deposit") {
return this.DEPOSIT_DATASOURCE_FIELDS[fieldId].uniqueValue;
return this.DEPOSIT_DATASOURCE_FIELDS[fieldId].filterType;
}
}else{
return false;
return "checkbox";
}
}
getFieldParam(fieldId:string,fieldType:string):string{
if(fieldType == "publication" || fieldType == "dataset" || fieldType == "software" || fieldType == "other" || fieldType == "result"){
return this.RESULT_FIELDS[fieldId].param;
}else if(fieldType == "project"){
return this.PROJECT_FIELDS[fieldId].param;
}else if(fieldType == "organization"){
return this.ORGANIZATION_FIELDS[fieldId].param;
}else if(fieldType == "datasource" || fieldType == "dataprovider"){
return this.DATASOURCE_FIELDS[fieldId].param;
}else{
return "UNDEFINED";
}
}
/*
AND
Funder: relfunder, relfundinglevel0_id, relfundinglevel1_id, relfundinglevel2_id
@ -220,7 +242,7 @@ RANGE
getFieldOperator(fieldId:string):string{
if(fieldId == "relfunder" || fieldId == "relfundinglevel0_id" || fieldId == "relfundinglevel1_id" || fieldId == "relfundinglevel2_id"
|| fieldId == "relproject" || fieldId == "community") {
|| fieldId == "relproject" || fieldId == "community" || fieldId == "projectendyear-range-projectstartyear") {
return "and";
} else if(fieldId == "instancetypename" || fieldId == "datasourcetypeuiname"
|| fieldId == "resultlanguagename" || fieldId == "datasourceodlanguages"
@ -237,5 +259,5 @@ export class FieldDetails{
param:string;
equalityOperator:string;
operator:string;
uniqueValue: boolean = false;
filterType: string = "checkbox";
}

View File

@ -0,0 +1,19 @@
import { Directive } from '@angular/core';
import { AbstractControl, FormGroup, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
export const fromYearAfterToYearValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const yearFrom = control.get('yearFrom');
const yearTo = control.get('yearTo');
return ((yearFrom && yearTo && (parseInt(yearFrom.value, 10) > parseInt(yearTo.value, 10))) ? { 'fromYearAfterToYear': true } : null);
};
@Directive({
selector: '[fromYearAfterToYear]',
providers: [{ provide: NG_VALIDATORS, useExisting: FromYearAfterToYearValidatorDirective, multi: true }]
})
export class FromYearAfterToYearValidatorDirective implements Validator {
validate(control: AbstractControl): ValidationErrors {
return fromYearAfterToYearValidator(control)
}
}

View File

@ -0,0 +1,19 @@
import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } from '@angular/forms';
import { Dates } from "../string-utils.class";
export function inValidYearValidator(): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
return ((control.value && !Dates.isValidYear(control.value)) ? {'inValidYear': {value: control.value}} : null);
};
}
@Directive({
selector: '[inValidYear]',
providers: [{provide: NG_VALIDATORS, useExisting: InValidYearValidatorDirective, multi: true}]
})
export class InValidYearValidatorDirective implements Validator {
validate(control: AbstractControl): {[key: string]: any} | null {
return inValidYearValidator()(control);
}
}

View File

@ -0,0 +1,44 @@
<div class="uk-margin-small-bottom">
<div class="uk-margin-small-top uk-margin-bottom uk-grid uk-flex uk-flex-bottom">
<h5 class="uk-margin-bottom-remove">{{_formatTitle(filter.title)}}</h5>
<a *ngIf="filter.selectedFromValue || filter.selectedToValue" (click)="clearFilter()" class="portal-link">
Clear
</a>
</div>
<div aria-expanded="false">
<div>
<div class = "uk-animation-fade filterItem searchFilterItem uk-text-small">
<div class="searchFilterBoxValues ">
<form class="uk-inline uk-text-small form-group" #rangeForm="ngForm" fromYearAfterToYear>
<input class=" uk-input form-control uk-width-1-3" (focus)="focusedInput = 'from'" (blur)="focusedInput = ''"
[(ngModel)]="filter.selectedFromValue" name="yearFrom" #yearFrom="ngModel" inValidYear
placeholder="From"/>
<input class=" uk-input form-control uk-width-1-3 uk-margin-left" (focus)="focusedInput = 'to'" (blur)="focusedInput = ''"
[(ngModel)]="filter.selectedToValue" name="yearTo" #yearTo="ngModel" inValidYear
placeholder="To"/>
<button type="submit" (click)="yearChanged()"
[ngStyle]="{'cursor': rangeForm.valid ? 'pointer' : 'not-allowed'}" class="uk-icon uk-width-1-6 uk-text-right"
[disabled]="rangeForm.invalid">
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
icon="chevron-right" ratio="1">
<polyline fill="none" stroke="#000" stroke-width="1.03" points="7 4 13 10 7 16"></polyline>
</svg>
</button>
<div *ngIf="(yearFrom.invalid && focusedInput != 'from' && (yearFrom.dirty || yearFrom.touched)) ||
(yearTo.invalid && focusedInput != 'to' && (yearTo.dirty || yearTo.touched))"
class="alert alert-danger uk-margin-small-top">
<div *ngIf="(yearFrom.errors && yearFrom.errors.inValidYear) || (yearTo.errors && yearTo.errors.inValidYear)">
Year must be between {{yearMin}} and {{yearMax}}.
</div>
</div>
<div *ngIf="yearFrom.valid && yearTo.valid && rangeForm.errors?.fromYearAfterToYear && (rangeForm.touched || rangeForm.dirty)"
class="alert alert-danger uk-margin-small-top">
"From" year must be equal or greater than "To" year.
</div>
</form>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,47 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
import { RangeFilter } from './rangeFilterHelperClasses.class';
import { Dates } from "../string-utils.class";
@Component({
selector: 'range-filter',
templateUrl: 'rangeFilter.component.html'
})
export class RangeFilterComponent {
@Input() filter:RangeFilter;
@Input() isDisabled:boolean = false;
public _maxCharacters:number =28;
public focusedInput: string = "";
public yearMin = Dates.yearMin;
public yearMax = Dates.yearMax;
@Output() onFilterChange = new EventEmitter();
constructor() {}
ngOnInit() {}
public _formatTitle(title){
return ((title.length > this._maxCharacters)?(title.substring(0,(this._maxCharacters - ('...').length))+"..."):title);
}
yearChanged(){
this.onFilterChange.emit({
value: this.filter
});
}
clearFilter() {
this.filter.selectedFromValue = null;
this.filter.selectedToValue = null;
this.onFilterChange.emit({
value: this.filter
});
}
getFilterName(value){
let name = value.name +" ("+ value.number.format()+")";
return name;
}
}

View File

@ -0,0 +1,23 @@
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import {RangeFilterComponent} from './rangeFilter.component';
import {InValidYearValidatorDirective} from "./inValidYear.directive";
import {FromYearAfterToYearValidatorDirective} from "./fromYearAfterToYear.directive";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule
],
declarations: [
RangeFilterComponent, InValidYearValidatorDirective, FromYearAfterToYearValidatorDirective
],
providers:[
],
exports: [
RangeFilterComponent
]
})
export class RangeFilterModule { }

View File

@ -0,0 +1,30 @@
import {Filter, Value} from "../../searchPages/searchUtils/searchHelperClasses.class";
import {SearchFields} from "../properties/searchFields";
export class RangeFilter{
public title: string; // eg Publication Date Range
public filterId: string; // type (name in url parameter)
public originalFilterIdFrom: string; // (in index)
public originalFilterIdTo: string; // (in index)
public selectedFromValue: string;
public selectedToValue: string;
public selectedFromAndToValues: string = "";
public static parse (fields:string[][], entityType:string,):RangeFilter[] {
var searchFields:SearchFields = new SearchFields();
var filters:RangeFilter[] = [];
if(fields){
for(let j=0; j<fields.length; j++) {
var filter:RangeFilter = new RangeFilter();
filter.title = searchFields.getFieldName(fields[j][0]+"-range-"+fields[j][1] ,entityType);
filter.filterId = searchFields.getFieldParam(fields[j][0]+"-range-"+fields[j][1] ,entityType);
filter.originalFilterIdFrom = fields[j][0];
filter.originalFilterIdTo = fields[j][1];
filters.push(filter);
}
}
return filters;
}
}

View File

@ -1,6 +1,9 @@
import {UrlSegment} from '@angular/router';
export class Dates {
public static yearMin = 1800;
public static yearMax = (new Date().getFullYear()) + 10;
public static isValidYear(yearString){
// First check for the pattern
if(!/^\d{4}$/.test(yearString))
@ -8,7 +11,7 @@ export class Dates {
var year = parseInt(yearString, 10);
// Check the ranges of month and year
if(year < 1000 || year > 3000 )
if(year < this.yearMin || year > this.yearMax )
return false;
return true;
}