Преглед на файлове

#1906 serach form autocmplete multi terms

bach преди 1 година
родител
ревизия
d1b4902aa3

+ 13 - 6
web/modules/custom/materio_sapi/src/Controller/Base.php

@@ -57,11 +57,14 @@ class Base extends ControllerBase {
     }
     
     // in case of term id provided restrict the keys to taxo fields
-    if ($this->term) {
+    if ($this->terms && count($this->terms)) {
       $term_conditions = $this->and_query->createConditionGroup('OR');
-      $term = (int) $this->term;
-      foreach (['tag_tid', 'thesaurus_tid'] as $field) {
-        $term_conditions->addCondition($field, $term);
+      // $term = (int) $this->term;
+      foreach ($this->terms as $term) {
+        $tid = $term->value;
+        foreach (['tag_tid', 'thesaurus_tid'] as $field) {
+          $term_conditions->addCondition($field, (int) $tid);
+        }
       }
       $this->and_query->addConditionGroup($term_conditions);
 
@@ -265,7 +268,11 @@ class Base extends ControllerBase {
       \Drupal::logger('materio_sapi')->notice($this->keys);
     }
     // get the exacte term id in case of autocomplete
-    $this->term = $request->query->get('term');
+    // $this->terms = $request->query->get('terms');
+    $t = $request->query->get('terms');
+    // $this->terms = strlen($t) ? explode(',', $t) : null;
+    $this->terms = strlen($t) ? json_decode($t) : null;
+
     // get the filters of advanced search
     $f = $request->query->get('filters');
     $this->filters = strlen($f) ? explode(',', $f) : null;
@@ -295,7 +302,7 @@ class Base extends ControllerBase {
       $this->sapiQuery();
 
       $resp['keys'] = $this->keys;
-      $resp['term'] = $this->term;
+      $resp['terms'] = json_encode($this->terms);
       $resp['filters'] = $this->filters;
       // $resp['count'] = $this->results->getResultCount();
       $resp['count'] = count($this->results['nids']);

+ 4 - 4
web/modules/custom/materio_sapi/src/Controller/FormAutocomplete.php

@@ -23,10 +23,9 @@ class FormAutocomplete extends ControllerBase {
   public function autocomplete(Request $request) {
     // Get the typed string from the URL, if it exists.
     if ($input = $request->query->get('q')) {
-      $typed_string = Tags::explode($input);
-      // $typed_string = Unicode::strtolower(array_pop($typed_string));
-      $typed_string = mb_strtolower(array_pop($typed_string));
-      // \Drupal::logger('materio_sapi')->notice($typed_string);
+      $tag_list = Tags::explode($input); // does not work with space separated words
+      // $tag_list = explode(" ", $input);
+      $typed_string = !empty($tag_list) ? mb_strtolower(array_pop($tag_list)) : '';
 
       $index = Index::load('autocomplete');
       $query = $index->query();
@@ -74,6 +73,7 @@ class FormAutocomplete extends ControllerBase {
         $tid = $result->getField('tid')->getValues()[0];
         $term_name = $result->getField('name')->getValues()[0]->getText();
         $response[] = [
+          // 'typed_string' => $typed_string,
           'value' => $tid,
           'label' => $term_name,
         ];

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
web/themes/custom/materiotheme/assets/dist/main.js


BIN
web/themes/custom/materiotheme/assets/dist/main.js.gz


BIN
web/themes/custom/materiotheme/assets/dist/module-base.7a080824c1dd865ba888.bundle.js.gz


Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
web/themes/custom/materiotheme/assets/dist/module-base.cfc12ce577588cf8823e.bundle.js


BIN
web/themes/custom/materiotheme/assets/dist/module-base.cfc12ce577588cf8823e.bundle.js.gz


+ 2 - 2
web/themes/custom/materiotheme/vuejs/components/Block/SearchBlock.vue

@@ -24,7 +24,7 @@ export default {
     ...mapState({
       canSearch: state => state.User.canSearch,
       keys: state => state.Search.keys,
-      term: state => state.Search.term,
+      terms: state => state.Search.terms,
       filters: state => state.Search.filters
     }),
     displayform(){
@@ -54,7 +54,7 @@ export default {
       // var urlParamsKeys = urlParams.keys() 
       const params = {
         keys: this.keys,
-        term: this.term,
+        terms: this.terms, //JSON.stringify(this.terms),
         filters: this.filters
       }
       console.log('Search getSearchForm params', params)

+ 58 - 28
web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue

@@ -15,7 +15,7 @@ export default {
     return {
       template: null,
       typed: null,
-      autocomplete: null,
+      autocomplete: [],
       slimFilters: [],
       $input: null
       // basePath: drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix
@@ -24,7 +24,7 @@ export default {
   computed: {
     ...mapState({
       keys: state => state.Search.keys,
-      term: state => state.Search.term,
+      terms: state => state.Search.terms,
       filters: state => state.Search.filters
     })
   },
@@ -51,26 +51,44 @@ export default {
       // push router
       this.$router.push({name:'base', query:{
         keys:this.typed,
-        term:this.autocomplete,
+        // terms:this.autocomplete.join(','),
+        terms: JSON.stringify(this.autocomplete),
         filters:filters.join(',')
       }})
-      // this.$router.push({
-      //   path:`${this.basePath}/base`,
-      //   query:{keys:this.typed,term:this.autocomplete}
-      // })
     },
     onAutoCompleteSelect(event, ui){
       event.preventDefault();
-      console.log('autoCompleteSelect', event, ui)
-      this.typed = ui.item.label
-      // we have to wait for typed watch to reset autocomplete before setting it
-      setTimeout(function(){
-        console.log('update autocomplete value after settimeout')
-        this.autocomplete = ui.item.value
-        if (this.typed !== this.keys || this.autocomplete !== this.term) {
-          this.submit()
+      console.log('autoCompleteSelect begining', this.typed, event, ui)
+      // split typed into tag list
+      var tag_list = this.typed.split(', ')
+      console.log('tag_list', tag_list)
+      // remove the last item as it is the first letters of autocomplete (like ma for marbre)
+      tag_list.pop()
+      // add in typed the label
+      tag_list.push(ui.item.label)
+
+      this.typed = tag_list.join(', ') + ', '
+
+      // check if item is not already in autocmplete 
+      let add = true
+      this.autocomplete.forEach( (term)  => {
+        if (term.value == ui.item.value) {
+          add = false
+          return
         }
-      }.bind(this), 1)
+      })
+      if (add) {
+        this.autocomplete.push(ui.item)
+      }
+      // we have to wait for typed watch to reset autocomplete before setting it
+      // setTimeout(function(){
+        // console.log('update autocomplete value after settimeout')
+        // this.autocomplete.push(ui.item)
+        // if (this.typed !== this.keys || this.autocomplete !== this.term) {
+        //   this.submit()
+        // }
+      // }.bind(this), 1)
+     console.log('autoCompleteSelect end : this.autocomplete', this.autocomplete) 
 
     },
     onSelectFiltersChange(index, info){
@@ -105,22 +123,34 @@ export default {
   },
   watch: {
     typed(n, o){
-      console.log('typed changed', o, n)
-      // is changed also when autocomplete change it ...
-      this.autocomplete = null
-    },
-    keys(n, o){
-      console.log('keys changed', o, n)
-      this.typed = n
-    },
-    term(n, o){
-      console.log('autocomplete changed', o, n)
-      this.autocomplete = n
+      console.log('watch typed changed o:' + o + ' n:' +n)
+      // todo remove terms from autocomplete if removed from typed
+      const r = /,\s?$/
+      let tag_list = n.replace(r,'').split(', ')
+      console.log('watch typed tag_list', tag_list)
+      console.log('watch typed autocomplete before', this.autocomplete)
+      this.autocomplete.forEach( (term,index,array)  => {
+        console.log("watch typed autocomplete term", term, index, array)
+        if (tag_list.indexOf(term.label) < 0) {
+          this.autocomplete.splice(index,1)
+        }
+      });
+      console.log('watch typed autocomplete after', this.autocomplete)
     }
+    // keys(n, o){
+    //   console.log('watch keys changed', o, n)
+    //   this.typed = n
+    // },
+    // terms(n, o){
+    //   // if term change from store
+    //   console.log('watch terms changed', o, n)
+    //   this.autocomplete = n
+    // }
   },
   created() {
+    // fill component values with store values in case of direct page loading
     this.typed = this.keys
-    this.autocomplete = this.term
+    this.autocomplete = this.terms
   },
   mounted(){
     // console.log('SearchForm mounted')

+ 6 - 4
web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue

@@ -73,10 +73,12 @@ export default {
       this.pagetitle = 'Base'
     }
 
-    if (params.has('term')) {
-      this.$store.commit('Search/setTerm', params.get('term'))
+    if (params.has('terms')) {
+      console.log('Base created, has terms', params.get('terms'))
+      // this.$store.commit('Search/setTerms', params.get('terms').split(','))
+      this.$store.commit('Search/setTerms', JSON.parse(params.get('terms')))
     } else {
-      this.$store.commit('Search/setTerm', '')
+      this.$store.commit('Search/setTerms', [])
     }
 
     if (params.has('filters')) {
@@ -91,7 +93,7 @@ export default {
     // when query change launch a new search
     console.log('Base beforeRouteUpdate', to, from, next)
     this.$store.commit('Search/setKeys', to.query.keys)
-    this.$store.commit('Search/setTerm', to.query.term)
+    this.$store.commit('Search/setTerms', to.query.terms)
     this.$store.commit('Search/setFilters', to.query.filters)
     this.pagetitle = to.query.keys
     this.newSearch()

+ 8 - 6
web/themes/custom/materiotheme/vuejs/store/modules/search.js

@@ -16,7 +16,7 @@ export default {
   // initial state
   state: {
     keys: '',
-    term: '',
+    terms: [],
     filters: [],
     uuids: [],
     items: [],
@@ -64,8 +64,9 @@ export default {
     setKeys (state, keys) {
       state.keys = keys
     },
-    setTerm (state, term) {
-      state.term = term
+    setTerms (state, terms) {
+      state.terms = terms
+      console.log('search store setTerms', terms)
     },
     setFilters (state, filters) {
       console.log('store search setFilters', filters)
@@ -110,7 +111,7 @@ export default {
       commit('resetNoresults')
       commit('resetOffset')
       commit('resetInfos')
-      if (state.keys || state.term) {
+      if (state.keys || state.terms) {
         this.commit('Common/setPagetitle', state.keys)
       } else {
         this.commit('Common/setPagetitle', 'Base')
@@ -126,10 +127,11 @@ export default {
     getResults ({ dispatch, commit, state }) {
       const params = {
         keys: state.keys,
-        term: state.term,
+        terms: JSON.stringify(state.terms),
         offset: state.offset,
         limit: state.limit
       }
+      console.log('search store getResults, params', params)
       if (state.filters) {
         console.log('getResults filters', state.filters)
         params.filters = state.filters.join(',')
@@ -138,7 +140,7 @@ export default {
       const q = qs.stringify(params)
       return MA.get('/materio_sapi/getresults?' + q)
         .then(({ data }) => {
-          console.log('search MA getresults data', data)
+          console.log('search MA getresults data', data, state.terms)
           // commit('setItems', data.items)
           commit('setInfos', data.infos)
           commit('setCount', data.count)

Някои файлове не бяха показани, защото твърде много файлове са промени