joinOp: [],
matchOp: [],
facets: [],
+ identQuery: null,
+ identQueryType: null,
org: null,
limit: null,
offset: null
}
// These fields can be copied directly into place
- ['format', 'sort', 'available', 'global']
+ ['format', 'sort', 'available', 'global', 'identQuery', 'identQueryType']
.forEach(field => {
if (context[field]) {
// Only propagate applied values to the URL.
context.reset();
// These fields can be copied directly into place
- ['format', 'sort', 'available', 'global']
+ ['format', 'sort', 'available', 'global', 'identQuery', 'identQueryType']
.forEach(field => {
const val = params.get(field);
if (val !== null) {
sort: string;
fieldClass: string[];
query: string[];
+ identQuery: string;
+ identQueryType: string; // isbn, issn, etc.
joinOp: string[];
matchOp: string[];
format: string;
this.format = '';
this.sort = '';
this.query = [''];
+ this.identQuery = null;
+ this.identQueryType = 'isbn';
this.fieldClass = ['keyword'];
this.matchOp = ['contains'];
this.joinOp = [''];
}
isSearchable(): boolean {
+
+ if (this.identQuery && this.identQueryType) {
+ return true;
+ }
+
return this.query.length
&& this.query[0] !== ''
&& this.searchOrg !== null;
str += ' sort(' + parts[0] + ')';
}
- // -------
- // Compile boolean sub-query components
- if (str.length) { str += ' '; }
- const qcount = this.query.length;
+ if (this.identQuery && this.identQueryType) {
+ if (str) { str += ' '; }
+ str += this.identQueryType + ':' + this.identQuery;
- // if we multiple boolean query components, wrap them in parens.
- if (qcount > 1) { str += '('; }
- this.query.forEach((q, idx) => {
- str += this.compileBoolQuerySet(idx);
- });
- if (qcount > 1) { str += ')'; }
- // -------
+ } else {
+
+ // -------
+ // Compile boolean sub-query components
+ if (str.length) { str += ' '; }
+ const qcount = this.query.length;
+
+ // if we multiple boolean query components, wrap them in parens.
+ if (qcount > 1) { str += '('; }
+ this.query.forEach((q, idx) => {
+ str += this.compileBoolQuerySet(idx);
+ });
+ if (qcount > 1) { str += ')'; }
+ // -------
+ }
if (this.format) {
str += ' format(' + this.format + ')';
<div class="flex-1">
<div *ngIf="idx == 0">
<select class="form-control" [(ngModel)]="searchContext.format">
- <option value=''>All Formats</option>
+ <option i18n value=''>All Formats</option>
<option *ngFor="let fmt of ccvmMap.search_format"
value="{{fmt.code()}}">{{fmt.value()}}</option>
</select>
<div *ngIf="idx > 0">
<select class="form-control"
[(ngModel)]="searchContext.joinOp[idx]">
- <option value='&&'>And</option>
- <option value='||'>Or</option>
+ <option i18n value='&&'>And</option>
+ <option i18n value='||'>Or</option>
</select>
</div>
</div>
<div class="flex-1 pl-1">
<select class="form-control"
[(ngModel)]="searchContext.fieldClass[idx]">
- <option value='keyword'>Keyword</option>
- <option value='title'>Title</option>
- <option value='jtitle'>Journal Title</option>
- <option value='author'>Author</option>
- <option value='subject'>Subject</option>
- <option value='series'>Series</option>
+ <option i18n value='keyword'>Keyword</option>
+ <option i18n value='title'>Title</option>
+ <option i18n value='jtitle'>Journal Title</option>
+ <option i18n value='author'>Author</option>
+ <option i18n value='subject'>Subject</option>
+ <option i18n value='series'>Series</option>
</select>
</div>
<div class="flex-1 pl-1">
<select class="form-control"
[(ngModel)]="searchContext.matchOp[idx]">
- <option value='contains'>Contains</option>
- <option value='nocontains'>Does not contain</option>
- <option value='phrase'>Contains phrase</option>
- <option value='exact'>Matches exactly</option>
- <option value='starts'>Starts with</option>
+ <option i18n value='contains'>Contains</option>
+ <option i18n value='nocontains'>Does not contain</option>
+ <option i18n value='phrase'>Contains phrase</option>
+ <option i18n value='exact'>Matches exactly</option>
+ <option i18n value='starts'>Starts with</option>
</select>
</div>
<div class="flex-2 pl-1">
value="{{audience.code()}}">{{audience.value()}}</option>
</select>
</div>
+ <div class="col-lg-2">
+ <select class="form-control"
+ [(ngModel)]="searchContext.identQueryType">
+ <option i18n value="identifier|isbn">ISBN</option>
+ <option i18n value="identifier|issn">ISSN</option>
+ <option i18n disabled value="cnbrowse">Call Number (Shelf Browse)</option>
+ <option i18n value="identifier|lccn">LCCN</option>
+ <option i18n value="identifier|tcn">TCN</option>
+ <option i18n disabled value="item_barcode">Item Barcode</option>
+ </select>
+ </div>
+ <div class="col-lg-2">
+ <input id='ident-query-input' type="text" class="form-control"
+ [(ngModel)]="searchContext.identQuery"
+ (keyup.enter)="formEnter()"
+ placeholder="Numeric Query..."/>
+ </div>
</div>
<div class="row pt-2" *ngIf="showAdvanced()">
<div class="col-lg-2">
// Query inputs are generated from search context data,
// so they are not available until after the first render.
// Search context data is extracted synchronously from the URL.
- this.renderer.selectRootElement('#first-query-input').focus();
+
+ if (this.searchContext.identQuery) {
+ // Focus identifier query input if identQuery is in progress
+ this.renderer.selectRootElement('#ident-query-input').focus();
+ } else {
+ // Otherwise focus the main query input
+ this.renderer.selectRootElement('#first-query-input').focus();
+ }
}
/**
}
});
+ if (this.searchContext.identQuery) {
+ show = true;
+ }
+
return show;
}