diff --git a/client/src/app.js b/client/src/app.js
index 786df7e..24d67f0 100644
--- a/client/src/app.js
+++ b/client/src/app.js
@@ -6,6 +6,7 @@ import "./shared/rich-text-editor.js";
import "./shared/form-navigation.js";
import "./shared/image-popup.js";
import "./shared/facebook-button.js";
+import "./shared/search-input.js";
import "./shared/nav/ow-nav.js";
import "./shared/nav/ow-path.js";
import "./shared/price/price-input.js";
diff --git a/client/src/local-businesses/local-businesses.js b/client/src/local-businesses/local-businesses.js
index 647fba8..f3a08be 100644
--- a/client/src/local-businesses/local-businesses.js
+++ b/client/src/local-businesses/local-businesses.js
@@ -1,16 +1,13 @@
-import { Component } from "../shared";
+import { Component } from "../shared.js";
+import "../shared/search-input.js";
customElements.define('local-business-list', class extends Component {
- static get observedAttributes() {
- return ['filter']
- }
-
constructor() {
super(`
`);
- {
- const filter = this.shadowRoot.querySelector('#filter');
- let t = null;
- filter.addEventListener('change', ev => {
- ev.stopPropagation();
- this.filter = ev.target.value;
- });
- filter.addEventListener('keyup', ev => {
- ev.stopPropagation();
- const value = ev.target.value;
-
- if (t) clearTimeout(t);
- t = setTimeout(() => {
- this.filter = value;
- t = null;
- }, 1000 / 3);
- });
- }
- }
-
- connectedCallback() {
- this.filter = this.getAttribute('filter');
- }
-
- attributeChangedCallback(name, oldV, newV) {
- super.attributeChangedCallback(name, oldV, newV);
- }
-
- get filter() {
- return this.getAttribute('filter');
- }
-
- set filter(value) {
- if (!value || value === '') {
- this.removeAttribute('filter');
- for (const el of this.querySelectorAll('local-business')) {
- el.removeAttribute('local-business-visible');
- }
- } else {
- this.setAttribute('filter', value);
- value = value.split(' ').filter(s => s && s.length).map(s => `(${s})`).join('|');
- const businesses = this.querySelectorAll('local-business');
- for (const el of businesses) {
- if (el.matches(new RegExp(value, 'ig'))) {
- el.setAttribute('local-business-visible', 'visible');
- } else {
- el.setAttribute('local-business-visible', 'invisible');
- }
- }
- }
}
});
diff --git a/client/src/marketplace/marketplace-offers.js b/client/src/marketplace/marketplace-offers.js
index 382345f..7de4704 100644
--- a/client/src/marketplace/marketplace-offers.js
+++ b/client/src/marketplace/marketplace-offers.js
@@ -1,4 +1,5 @@
-import { Component, BUTTON_STYLE } from "../shared";
+import { Component, BUTTON_STYLE } from "../shared.js";
+import "../shared/search-input.js";
customElements.define('marketplace-offers', class extends Component {
static get observedAttributes() {
@@ -28,6 +29,9 @@ customElements.define('marketplace-offers', class extends Component {
::slotted(marketplace-offer), ::slotted(user-edit-offer) {
margin-bottom: 20px;
}
+ ::slotted([search-visible='invisible']) {
+ display: none;
+ }
@media only screen and (min-device-width: 1000px) {
#offers {
display: flex;
@@ -47,6 +51,9 @@ customElements.define('marketplace-offers', class extends Component {
+
diff --git a/client/src/marketplace/user-edit-offer.js b/client/src/marketplace/user-edit-offer.js
index c1d818e..ac0f651 100644
--- a/client/src/marketplace/user-edit-offer.js
+++ b/client/src/marketplace/user-edit-offer.js
@@ -147,4 +147,8 @@ customElements.define('user-edit-offer', class extends Component {
}
}
}
+
+ matches(regex) {
+ return !!this.description.match(regex)
+ }
});
diff --git a/client/src/shared/search-input.js b/client/src/shared/search-input.js
new file mode 100644
index 0000000..bafb17c
--- /dev/null
+++ b/client/src/shared/search-input.js
@@ -0,0 +1,101 @@
+import { Component } from "../shared.js";
+
+customElements.define('search-input', class extends Component {
+ #host;
+
+ static get observedAttributes() {
+ return ['filter', 'target']
+ }
+
+ constructor() {
+ super(`
+
+
+ `);
+ const filter = this.shadowRoot.querySelector('#filter');
+ let t = null;
+ filter.addEventListener('change', ev => {
+ ev.stopPropagation();
+ this.filter = ev.target.value;
+ });
+ filter.addEventListener('keyup', ev => {
+ ev.stopPropagation();
+ const value = ev.target.value;
+
+ if (t) clearTimeout(t);
+ t = setTimeout(() => {
+ this.filter = value;
+ t = null;
+ }, 1000 / 3);
+ });
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ let node = this;
+ while (node) {
+ console.warn(node)
+ if (node == null) return console.warn('no parent node', node);
+ if (node instanceof ShadowRoot) {
+ console.warn('node is shadow')
+ this.#host = node.host;
+ break;
+ }
+ node = node.parentNode;
+ }
+ }
+
+ get target() {
+ return this.getAttribute('target');
+ }
+
+ set target(tagName) {
+ this.setAttribute('target', tagName);
+ }
+
+ get filter() {
+ return this.getAttribute('filter');
+ }
+
+ set filter(value) {
+ console.warn(this.#host, value);
+ if (!this.#host) return;
+ const v = this.#host.querySelectorAll(this.target);
+
+ if (!value || value === '') {
+ this.removeAttribute('filter');
+ for (const el of v) {
+ el.removeAttribute('search-visible');
+ }
+ } else {
+ this.setAttribute('filter', value);
+ value = value.split(' ').filter(s => s && s.length).map(s => `(${ s })`).join('|');
+ for (const el of v) {
+ if (!el.matches) continue;
+ if (el.matches(new RegExp(value, 'ig'))) {
+ el.setAttribute('search-visible', 'visible');
+ } else {
+ el.setAttribute('search-visible', 'invisible');
+ }
+ }
+ }
+ }
+});