diff --git a/config/sync/search_api.index.database.yml b/config/sync/search_api.index.database.yml index cbd01c1..2993d95 100644 --- a/config/sync/search_api.index.database.yml +++ b/config/sync/search_api.index.database.yml @@ -8,8 +8,8 @@ dependencies: - taxonomy - search_api config: - - field.storage.node.field_famille - field.storage.node.body + - field.storage.node.field_famille - field.storage.node.field_tags - field.storage.taxonomy_term.field_synonyms - field.storage.node.field_thesaurus @@ -52,6 +52,14 @@ field_settings: dependencies: config: - field.storage.node.field_famille + nid: + label: ID + datasource_id: 'entity:node' + property_path: nid + type: integer + dependencies: + module: + - node node_grants: label: 'Node access information' property_path: search_api_node_grants @@ -68,7 +76,7 @@ field_settings: config: - field.storage.node.body status: - label: null + label: status datasource_id: 'entity:node' property_path: status type: boolean @@ -101,6 +109,18 @@ field_settings: - field.storage.taxonomy_term.field_synonyms module: - taxonomy + tag_tid: + label: 'Tags » Taxonomy term » Term ID' + datasource_id: 'entity:node' + property_path: 'field_tags:entity:tid' + type: text + boost: !!float 13 + dependencies: + config: + - field.storage.node.field_tags + module: + - taxonomy + - taxonomy thesaurus_name: label: 'Thesaurus » Taxonomy term » Name' datasource_id: 'entity:node' @@ -125,6 +145,18 @@ field_settings: - field.storage.taxonomy_term.field_synonyms module: - taxonomy + thesaurus_tid: + label: 'Thesaurus » Taxonomy term » Term ID' + datasource_id: 'entity:node' + property_path: 'field_thesaurus:entity:tid' + type: text + boost: !!float 21 + dependencies: + config: + - field.storage.node.field_thesaurus + module: + - taxonomy + - taxonomy title: label: Title datasource_id: 'entity:node' @@ -135,7 +167,7 @@ field_settings: module: - node uid: - label: null + label: uid datasource_id: 'entity:node' property_path: uid type: integer @@ -185,8 +217,10 @@ processor_settings: - processed - tag_name - tag_synonyms + - tag_tid - thesaurus_name - thesaurus_synonyms + - thesaurus_tid - title title: true alt: true diff --git a/web/modules/custom/materio_sapi/materio_sapi.routing.yml b/web/modules/custom/materio_sapi/materio_sapi.routing.yml index cd43f9c..833bba3 100644 --- a/web/modules/custom/materio_sapi/materio_sapi.routing.yml +++ b/web/modules/custom/materio_sapi/materio_sapi.routing.yml @@ -21,3 +21,18 @@ materio_sapi.search_form: # _title: 'MaterioSapiSearchForm' # requirements: # _access: 'TRUE' + +materio_sapi.getresults: + path: '/materio_sapi/getresults' + defaults: + _controller: '\Drupal\materio_sapi\Controller\Base::getResults' + _format: json + requirements: + _permission: 'access materio search' + +# materio_sapi.base: +# path: '/base/{keys}/{autocomplete}' +# defaults: +# _controller: '\Drupal\materio_sapi\Controller\Base::base' +# requirements: +# _permission: 'access materio search' diff --git a/web/modules/custom/materio_sapi/src/Controller/Base.php b/web/modules/custom/materio_sapi/src/Controller/Base.php new file mode 100644 index 0000000..a37e27c --- /dev/null +++ b/web/modules/custom/materio_sapi/src/Controller/Base.php @@ -0,0 +1,97 @@ + 'ok', + 'autocomplete' => $request->query->get('autocomplete'), + 'keys' => $request->query->get('keys'), + 'range' => array( + 'offset' => $request->query->get('offset'), + 'limit' => $request->query->get('limit'), + ), + ]; + + // Get the typed string from the URL, if it exists. + if ($keys = $resp['keys']) { + $typed_string = Tags::explode($keys); + $typed_string = Unicode::strtolower($keys); + \Drupal::logger('materio_sapi')->notice($typed_string); + + $index = Index::load('database'); + $query = $index->query(); + + // Change the parse mode for the search. + $parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode') + ->createInstance('direct'); + $parse_mode->setConjunction('OR'); + $query->setParseMode($parse_mode); + + // Set fulltext search keywords and fields. + $query->keys($typed_string); + // $query->setFulltextFields(['name']); + + // Set additional conditions. + // $query->addCondition('status', 1) + // ->addCondition('author', 1, '<>'); + + // Restrict the search to specific languages. + // $query->setLanguages(['de', 'it']); + + // Do paging. + $query->range($resp['range']['offset'], $resp['range']['limit']); + + // Add sorting. + $query->sort('search_api_relevance', 'DESC'); + + // Set one or more tags for the query. + // @see hook_search_api_query_TAG_alter() + // @see hook_search_api_results_TAG_alter() + $query->addTag('materio_sapi_search'); + + $results = $query->execute(); + + $resultitems = $results->getResultItems(); + $resp['count'] = $results->getResultCount(); + $resp['resultitems'] = array_keys($resultitems); + $resp['options'] = $query->getOptions(); + + + $items = []; + foreach ($results as $result) { + // \Drupal::logger('materio_sapi')->notice(print_r($result->getField('tid')->getValues(),true)); + // \Drupal::logger('materio_sapi')->notice(print_r($result->getField('name')->getValues(),true)); + $nid = $result->getField('nid')->getValues()[0]; + $title = $result->getField('title')->getValues()[0]->getText(); + $items[] = [ + 'nid' => $nid, + 'title' => $title, + ]; + } + $resp['items'] = $items; + } + + return new JsonResponse($resp); + } + +} diff --git a/web/modules/custom/materio_sapi/src/Form/MaterioSapiSearchForm.php b/web/modules/custom/materio_sapi/src/Form/MaterioSapiSearchForm.php index dbc7c0e..01c9cf5 100644 --- a/web/modules/custom/materio_sapi/src/Form/MaterioSapiSearchForm.php +++ b/web/modules/custom/materio_sapi/src/Form/MaterioSapiSearchForm.php @@ -30,12 +30,19 @@ class MaterioSapiSearchForm extends FormBase { '#weight' => '0', '#attributes' => [ "placeholder" => $this->t('Search'), - "@keyup" => "keyup", + // "@keyup" => "keyup", "@keyup.enter" => "submit", - "v-model" => "typed" - + "v-model" => "keys", + // "v-on:select" => "typed", ], '#autocomplete_route_name' => 'materio_sapi.search_autocomplete', + + ]; + $form['searchautocomplete'] = [ + '#type' => 'hidden', + '#attributes' => [ + "v-model" => "autocomplete" + ], ]; $form['submit'] = [ '#type' => 'submit', diff --git a/web/themes/custom/materiotheme/assets/dist/main.js b/web/themes/custom/materiotheme/assets/dist/main.js index 3b99d38..e271e10 100644 --- a/web/themes/custom/materiotheme/assets/dist/main.js +++ b/web/themes/custom/materiotheme/assets/dist/main.js @@ -393,7 +393,7 @@ eval("\n\nvar bind = __webpack_require__(/*! ./helpers/bind */ \"./node_modules/ /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar _default = {\n props: ['title', 'block'],\n data: function data() {\n return {\n template: null,\n mail: '',\n password: ''\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)(['User'])),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n userLogin: 'User/userLogin'\n }), {\n login: function login() {\n this.userLogin({\n mail: this.mail,\n pass: this.password\n });\n },\n request_password: function request_password() {\n console.log('request_password');\n },\n create_account: function create_account() {\n console.log('create_account');\n }\n }),\n beforeMount: function beforeMount() {\n var _this = this;\n\n console.log('LoginBlock beforeMount', this._props.block);\n\n if (this._props.block) {\n // console.log('LoginBlock beforeMount if this._props.block ok');\n this.template = _vue.default.compile(this._props.block);\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n mounted: function mounted() {\n // console.log('LoginBlock mounted');\n Drupal.attachBehaviors(this.$el);\n },\n render: function render(h) {\n // console.log('LoginBlock render');\n if (!this.template) {\n // console.log('LoginBlock render NAN');\n return h('span', 'Loading ...');\n } else {\n // console.log('LoginBlock render template');\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar _default = {\n props: ['title', 'block'],\n data: function data() {\n return {\n template: null,\n mail: '',\n password: ''\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)(['User'])),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n userLogin: 'User/userLogin'\n }), {\n login: function login() {\n this.userLogin({\n mail: this.mail,\n pass: this.password\n });\n },\n request_password: function request_password() {\n console.log('request_password');\n },\n create_account: function create_account() {\n console.log('create_account');\n }\n }),\n beforeMount: function beforeMount() {\n var _this = this;\n\n // console.log('LoginBlock beforeMount', this._props.block);\n if (this._props.block) {\n // console.log('LoginBlock beforeMount if this._props.block ok');\n this.template = _vue.default.compile(this._props.block);\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n mounted: function mounted() {\n // console.log('LoginBlock mounted');\n Drupal.attachBehaviors(this.$el);\n },\n render: function render(h) {\n // console.log('LoginBlock render');\n if (!this.template) {\n // console.log('LoginBlock render NAN');\n return h('span', 'Loading ...');\n } else {\n // console.log('LoginBlock render template');\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); /***/ }), @@ -441,7 +441,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = {\n props: ['form'],\n data: function data() {\n return {\n template: null,\n typed: \"\"\n };\n },\n methods: {\n keyup: function keyup() {\n console.log(\"search typed\", this.typed);\n },\n submit: function submit() {\n console.log(\"search clicked\");\n }\n },\n beforeMount: function beforeMount() {\n var _this = this;\n\n // console.log('SearchForm beforeMount');\n if (this._props.form) {\n // console.log('SearchForm beforeMount if this._props.form ok');\n this.template = _vue.default.compile(this._props.form); // https://github.com/vuejs/vue/issues/9911\n\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n mounted: function mounted() {\n // console.log('SearchForm mounted');\n Drupal.attachBehaviors(this.$el);\n },\n render: function render(h) {\n // console.log('searchForm render');\n if (!this.template) {\n return h('span', 'Loading ...');\n } else {\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar _default = {\n props: ['form'],\n data: function data() {\n return {\n template: null // keys: \"\",\n // autocomplete: \"\"\n\n };\n },\n computed: {\n // ...mapState(['Search'])\n // ...mapState({\n // // keys: state => state.Search.keys,\n // autocomplete: state => state.Search.autocomplete\n // }),\n keys: {\n get: function get() {\n return this.$store.state.Search.keys;\n },\n set: function set(value) {\n this.$store.commit('Search/setKeys', value);\n }\n },\n autocomplete: {\n get: function get() {\n return this.$store.state.Search.autocomplete;\n },\n set: function set(value) {\n this.$store.commit('Search/setAutocomplete', value);\n }\n }\n },\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n getResults: 'Search/getResults'\n }), {\n submit: function submit() {\n console.log(\"search clicked\", this.keys, this.autocomplete);\n this.getResults();\n },\n onAutoCompleteSelect: function onAutoCompleteSelect(event, ui) {\n event.preventDefault(); // console.log('autoCompleteSelect', event, ui);\n\n this.keys = ui.item.label;\n this.autocomplete = ui.item.value;\n }\n }),\n beforeMount: function beforeMount() {\n var _this = this;\n\n // console.log('SearchForm beforeMount');\n if (this._props.form) {\n // console.log('SearchForm beforeMount if this._props.form ok');\n this.template = _vue.default.compile(this._props.form); // https://github.com/vuejs/vue/issues/9911\n\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n watch: {\n keys: function keys() {\n console.log('keys changed', this.keys);\n }\n },\n mounted: function mounted() {\n // console.log('SearchForm mounted');\n Drupal.attachBehaviors(this.$el); // Catch the jquery ui events for autocmplete widget\n\n jQuery(this.$el.querySelector('#edit-search')).on('autocompleteselect', this.onAutoCompleteSelect);\n },\n render: function render(h) {\n // console.log('searchForm render');\n if (!this.template) {\n return h('span', 'Loading ...');\n } else {\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); /***/ }), @@ -1005,7 +1005,19 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _nod /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _vuex = _interopRequireDefault(__webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\"));\n\nvar _user = _interopRequireDefault(__webpack_require__(/*! ./modules/user */ \"./web/themes/custom/materiotheme/vuejs/store/modules/user.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart\n_vue.default.use(_vuex.default);\n\nvar _default = new _vuex.default.Store({\n modules: {\n User: _user.default\n }\n});\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/store/index.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _vuex = _interopRequireDefault(__webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\"));\n\nvar _user = _interopRequireDefault(__webpack_require__(/*! ./modules/user */ \"./web/themes/custom/materiotheme/vuejs/store/modules/user.js\"));\n\nvar _search = _interopRequireDefault(__webpack_require__(/*! ./modules/search */ \"./web/themes/custom/materiotheme/vuejs/store/modules/search.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart\n_vue.default.use(_vuex.default);\n\nvar _default = new _vuex.default.Store({\n modules: {\n User: _user.default,\n Search: _search.default\n }\n});\n\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/store/index.js?"); + +/***/ }), + +/***/ "./web/themes/custom/materiotheme/vuejs/store/modules/search.js": +/*!**********************************************************************!*\ + !*** ./web/themes/custom/materiotheme/vuejs/store/modules/search.js ***! + \**********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _jsonAxios = __webpack_require__(/*! vuejs/api/json-axios */ \"./web/themes/custom/materiotheme/vuejs/api/json-axios.js\");\n\nvar _maAxios = __webpack_require__(/*! vuejs/api/ma-axios */ \"./web/themes/custom/materiotheme/vuejs/api/ma-axios.js\");\n\nvar _querystring = _interopRequireDefault(__webpack_require__(/*! querystring */ \"./node_modules/querystring-es3/index.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar _default = {\n namespaced: true,\n // initial state\n state: {\n keys: \"\",\n autocomplete: \"\",\n results: {}\n },\n // getters\n getters: {},\n // mutations\n mutations: {\n setResults: function setResults(state, data) {\n state.results = data.results;\n },\n setKeys: function setKeys(state, keys) {\n state.keys = keys;\n },\n setAutocomplete: function setAutocomplete(state, autocomplete) {\n state.autocomplete = autocomplete;\n }\n },\n // actions\n actions: {\n getResults: function getResults(_ref) {\n var dispatch = _ref.dispatch,\n commit = _ref.commit,\n state = _ref.state;\n var params = {\n keys: state.keys,\n autocomplete: state.autocomplete,\n offset: 0,\n limit: 25\n };\n console.log('Search getResults params', params);\n\n var q = _querystring.default.stringify(params);\n\n return _maAxios.MA.get(\"/materio_sapi/getresults?\" + q).then(function (_ref2) {\n var data = _ref2.data;\n console.log('search MA getresults data', data);\n commit('setResults', data);\n }).catch(function (error) {\n console.warn('Issue with getResults', error);\n Promise.reject(error);\n });\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/store/modules/search.js?"); /***/ }), diff --git a/web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue b/web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue index 5b1194f..c0254f6 100644 --- a/web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue +++ b/web/themes/custom/materiotheme/vuejs/components/Block/LoginBlock.vue @@ -33,7 +33,7 @@ export default { } }, beforeMount() { - console.log('LoginBlock beforeMount', this._props.block); + // console.log('LoginBlock beforeMount', this._props.block); if(this._props.block){ // console.log('LoginBlock beforeMount if this._props.block ok'); this.template = Vue.compile(this._props.block) diff --git a/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue b/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue index 3738ec0..09ccbf6 100644 --- a/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue +++ b/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue @@ -2,20 +2,54 @@ import Vue from 'vue' +import { mapState, mapActions } from 'vuex' + export default { props: ['form'], data() { return { - template: null, - typed: "" + template: null + // keys: "", + // autocomplete: "" } }, - methods: { - keyup() { - console.log("search typed", this.typed); + computed: { + // ...mapState(['Search']) + // ...mapState({ + // // keys: state => state.Search.keys, + // autocomplete: state => state.Search.autocomplete + // }), + keys: { + get(){ + return this.$store.state.Search.keys + }, + set(value){ + this.$store.commit('Search/setKeys', value) + } }, + autocomplete: { + get(){ + return this.$store.state.Search.autocomplete + }, + set(value){ + this.$store.commit('Search/setAutocomplete', value) + } + } + + }, + methods: { + ...mapActions({ + getResults: 'Search/getResults' + }), submit() { - console.log("search clicked"); + console.log("search clicked", this.keys, this.autocomplete); + this.getResults(); + }, + onAutoCompleteSelect(event, ui){ + event.preventDefault(); + // console.log('autoCompleteSelect', event, ui); + this.keys = ui.item.label + this.autocomplete = ui.item.value } }, beforeMount() { @@ -29,9 +63,16 @@ export default { this.template.staticRenderFns.map(fn => (this.$options.staticRenderFns.push(fn))); } }, + watch: { + keys(){ + console.log('keys changed', this.keys); + } + }, mounted(){ // console.log('SearchForm mounted'); Drupal.attachBehaviors(this.$el); + // Catch the jquery ui events for autocmplete widget + jQuery(this.$el.querySelector('#edit-search')).on('autocompleteselect', this.onAutoCompleteSelect); }, render(h) { // console.log('searchForm render'); diff --git a/web/themes/custom/materiotheme/vuejs/store/index.js b/web/themes/custom/materiotheme/vuejs/store/index.js index ee6803d..29c190e 100644 --- a/web/themes/custom/materiotheme/vuejs/store/index.js +++ b/web/themes/custom/materiotheme/vuejs/store/index.js @@ -1,12 +1,14 @@ import Vue from 'vue' import Vuex from 'vuex' import User from './modules/user' +import Search from './modules/search' // https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart Vue.use(Vuex) export default new Vuex.Store({ modules: { - User + User, + Search } }) diff --git a/web/themes/custom/materiotheme/vuejs/store/modules/search.js b/web/themes/custom/materiotheme/vuejs/store/modules/search.js new file mode 100644 index 0000000..1ee6ec8 --- /dev/null +++ b/web/themes/custom/materiotheme/vuejs/store/modules/search.js @@ -0,0 +1,53 @@ +import { JSONAPI } from 'vuejs/api/json-axios' +import { MA } from 'vuejs/api/ma-axios' +import qs from 'querystring' + +export default { + namespaced: true, + + // initial state + state : { + keys: "", + autocomplete: "", + results: {} + }, + + // getters + getters : {}, + + // mutations + mutations : { + setResults (state, data) { + state.results = data.results + }, + setKeys (state, keys) { + state.keys = keys + }, + setAutocomplete (state, autocomplete) { + state.autocomplete = autocomplete + } + }, + + // actions + actions : { + getResults ({ dispatch, commit, state }) { + let params = { + keys: state.keys, + autocomplete: state.autocomplete, + offset:0, + limit: 25 + } + console.log('Search getResults params', params); + let q = qs.stringify(params) + return MA.get(`/materio_sapi/getresults?`+q) + .then(({ data }) => { + console.log('search MA getresults data', data) + commit('setResults', data) + }) + .catch(( error ) => { + console.warn('Issue with getResults', error) + Promise.reject(error) + }) + } + } +}