LP1819236 Ang cat prevent keyword starts/exact searches
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / search-form.component.html
1 <div id='staffcat-search-form'>
2
3   <div *ngIf="!showThyself" class="row pt-1 pb-1 mb-2 pr-2">
4     <div class="col-lg-12 d-flex">
5       <div class="flex-1"></div><!-- push right -->
6       <a (click)="showThyself=true" class="label-with-material-icon no-href" i18n>
7         Show Search Form <span class="material-icons">unfold_more</span>
8       </a>
9     </div>
10   </div>
11   
12   <div *ngIf="showThyself" class="row pt-3 pb-3 mb-3">
13   <div class="col-lg-8">
14     <ngb-tabset #searchTabs [activeId]="searchTab" (tabChange)="onTabChange($event)">
15       <ngb-tab title="Keyword Search" i18n-title id="term">
16         <ng-template ngbTabContent>
17           <div class="row"
18             [ngClass]="{'mt-4': idx == 0, 'mt-1': idx > 0}"
19             *ngFor="let q of context.termSearch.query; let idx = index; trackBy:trackByIdx">
20             <div class="col-lg-2 pr-1">
21               <div *ngIf="idx == 0">
22                 <select class="form-control" [(ngModel)]="context.termSearch.format">
23                   <option i18n value=''>All Formats</option>
24                   <option *ngFor="let fmt of ccvmMap.search_format"
25                     value="{{fmt.code()}}">{{fmt.value()}}</option>
26                 </select>
27               </div>
28               <div *ngIf="idx > 0">
29                 <select class="form-control"
30                   [(ngModel)]="context.termSearch.joinOp[idx]">
31                   <option i18n value='&&'>And</option>
32                   <option i18n value='||'>Or</option>
33                 </select>
34               </div>
35             </div>
36             <div class="col-lg-2 pl-0 pr-2">
37               <select class="form-control" 
38                 (change)="preventBogusCombos(idx)"
39                 [(ngModel)]="context.termSearch.fieldClass[idx]">
40                 <option i18n value='keyword'>Keyword</option>
41                 <option i18n value='title'>Title</option>
42                 <option i18n value='jtitle'>Journal Title</option>
43                 <option i18n value='author'>Author</option>
44                 <option i18n value='subject'>Subject</option>
45                 <option i18n value='series'>Series</option>
46               </select>
47             </div>
48             <div class="col-lg-2 pl-0 pr-2">
49               <select class="form-control" 
50                 [(ngModel)]="context.termSearch.matchOp[idx]">
51                 <option i18n value='contains'>Contains</option>
52                 <option i18n value='nocontains'>Does not contain</option>
53                 <option i18n value='phrase'>Contains phrase</option>
54                 <option [disabled]="context.termSearch.fieldClass[idx]=='keyword'"
55                   i18n value='exact'>Matches exactly</option>
56                 <option [disabled]="context.termSearch.fieldClass[idx]=='keyword'"
57                   i18n value='starts'>Starts with</option>
58               </select>
59             </div>
60             <div class="col-lg-4 pl-0 pr-2">
61               <div class="form-group">
62                 <div *ngIf="idx == 0">
63                   <input type="text" class="form-control"
64                     id='first-query-input'
65                     [(ngModel)]="context.termSearch.query[idx]"
66                     (keyup.enter)="searchByForm()"
67                     placeholder="Query..."/>
68                 </div>
69                 <div *ngIf="idx > 0">
70                   <input type="text" class="form-control"
71                     [(ngModel)]="context.termSearch.query[idx]"
72                     (keyup.enter)="searchByForm()"
73                     placeholder="Query..."/>
74                 </div>
75               </div>
76             </div>
77             <div class="col-lg-2 pl-0 pr-1">
78               <button class="btn btn-sm material-icon-button"
79                 (click)="addSearchRow(idx + 1)"
80                 i18n-title title="Add Search Row">
81                 <span class="material-icons">add_circle_outline</span>
82               </button>
83               <button class="btn btn-sm material-icon-button"
84                 [disabled]="context.termSearch.query.length < 2"
85                 (click)="delSearchRow(idx)"
86                 i18n-title title="Remove Search Row">
87                 <span class="material-icons">remove_circle_outline</span>
88               </button>
89               <button *ngIf="idx == 0"
90                 class="btn btn-sm material-icon-button" 
91                 type="button" (click)="toggleFilters()" 
92                 title="Toggle Search Filters" i18n-title>
93                 <span class="material-icons">more_vert</span>
94               </button>
95             </div>
96           </div>
97           <div class="row">
98             <div class="col-lg-12 form-inline">
99                 <select class="form-control mr-2" [(ngModel)]="context.sort">
100                   <option value='' i18n>Sort by Relevance</option>
101                   <optgroup label="Sort by Title" i18n-label>
102                     <option value='titlesort' i18n>Title: A to Z</option>
103                     <option value='titlesort.descending' i18n>Title: Z to A</option>
104                   </optgroup>
105                   <optgroup label="Sort by Author" i18n-label>
106                     <option value='authorsort' i18n>Author: A to Z</option>
107                     <option value='authorsort.descending' i18n>Author: Z to A</option>
108                   </optgroup>
109                   <optgroup label="Sort by Publication Date" i18n-label>
110                     <option value='pubdate' i18n>Date: A to Z</option>
111                     <option value='pubdate.descending' i18n>Date: Z to A</option>
112                   </optgroup>
113                   <optgroup label="Sort by Popularity" i18n-label>
114                     <option value='popularity' i18n>Most Popular</option>
115                     <option value='poprel' i18n>Popularity Adjusted Relevance</option>
116                   </optgroup>
117                 </select>
118                 <div class="checkbox pl-2 ml-2">
119                   <label>
120                     <input type="checkbox" [(ngModel)]="context.termSearch.available"/>
121                     <span class="pl-1" i18n>Limit to Available</span>
122                   </label>
123                 </div>
124                 <div class="checkbox pl-3">
125                   <label>
126                     <input type="checkbox"
127                       [(ngModel)]="context.termSearch.groupByMetarecord"/>
128                     <span class="pl-1" i18n>Group Formats/Editions</span>
129                   </label>
130                 </div>
131                 <div class="checkbox pl-3">
132                   <label>
133                     <input type="checkbox" [(ngModel)]="context.termSearch.global"/>
134                     <span class="pl-1" i18n>Results from All Libraries</span>
135                   </label>
136                 </div>
137               </div>
138           </div>
139           <div class="row mt-3" *ngIf="showFilters()">
140             <div class="col-lg-3">
141               <select class="form-control"  multiple="true"
142                 [(ngModel)]="context.termSearch.ccvmFilters.item_type">
143                 <option value='' i18n>All Item Types</option>
144                 <option *ngFor="let itemType of ccvmMap.item_type"
145                   value="{{itemType.code()}}">{{itemType.value()}}</option>
146               </select>
147             </div>
148             <div class="col-lg-3">
149               <select class="form-control" multiple="true"
150                 [(ngModel)]="context.termSearch.ccvmFilters.item_form">
151                 <option value='' i18n>All Item Forms</option>
152                 <option *ngFor="let itemForm of ccvmMap.item_form"
153                   value="{{itemForm.code()}}">{{itemForm.value()}}</option>
154               </select>
155             </div>
156             <div class="col-lg-3">
157               <select class="form-control" 
158                 [(ngModel)]="context.termSearch.ccvmFilters.item_lang" multiple="true">
159                 <option value='' i18n>All Languages</option>
160                 <option *ngFor="let lang of ccvmMap.item_lang"
161                   value="{{lang.code()}}">{{lang.value()}}</option>
162               </select>
163             </div>
164             <div class="col-lg-3">
165               <select class="form-control" 
166                 [(ngModel)]="context.termSearch.ccvmFilters.audience" multiple="true">
167                 <option value='' i18n>All Audiences</option>
168                 <option *ngFor="let audience of ccvmMap.audience"
169                   value="{{audience.code()}}">{{audience.value()}}</option>
170               </select>
171             </div>
172           </div>
173           <div class="row mt-3" *ngIf="showFilters()">
174             <div class="col-lg-3">
175               <select class="form-control" 
176                 [(ngModel)]="context.termSearch.ccvmFilters.vr_format" multiple="true">
177                 <option value='' i18n>All Video Formats</option>
178                 <option *ngFor="let vrFormat of ccvmMap.vr_format"
179                   value="{{vrFormat.code()}}">{{vrFormat.value()}}</option>
180               </select>
181             </div>
182             <div class="col-lg-3">
183               <select class="form-control" 
184                 [(ngModel)]="context.termSearch.ccvmFilters.bib_level" multiple="true">
185                 <option value='' i18n>All Bib Levels</option>
186                 <option *ngFor="let bibLevel of ccvmMap.bib_level"
187                   value="{{bibLevel.code()}}">{{bibLevel.value()}}</option>
188               </select>
189             </div>
190             <div class="col-lg-3">
191               <select class="form-control" 
192                 [(ngModel)]="context.termSearch.ccvmFilters.lit_form" multiple="true">
193                 <option value='' i18n>All Literary Forms</option>
194                 <option *ngFor="let litForm of ccvmMap.lit_form"
195                   value="{{litForm.code()}}">{{litForm.value()}}</option>
196               </select>
197             </div>
198             <div class="col-lg-3">
199               <select class="form-control" 
200                 [(ngModel)]="context.termSearch.copyLocations" multiple="true">
201                 <option value='' i18n>All Copy Locations</option>
202                 <option *ngFor="let loc of copyLocations" value="{{loc.id()}}" i18n>
203                   {{loc.name()}} ({{orgName(loc.owning_lib())}})
204                 </option>
205               </select>
206             </div>
207           </div>
208           <div class="row mt-3" *ngIf="showFilters()">
209             <div class="col-lg-12">
210               <div class="form-inline" i18n>
211                 <label for="pub-date1-input">Publication Year is</label>
212                 <select class="form-control ml-2" [(ngModel)]="context.termSearch.dateOp">
213                   <option value='is'>Is</option>
214                   <option value='before'>Before</option>
215                   <option value='after'>After</option>
216                   <option value='between'>Between</option>
217                 </select>
218                 <input class="form-control ml-2" type="number"
219                   [(ngModel)]="context.termSearch.date1"/>
220                 <input class="form-control ml-2" type="number"
221                   *ngIf="context.termSearch.dateOp == 'between'"
222                   [(ngModel)]="context.termSearch.date2"/>
223               </div>
224             </div>
225           </div>
226         </ng-template>
227       </ngb-tab>
228       <ngb-tab title="Numeric Search" i18n-title id="ident">
229         <ng-template ngbTabContent>
230           <div class="row mt-4">
231             <div class="col-lg-12">
232               <div class="form-inline">
233                 <label for="ident-type" i18n>Query Type</label>
234                 <select class="form-control ml-2" name="ident-type"
235                   [(ngModel)]="context.identSearch.queryType">
236                   <option i18n value="identifier|isbn">ISBN</option>
237                   <option i18n value="identifier|issn">ISSN</option>
238                   <option i18n value="identifier|lccn">LCCN</option>
239                   <option i18n value="identifier|tcn">TCN</option>
240                   <option i18n value="item_barcode">Item Barcode</option>
241                 </select>
242                 <label for="ident-value" class="ml-2" i18n>Value</label>
243                 <input name="ident-value" id='ident-query-input' 
244                   type="text" class="form-control ml-2"
245                   [(ngModel)]="context.identSearch.value"
246                   (keyup.enter)="searchByForm()"
247                   placeholder="Numeric Query..."/>
248               </div>
249             </div>
250           </div>
251         </ng-template>
252       </ngb-tab>
253       <ngb-tab title="MARC Search" i18n-title id="marc">
254         <ng-template ngbTabContent>
255           <div class="row mt-4">
256             <div class="col-lg-12">
257               <div class="form-inline mt-2" 
258                 *ngFor="let q of context.marcSearch.values; let idx = index; trackBy:trackByIdx">
259                 <label for="marc-tag-{{idx}}" i18n>Tag</label>
260                 <input class="form-control ml-2" size="3" type="text" 
261                   name="marc-tag-{{idx}}" id="{{ idx == 0 ? 'first-marc-tag' : '' }}"
262                   [(ngModel)]="context.marcSearch.tags[idx]"
263                   (keyup.enter)="searchByForm()"/>
264                 <label for="marc-subfield-{{idx}}" class="ml-2" i18n>Subfield</label>
265                 <input class="form-control ml-2" size="1" type="text" 
266                   name="marc-subfield-{{idx}}"
267                   [(ngModel)]="context.marcSearch.subfields[idx]"
268                   (keyup.enter)="searchByForm()"/>
269                 <label for="marc-value-{{idx}}" class="ml-2" i18n>Value</label>
270                 <input class="form-control ml-2" type="text" name="marc-value-{{idx}}"
271                   [(ngModel)]="context.marcSearch.values[idx]" 
272                   (keyup.enter)="searchByForm()"/>
273                 <button class="btn btn-sm material-icon-button ml-2"
274                   (click)="addMarcSearchRow(idx + 1)">
275                   <span class="material-icons">add_circle_outline</span>
276                 </button>
277                 <button class="btn btn-sm material-icon-button ml-2"
278                   [disabled]="context.marcSearch.values.length < 2"
279                   (click)="delMarcSearchRow(idx)">
280                   <span class="material-icons">remove_circle_outline</span>
281                 </button>
282               </div>
283             </div>
284           </div>
285         </ng-template>
286       </ngb-tab>
287       <ngb-tab title="Browse" i18n-title id="browse">
288         <ng-template ngbTabContent>
289           <div class="row mt-4">
290             <div class="col-lg-12 form-inline">
291               <label for="field-class" i18n>Browse for</label>
292               <select class="form-control ml-2" name="field-class"
293                 [(ngModel)]="context.browseSearch.fieldClass">
294                 <option i18n value='title'>Title</option>
295                 <option i18n value='author'>Author</option>
296                 <option i18n value='subject'>Subject</option>
297                 <option i18n value='series'>Series</option>
298               </select>
299               <label for="query" class="ml-2"> starting with </label>
300               <input type="text" class="form-control ml-2" 
301                 id='browse-term-input' name="query"
302                 [(ngModel)]="context.browseSearch.value"
303                 (keyup.enter)="searchByForm()"
304                 placeholder="Browse for..."/>
305             </div>
306           </div>
307         </ng-template>
308       </ngb-tab>
309       <ngb-tab title="Shelf Browse" i18n-title id="cnbrowse">
310         <ng-template ngbTabContent>
311           <div class="row mt-4">
312             <div class="col-lg-12 form-inline">
313               <label for="cnbrowse-term-input" i18n>
314                 Browse Call Numbers starting with 
315               </label>
316               <input type="text" class="form-control ml-2" 
317                 id='cnbrowse-term-input' name="query"
318                 [(ngModel)]="context.cnBrowseSearch.value"
319                 (keyup.enter)="searchByForm()"
320                 placeholder="Browse Call Numbers..."/>
321             </div>
322           </div>
323         </ng-template>
324       </ngb-tab>      
325     </ngb-tabset>
326   </div>
327   <div class="col-lg-4">
328     <div class="row">
329       <div class="col-lg-12">
330         <div class="card">
331           <div class="card-body">
332             <div class="float-right d-flex">
333               <eg-org-select 
334                 (onChange)="orgOnChange($event)"
335                 [initialOrg]="context.searchOrg"
336                 [placeholder]="'Library'" >
337               </eg-org-select>
338               <button class="btn btn-success mr-1 ml-1" type="button"
339                 [disabled]="searchIsActive()"
340                 (click)="context.pager.offset=0;searchByForm()" i18n>
341                 Search
342               </button>
343               <button class="btn btn-warning mr-1" type="button"
344                 [disabled]="searchIsActive()"
345                 (click)="context.reset()" i18n>
346                 Reset
347               </button>
348             </div>
349           </div>
350         </div>
351       </div>
352     </div>
353     <div class="row mt-1">
354       <div class="col-lg-12">
355         <eg-catalog-search-templates [searchTab]="searchTab">
356         </eg-catalog-search-templates>
357       </div>
358     </div>
359     <div class="row mt-1">
360       <div class="col-lg-12">
361         <eg-catalog-basket-actions></eg-catalog-basket-actions>
362       </div>
363     </div>
364   </div>
365   </div>
366 </div>
367