Search.vue 3.52 KB
Newer Older
Markus Opolka's avatar
Markus Opolka committed
1
<template>
Markus Opolka's avatar
Markus Opolka committed
2
3
4
5
6
<v-container grid-list-md>
  <v-layout row wrap>
    <v-flex xs12>
      <h3>{{header}}</h3>
    </v-flex>
Markus Opolka's avatar
Markus Opolka committed
7

8
9
10
11
    <v-flex xs12>
      <p>With the search you can search for regular expressions with in all tags and corresponding contents.</p>
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
12
    <!-- Search Help -->
Markus Opolka's avatar
Markus Opolka committed
13
14
15
16
17
18
19
    <v-flex xs12>
      <v-expansion-panel>
        <v-expansion-panel-content>
          <div slot="header">Toggle Syntax Help</div>
          <v-card>
            <v-card-text class="grey lighten-3">
              <p>Content in an element: <strong>element:content</strong> (Regular Expressions are supported)</p>
20
21
22
              <p>If no element is provided, the text will be searched.</p>
              <!-- <p>Attribute of an element: <strong>element@attribute=value</strong></p> -->
              <!-- <p>Attribute and content: <strong>element@attribute=value:content</strong></p> -->
Markus Opolka's avatar
Markus Opolka committed
23
24
25
26
27
28
            </v-card-text>
          </v-card>
        </v-expansion-panel-content>
      </v-expansion-panel>
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
29
    <!-- Main Input Field -->
30
    <v-flex xs12 md9>
Markus Opolka's avatar
Markus Opolka committed
31
32
33
34
35
36
37
      <v-text-field
        v-model="search"
        label="Query"
        data-vv-search="search"
        required
        @keyup.enter.native="validate"
        ></v-text-field>
38
39
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
40
    <!-- Search Buttons -->
41
42
43
44
45
    <v-flex xs12 md3>
      <v-btn @click="validate" color="blue-grey darken-2" class="white--text">Search</v-btn>
      <v-btn @click="clear" color="blue-grey darken-2" class="white--text">Clear</v-btn>
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
46
47
48
49
    <!-- Options -->
    <v-flex xs9>
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
50
    <!-- Invalid Search Warning -->
51
52
    <v-flex xs12>
      <v-alert outline color="lime darken-2" icon="warning" :value="invalid">
Markus Opolka's avatar
Markus Opolka committed
53
54
55
56
57
58
        Invalid Search Query
      </v-alert>
    </v-flex>

    <!-- Progress Bar -->
    <v-flex xs12 v-if="searching">
59
      <v-progress-linear indeterminate color="primary"></v-progress-linear>
Markus Opolka's avatar
Markus Opolka committed
60
61
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
62
    <!-- Search Results Meta -->
63
64
65
    <v-flex xs12 v-if="results">
      <v-card color="blue-grey lighten-1" class="white--text">
        <v-card-text>
66
          Results: {{results.length}} letter(s)
67
68
69
70
        </v-card-text>
      </v-card>
    </v-flex>

Markus Opolka's avatar
Markus Opolka committed
71
    <!-- Search Results -->
Markus Opolka's avatar
Markus Opolka committed
72
    <v-flex xs12 v-if="results">
73
        <result :letter="letter" v-for="letter in results" v-bind:key="letter.url" />
Markus Opolka's avatar
Markus Opolka committed
74
    </v-flex>
Markus Opolka's avatar
Markus Opolka committed
75

Markus Opolka's avatar
Markus Opolka committed
76
  </v-layout>
Markus Opolka's avatar
Markus Opolka committed
77
78
79
80
 </v-container>
</template>

<script>
Markus Opolka's avatar
Markus Opolka committed
81
export default {
Markus Opolka's avatar
Markus Opolka committed
82
  // General Search Component
Markus Opolka's avatar
Markus Opolka committed
83
84
85
86
87
88
  name: 'Search',
  data () {
    return {
      header: 'Search',
      invalid: false,
      search: '',
89
      pattern: '^([a-z]+):(.+)',
Markus Opolka's avatar
Markus Opolka committed
90
      results: null,
Markus Opolka's avatar
Markus Opolka committed
91
      searching: false,
92
      cutoff: 100,
Markus Opolka's avatar
Markus Opolka committed
93
      showlabels: false
Markus Opolka's avatar
Markus Opolka committed
94
95
96
    }
  },
  methods: {
97
98
    find (params) {
      // Call search API
Markus Opolka's avatar
Markus Opolka committed
99
100
101
102
103
104
      // Remove undefined values
      Object.keys(params).forEach((key) => (params[key] == null) && delete params[key])
      this.searching = true
      this.$http.get('http://localhost:3000/api/search/', {params: params}).then(function (data) {
        this.results = data.body
        this.searching = false
Markus Opolka's avatar
Markus Opolka committed
105
      })
Markus Opolka's avatar
Markus Opolka committed
106
    },
Markus Opolka's avatar
Markus Opolka committed
107
    validate () {
Markus Opolka's avatar
Markus Opolka committed
108
      // Validate input field
109
      let search = this.search.split(':')
Markus Opolka's avatar
Markus Opolka committed
110

111
112
113
114
115
116
117
118
119
120
121
      // If no element is entered we search the text <l>
      if (typeof search[1] === 'undefined') {
        search.unshift('l')
      }

      let params = {
        element: search[0],
        content: search[1]
      }

      if (!params.content) {
Markus Opolka's avatar
Markus Opolka committed
122
        this.invalid = true
123
124
125
      } else {
        this.invalid = false
        this.find(params)
Markus Opolka's avatar
Markus Opolka committed
126
      }
Markus Opolka's avatar
Markus Opolka committed
127
128
    },
    clear () {
Markus Opolka's avatar
Markus Opolka committed
129
      // Clear input field
Markus Opolka's avatar
Markus Opolka committed
130
131
      this.invalid = false
      this.search = ''
Markus Opolka's avatar
Markus Opolka committed
132
133
    }
  }
Markus Opolka's avatar
Markus Opolka committed
134
}
Markus Opolka's avatar
Markus Opolka committed
135
</script>