mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-25 02:04:15 +02:00
implementing typed search
This commit is contained in:
parent
60dab77cf4
commit
d32914bc02
@ -4,7 +4,7 @@ import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {Directory} from "../../common/entities/Directory";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../common/entities/AutoCompleteItem";
|
||||
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
||||
import {SearchResult} from "../../common/entities/SearchResult";
|
||||
import {Photo} from "../../common/entities/Photo";
|
||||
@ -70,8 +70,14 @@ export class GalleryMWs {
|
||||
if (!(req.params.text)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
ObjectManagerRepository.getInstance().getSearchManager().search(req.params.text, (err, result:SearchResult) => {
|
||||
|
||||
let type:SearchTypes;
|
||||
console.log()
|
||||
if (req.query.type) {
|
||||
type = parseInt(req.query.type);
|
||||
}
|
||||
|
||||
ObjectManagerRepository.getInstance().getSearchManager().search(req.params.text, type, (err, result:SearchResult) => {
|
||||
if (err || !result) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
||||
}
|
||||
@ -90,6 +96,7 @@ export class GalleryMWs {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
ObjectManagerRepository.getInstance().getSearchManager().instantSearch(req.params.text, (err, result:SearchResult) => {
|
||||
if (err || !result) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../common/entities/AutoCompleteItem";
|
||||
import {SearchResult} from "../../common/entities/SearchResult";
|
||||
export interface ISearchManager {
|
||||
autocomplete(text, cb:(error:any, result:Array<AutoCompleteItem>) => void);
|
||||
search(text, cb:(error:any, result:SearchResult) => void);
|
||||
instantSearch(text, cb:(error:any, result:SearchResult) => void);
|
||||
autocomplete(text:string, cb:(error:any, result:Array<AutoCompleteItem>) => void);
|
||||
search(text:string, searchType:SearchTypes, cb:(error:any, result:SearchResult) => void);
|
||||
instantSearch(text:string, cb:(error:any, result:SearchResult) => void);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import {AutoCompleteItem} from "../../../common/entities/AutoCompleteItem";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {ISearchManager} from "../ISearchManager";
|
||||
import {SearchResult} from "../../../common/entities/SearchResult";
|
||||
|
||||
@ -9,7 +9,7 @@ export class SearchManager implements ISearchManager {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
search(text, cb:(error:any, result:SearchResult) => void) {
|
||||
search(text, searchType:SearchTypes, cb:(error:any, result:SearchResult) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {AutoCompleteItem, AutoCompeleteTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {ISearchManager} from "../ISearchManager";
|
||||
import {DirectoryModel} from "./entities/DirectoryModel";
|
||||
import {PhotoModel} from "./entities/PhotoModel";
|
||||
@ -18,25 +18,25 @@ export class MongoSearchManager implements ISearchManager {
|
||||
promises.push(
|
||||
PhotoModel.find({name: {$regex: text, $options: "i"}})
|
||||
.limit(10).select('name').exec().then((res:Array<any>)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.image));
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), SearchTypes.image));
|
||||
}));
|
||||
|
||||
promises.push(
|
||||
PhotoModel.find({"metadata.positionData.city": {$regex: text, $options: "i"}})
|
||||
.limit(10).select('metadata.positionData.city').exec().then((res:Array<any>)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.city), AutoCompeleteTypes.position));
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.city), SearchTypes.position));
|
||||
}));
|
||||
|
||||
promises.push(
|
||||
PhotoModel.find({"metadata.positionData.state": {$regex: text, $options: "i"}})
|
||||
.limit(10).select('metadata.positionData.state').exec().then((res:Array<any>)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.state), AutoCompeleteTypes.position));
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.state), SearchTypes.position));
|
||||
}));
|
||||
|
||||
promises.push(
|
||||
PhotoModel.find({"metadata.positionData.country": {$regex: text, $options: "i"}})
|
||||
.limit(10).select('metadata.positionData.country').exec().then((res:Array<any>)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.country), AutoCompeleteTypes.position));
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.country), SearchTypes.position));
|
||||
}));
|
||||
|
||||
//TODO: fix caseinsensitivity
|
||||
@ -44,7 +44,7 @@ export class MongoSearchManager implements ISearchManager {
|
||||
PhotoModel.find({"metadata.keywords": {$regex: text, $options: "i"}})
|
||||
.limit(10).select('metadata.keywords').exec().then((res:Array<any>)=> {
|
||||
res.forEach((photo)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(photo.metadata.keywords.filter(k => k.indexOf(text) != -1), AutoCompeleteTypes.keyword));
|
||||
items = items.concat(this.encapsulateAutoComplete(photo.metadata.keywords.filter(k => k.indexOf(text) != -1), SearchTypes.keyword));
|
||||
});
|
||||
}));
|
||||
|
||||
@ -52,7 +52,7 @@ export class MongoSearchManager implements ISearchManager {
|
||||
DirectoryModel.find({
|
||||
name: {$regex: text, $options: "i"}
|
||||
}).limit(10).select('name').exec().then((res:Array<any>)=> {
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.directory));
|
||||
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), SearchTypes.directory));
|
||||
}));
|
||||
|
||||
|
||||
@ -66,39 +66,59 @@ export class MongoSearchManager implements ISearchManager {
|
||||
|
||||
}
|
||||
|
||||
search(text, cb:(error:any, result:SearchResult) => void) {
|
||||
console.log("instantSearch: " + text);
|
||||
search(text:string, searchType:SearchTypes, cb:(error:any, result:SearchResult) => void) {
|
||||
console.log("search: " + text + ", type:" + searchType);
|
||||
let result:SearchResult = new SearchResult();
|
||||
|
||||
let promises = [];
|
||||
let photoFilterOR = [];
|
||||
|
||||
result.searchText = text;
|
||||
PhotoModel.find({
|
||||
$or: [
|
||||
{name: {$regex: text, $options: "i"}},
|
||||
{"metadata.positionData.city": {$regex: text, $options: "i"}},
|
||||
{"metadata.positionData.state": {$regex: text, $options: "i"}},
|
||||
{"metadata.positionData.country": {$regex: text, $options: "i"}},
|
||||
{"metadata.keywords": {$regex: text, $options: "i"}}
|
||||
]
|
||||
result.searchType = searchType;
|
||||
|
||||
}).populate('directory', 'name path').exec((err, res:Array<any>) => {
|
||||
if (err || !res) {
|
||||
return cb(err, null);
|
||||
}
|
||||
result.photos = res;
|
||||
|
||||
DirectoryModel.find({
|
||||
if (!searchType || searchType === SearchTypes.image) {
|
||||
photoFilterOR.push({name: {$regex: text, $options: "i"}});
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.position) {
|
||||
photoFilterOR.push({"metadata.positionData.city": {$regex: text, $options: "i"}});
|
||||
photoFilterOR.push({"metadata.positionData.state": {$regex: text, $options: "i"}});
|
||||
photoFilterOR.push({"metadata.positionData.country": {$regex: text, $options: "i"}});
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.keyword) {
|
||||
photoFilterOR.push({"metadata.keywords": {$regex: text, $options: "i"}});
|
||||
}
|
||||
|
||||
let photoFilter = {};
|
||||
if (photoFilterOR.length == 1) {
|
||||
photoFilter = photoFilterOR[0];
|
||||
} else {
|
||||
photoFilter = {$or: photoFilterOR};
|
||||
}
|
||||
|
||||
if (!searchType || photoFilterOR.length > 0) {
|
||||
promises.push(PhotoModel.find(photoFilter).populate('directory', 'name path').exec().then((res:Array<any>) => {
|
||||
result.photos = res;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
if (!searchType || searchType === SearchTypes.directory) {
|
||||
promises.push(DirectoryModel.find({
|
||||
name: {
|
||||
$regex: text,
|
||||
$options: "i"
|
||||
}
|
||||
}).select('name').exec((err, res:Array<any>) => {
|
||||
if (err || !res) {
|
||||
return cb(err, null);
|
||||
}
|
||||
}).exec().then((res:Array<any>) => {
|
||||
result.directories = res;
|
||||
return cb(null, result);
|
||||
});
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
Promise.all(promises).then(()=> {
|
||||
return cb(null, result);
|
||||
}).catch((err)=> {
|
||||
console.error(err);
|
||||
return cb(err, null);
|
||||
});
|
||||
}
|
||||
|
||||
@ -138,7 +158,7 @@ export class MongoSearchManager implements ISearchManager {
|
||||
});
|
||||
}
|
||||
|
||||
private encapsulateAutoComplete(values:Array<string>, type:AutoCompeleteTypes) {
|
||||
private encapsulateAutoComplete(values:Array<string>, type:SearchTypes) {
|
||||
let res = [];
|
||||
values.forEach((value)=> {
|
||||
res.push(new AutoCompleteItem(value, type));
|
||||
|
@ -45,7 +45,7 @@ export class GalleryRouter {
|
||||
|
||||
private addSearch() {
|
||||
this.app.get("/api/gallery/search/:text",
|
||||
AuthenticationMWs.authenticate,
|
||||
// AuthenticationMWs.authenticate,
|
||||
GalleryMWs.search,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
@ -61,7 +61,7 @@ export class GalleryRouter {
|
||||
|
||||
private addAutoComplete() {
|
||||
this.app.get("/api/gallery/autocomplete/:text",
|
||||
// AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authenticate,
|
||||
GalleryMWs.autocomplete,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
|
@ -29,7 +29,7 @@ export class PublicRouter {
|
||||
res.render(_path.resolve(__dirname, './../../frontend/index.ejs'), res.tpl);
|
||||
};
|
||||
|
||||
this.app.get(['/', '/login', "/gallery*", "/admin"], renderIndex);
|
||||
this.app.get(['/', '/login', "/gallery*", "/admin", "/search*"], renderIndex);
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum AutoCompeleteTypes {
|
||||
export enum SearchTypes {
|
||||
image,
|
||||
directory,
|
||||
keyword,
|
||||
@ -6,7 +6,7 @@ export enum AutoCompeleteTypes {
|
||||
}
|
||||
|
||||
export class AutoCompleteItem {
|
||||
constructor(public text:string, public type:AutoCompeleteTypes) {
|
||||
constructor(public text:string, public type:SearchTypes) {
|
||||
}
|
||||
|
||||
equals(other:AutoCompleteItem) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Directory} from "./Directory";
|
||||
import {Photo} from "./Photo";
|
||||
import {SearchTypes} from "./AutoCompleteItem";
|
||||
export class SearchResult {
|
||||
|
||||
public searchText:string;
|
||||
public directories:Array<Directory>;
|
||||
public photos:Array<Photo>;
|
||||
|
||||
public searchText:string = "";
|
||||
public searchType:SearchTypes;
|
||||
public directories:Array<Directory> = [];
|
||||
public photos:Array<Photo> = [];
|
||||
}
|
@ -50,6 +50,11 @@ import {NetworkService} from "./model/network/network.service";
|
||||
name: 'Gallery',
|
||||
component: GalleryComponent
|
||||
},
|
||||
{
|
||||
path: '/search/:searchText',
|
||||
name: 'Search',
|
||||
component: GalleryComponent
|
||||
},
|
||||
])
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<gallery-lightbox #lightbox></gallery-lightbox>
|
||||
<app-frame>
|
||||
<div navbar>
|
||||
<gallery-search *ngIf="showSearchBar"></gallery-search>
|
||||
<gallery-search #search *ngIf="showSearchBar"></gallery-search>
|
||||
</div>
|
||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.directory">
|
||||
<gallery-directory *ngFor="let directory of _galleryService.content.directory.directories"
|
||||
@ -11,7 +11,16 @@
|
||||
|
||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.searchResult">
|
||||
<ol class="breadcrumb">
|
||||
<li class="active"> Searching for: <strong>{{_galleryService.content.searchResult.searchText}}</strong></li>
|
||||
<li class="active">
|
||||
Searching for:
|
||||
<span [ngSwitch]="_galleryService.content.searchResult.searchType">
|
||||
<span *ngSwitchWhen="0" class="glyphicon glyphicon-picture"></span>
|
||||
<span *ngSwitchWhen="1" class="glyphicon glyphicon-folder-open"></span>
|
||||
<span *ngSwitchWhen="2" class="glyphicon glyphicon-tag"></span>
|
||||
<span *ngSwitchWhen="3" class="glyphicon glyphicon-map-marker"></span>
|
||||
</span>
|
||||
<strong>{{_galleryService.content.searchResult.searchText}}</strong>
|
||||
</li>
|
||||
</ol>
|
||||
<div *ngFor="let directory of _galleryService.content.searchResult.directories">
|
||||
<gallery-directory *ngIf="directory" [directory]="directory"></gallery-directory>
|
||||
|
@ -1,6 +1,6 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import {Component, OnInit} from "@angular/core";
|
||||
import {Component, OnInit, ViewChild} from "@angular/core";
|
||||
import {AuthenticationService} from "../model/network/authentication.service.ts";
|
||||
import {Router, RouteParams} from "@angular/router-deprecated";
|
||||
import {GalleryService} from "./gallery.service";
|
||||
@ -10,6 +10,7 @@ import {FrameComponent} from "../frame/frame.component";
|
||||
import {GalleryLightboxComponent} from "./lightbox/lightbox.gallery.component";
|
||||
import {GallerySearchComponent} from "./search/search.gallery.component";
|
||||
import {Config} from "../config/Config";
|
||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
|
||||
@Component({
|
||||
selector: 'gallery',
|
||||
@ -23,9 +24,10 @@ import {Config} from "../config/Config";
|
||||
})
|
||||
export class GalleryComponent implements OnInit {
|
||||
|
||||
@ViewChild(GallerySearchComponent) search:GallerySearchComponent;
|
||||
|
||||
public showSearchBar:boolean = true;
|
||||
|
||||
|
||||
constructor(private _galleryService:GalleryService,
|
||||
private _params:RouteParams,
|
||||
private _authService:AuthenticationService,
|
||||
@ -40,12 +42,30 @@ export class GalleryComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
let directoryName = this._params.get('directory');
|
||||
console.log(this._params);
|
||||
console.log(directoryName);
|
||||
|
||||
let searchText = this._params.get('searchText');
|
||||
if (searchText && searchText != "") {
|
||||
console.log("searching");
|
||||
let typeString = this._params.get('type');
|
||||
|
||||
if (typeString && typeString != "") {
|
||||
console.log("with type");
|
||||
let type:SearchTypes = SearchTypes[typeString];
|
||||
this._galleryService.search(searchText, type);
|
||||
return;
|
||||
}
|
||||
|
||||
this._galleryService.search(searchText);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let directoryName = this._params.get('directory');
|
||||
directoryName = directoryName ? directoryName : "";
|
||||
|
||||
this._galleryService.getDirectory(directoryName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@ import {Message} from "../../../common/entities/Message";
|
||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||
import {Photo} from "../../../common/entities/Photo";
|
||||
import {Directory} from "../../../common/entities/Directory";
|
||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
|
||||
@Injectable()
|
||||
export class GalleryService {
|
||||
@ -33,12 +34,18 @@ export class GalleryService {
|
||||
}
|
||||
|
||||
//TODO: cache
|
||||
public search(text:string):Promise<Message<ContentWrapper>> {
|
||||
public search(text:string, type?:SearchTypes):Promise<Message<ContentWrapper>> {
|
||||
clearTimeout(this.searchId);
|
||||
if (text === null || text === '') {
|
||||
return Promise.resolve(new Message(null, null));
|
||||
}
|
||||
return this._networkService.getJson("/gallery/search/" + text).then(
|
||||
|
||||
let queryString = "/gallery/search/" + text;
|
||||
if (type) {
|
||||
queryString += "?type=" + type;
|
||||
}
|
||||
|
||||
return this._networkService.getJson(queryString).then(
|
||||
(message:Message<ContentWrapper>) => {
|
||||
if (!message.error && message.result) {
|
||||
this.content = message.result;
|
||||
|
@ -5,16 +5,16 @@
|
||||
|
||||
<div class="photo-position" *ngIf="gridPhoto.photo.metadata.positionData">
|
||||
<span class="glyphicon glyphicon-map-marker"></span>
|
||||
<a *ngIf="gridPhoto.photo.metadata.positionData.city || gridPhoto.photo.metadata.positionData.state || gridPhoto.photo.metadata.positionData.country">
|
||||
{{gridPhoto.photo.metadata.positionData.city || gridPhoto.photo.metadata.positionData.state ||
|
||||
gridPhoto.photo.metadata.positionData.country}}
|
||||
<a [routerLink]="['Search',{searchText: getPositionText(), type:SearchTypes[SearchTypes.position]}]"
|
||||
*ngIf="getPositionText()">
|
||||
{{getPositionText()}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="photo-keywords">
|
||||
<template ngFor let-keyword [ngForOf]="gridPhoto.photo.metadata.keywords" let-last="last">
|
||||
#<a>{{keyword}}</a>
|
||||
<a [routerLink]="['Search',{searchText: keyword, type: SearchTypes[SearchTypes.keyword]}]">#{{keyword}}</a>
|
||||
<template [ngIf]="!last">,</template>
|
||||
</template>
|
||||
|
||||
|
@ -3,11 +3,14 @@
|
||||
import {Component, Input, ElementRef, ViewChild} from "@angular/core";
|
||||
import {IRenderable, Dimension} from "../../../model/IRenderable";
|
||||
import {GridPhoto} from "../GridPhoto";
|
||||
import {SearchTypes} from "../../../../../common/entities/AutoCompleteItem";
|
||||
import {RouterLink} from "@angular/router-deprecated";
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-grid-photo',
|
||||
templateUrl: 'app/gallery/grid/photo/photo.grid.gallery.component.html',
|
||||
styleUrls: ['app/gallery/grid/photo/photo.grid.gallery.component.css'],
|
||||
directives: [RouterLink],
|
||||
})
|
||||
export class GalleryPhotoComponent implements IRenderable {
|
||||
@Input() gridPhoto:GridPhoto;
|
||||
@ -18,15 +21,25 @@ export class GalleryPhotoComponent implements IRenderable {
|
||||
height: 0,
|
||||
background: ""
|
||||
};
|
||||
SearchTypes:any = [];
|
||||
|
||||
constructor() {
|
||||
this.SearchTypes = SearchTypes;
|
||||
}
|
||||
|
||||
getPositionText():string {
|
||||
if (!this.gridPhoto) {
|
||||
return ""
|
||||
}
|
||||
return this.gridPhoto.photo.metadata.positionData.city ||
|
||||
this.gridPhoto.photo.metadata.positionData.state ||
|
||||
this.gridPhoto.photo.metadata.positionData.country;
|
||||
}
|
||||
|
||||
hover() {
|
||||
this.infoStyle.height = this.infoDiv.nativeElement.clientHeight;
|
||||
this.infoStyle.background = "rgba(0,0,0,0.8)";
|
||||
|
||||
|
||||
}
|
||||
|
||||
mouseOut() {
|
||||
@ -34,7 +47,7 @@ export class GalleryPhotoComponent implements IRenderable {
|
||||
this.infoStyle.background = "rgba(0,0,0,0.0)";
|
||||
|
||||
}
|
||||
|
||||
|
||||
public getDimension():Dimension {
|
||||
return new Dimension(this.imageRef.nativeElement.offsetTop,
|
||||
this.imageRef.nativeElement.offsetLeft,
|
||||
|
@ -6,8 +6,10 @@
|
||||
ngControl="search"
|
||||
name="srch-term" id="srch-term" autocomplete="off">
|
||||
|
||||
<div class="autocomplete-list" *ngIf="autoCompleteItems.length > 0">
|
||||
<div class="autocomplete-item" *ngFor="let item of autoCompleteItems" (mousedown)="search(item)">
|
||||
<div class="autocomplete-list" *ngIf="autoCompleteItems.length > 0"
|
||||
(mouseover)="setMouseOverAutoComplete(true)" (mouseout)="setMouseOverAutoComplete(false)">
|
||||
<div class="autocomplete-item" *ngFor="let item of autoCompleteItems">
|
||||
<a [routerLink]="['Search',{searchText: item.text, type: SearchTypes[item.type]}]">
|
||||
<span [ngSwitch]="item.type">
|
||||
<span *ngSwitchWhen="0" class="glyphicon glyphicon-picture"></span>
|
||||
<span *ngSwitchWhen="1" class="glyphicon glyphicon-folder-open"></span>
|
||||
@ -15,6 +17,7 @@
|
||||
<span *ngSwitchWhen="3" class="glyphicon glyphicon-map-marker"></span>
|
||||
</span>
|
||||
{{item.preText}}<strong>{{item.highLightText}}</strong>{{item.postText}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
import {Component} from "@angular/core";
|
||||
import {AutoCompleteService} from "./autocomplete.service";
|
||||
import {AutoCompleteItem, AutoCompeleteTypes} from "../../../../common/entities/AutoCompleteItem";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../../common/entities/AutoCompleteItem";
|
||||
import {RouteParams, RouterLink} from "@angular/router-deprecated";
|
||||
import {Message} from "../../../../common/entities/Message";
|
||||
import {GalleryService} from "../gallery.service";
|
||||
import {FORM_DIRECTIVES} from "@angular/common";
|
||||
@ -13,14 +14,22 @@ import {Config} from "../../config/Config";
|
||||
templateUrl: 'app/gallery/search/search.gallery.component.html',
|
||||
styleUrls: ['app/gallery/search/search.gallery.component.css'],
|
||||
providers: [AutoCompleteService],
|
||||
directives: [FORM_DIRECTIVES]
|
||||
directives: [FORM_DIRECTIVES, RouterLink]
|
||||
})
|
||||
export class GallerySearchComponent {
|
||||
|
||||
autoCompleteItems:Array<AutoCompleteRenderItem> = [];
|
||||
private searchText:string = "";
|
||||
|
||||
constructor(private _autoCompleteService:AutoCompleteService, private _galleryService:GalleryService) {
|
||||
SearchTypes:any = [];
|
||||
|
||||
constructor(private _autoCompleteService:AutoCompleteService, private _galleryService:GalleryService, private _params:RouteParams) {
|
||||
|
||||
this.SearchTypes = SearchTypes;
|
||||
let searchText = this._params.get('searchText');
|
||||
if (searchText && searchText != "") {
|
||||
this.searchText = searchText;
|
||||
}
|
||||
}
|
||||
|
||||
onSearchChange(event:KeyboardEvent) {
|
||||
@ -49,9 +58,16 @@ export class GallerySearchComponent {
|
||||
}
|
||||
|
||||
|
||||
mouseOverAutoComplete:boolean = false;
|
||||
|
||||
public setMouseOverAutoComplete(value) {
|
||||
this.mouseOverAutoComplete = value;
|
||||
}
|
||||
|
||||
public onFocusLost(event) {
|
||||
this.autoCompleteItems = [];
|
||||
if (this.mouseOverAutoComplete == false) {
|
||||
this.autoCompleteItems = [];
|
||||
}
|
||||
}
|
||||
|
||||
public onFocus(event) {
|
||||
@ -88,15 +104,19 @@ export class GallerySearchComponent {
|
||||
});
|
||||
}
|
||||
|
||||
public setSearchText(searchText:string) {
|
||||
this.searchText = searchText;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AutoCompleteRenderItem {
|
||||
public preText:string = "";
|
||||
public highLightText:string = "";
|
||||
public postText:string = "";
|
||||
public type:AutoCompeleteTypes;
|
||||
public type:SearchTypes;
|
||||
|
||||
constructor(public text:string, searchText:string, type:AutoCompeleteTypes) {
|
||||
constructor(public text:string, searchText:string, type:SearchTypes) {
|
||||
let preIndex = text.toLowerCase().indexOf(searchText.toLowerCase());
|
||||
if (preIndex > -1) {
|
||||
this.preText = text.substring(0, preIndex);
|
||||
|
@ -23,7 +23,7 @@ export class NetworkService {
|
||||
.toPromise()
|
||||
.then(res => <Message<any>> res.json())
|
||||
.catch(NetworkService.handleError);
|
||||
}
|
||||
}
|
||||
|
||||
return this._http[method](this._baseUrl + url, body, options)
|
||||
.toPromise()
|
||||
|
Loading…
Reference in New Issue
Block a user