Last active
February 18, 2020 15:03
-
-
Save panoply/05da67ac0fba758eccfe83408110c99e to your computer and use it in GitHub Desktop.
Shopify Search Filter using Mithril
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Modules */ | |
import m from 'mithril' | |
import url from 'urljs' | |
export default () => { | |
const products = document.querySelector('#product-collection') | |
const results = document.querySelector('#search-collection') | |
const items = data => { | |
return [ | |
m('.row.justify-content-start.align-content-center.p-2', [ | |
data.map(item => { | |
return [ | |
m('.col-6.col-sm-4.col-md-4.col-lg-4.col-xl-3.p-2', [ | |
m('.product', [ | |
m('.product__item', [ | |
item.quantity < 4 && item.quantity !== 0 && [ | |
m('.badge.limited-stock.d-block', `${item.quantity} IN STOCK`) | |
], | |
item.sale && m('.badge.sale', item.sale), | |
m(`a[href="${item.url}"][data-turbolinks-preload="true"]`, [ | |
m('picture', [ | |
m(`source[media="(min-width: 540px)"][srcset="${item.image}"]`), | |
m(`img.img-fluid[src="${item.image}"]`) | |
]), | |
m('.product__info.d-flex.justify-content-between.px-0.px-md-3', [ | |
m('.align-self-center.d-block', [ | |
m('.title.d-block', `${item.title}`), | |
item.color && m('.color.d-block.pt-1', `${item.color}`) | |
]), | |
m('.price.align-self-center', [ | |
m('span.d-block', m.trust(item.price)), | |
item.compare && m('span.old.d-block', m.trust(item.compare)) | |
]) | |
]) | |
]) | |
]) | |
]) | |
]) | |
] | |
}) | |
]) | |
] | |
} | |
const visible = char => { | |
if (char < 2) { | |
url.updateSearchParam('search') | |
!results.classList.contains('d-none') && results.classList.add('d-none') | |
products.classList.contains('d-none') && products.classList.remove('d-none') | |
} else { | |
url.updateSearchParam('search', `${state.value}`) | |
results.classList.contains('d-none') && results.classList.remove('d-none') | |
!products.classList.contains('d-none') && products.classList.add('d-none') | |
} | |
} | |
const state = { | |
gender: window.location.pathname.split('/').slice(1)[1], | |
data: [], | |
value: '', | |
setValue (v) { | |
state.value = v | |
setTimeout(() => { | |
return m.request({ | |
url: `/search?type=product&q=${state.gender}%20${state.value}*&view=json`, | |
background: true | |
}).then(data => { | |
m.render(results, items(data.results)) | |
}).then(() => { | |
visible(state.value.length) | |
}) | |
}, 250) | |
} | |
} | |
const Input = { | |
oninit () { | |
if (url.queryString('search')) { | |
state.value = url.queryString('search') | |
state.setValue(state.value) | |
} | |
}, | |
view () { | |
return [ | |
m('.search__products', [ | |
m('input', { | |
placeholder: 'SEARCH', | |
oninput: m.withAttr('value', state.setValue), | |
value: state.value | |
}) | |
]) | |
] | |
} | |
} | |
m.mount(document.querySelector('#search-filter'), Input) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{%comment%} | |
Add this to the template folder in the customize code page. | |
{%endcomment%} | |
{%- layout none -%} | |
{%- capture results -%} | |
{%- for item in search.results -%} | |
{%- unless item.title contains 'Re-waxing' -%} | |
{%- comment -%} | |
Set `product` variable | |
{%- endcomment -%} | |
{%- assign product = item -%} | |
{%- comment -%} | |
Check if the product is sold out and set a variable to be used below. | |
{%- endcomment -%} | |
{%- assign sold_out = true -%} | |
{%- if product.available -%} | |
{%- assign sold_out = false -%} | |
{%- endif -%} | |
{%- comment -%} | |
Check if the product is on sale and set a variable to be used below. | |
{%- endcomment -%} | |
{%- assign on_sale = false -%} | |
{%- if product.compare_at_price > product.price -%} | |
{%- assign on_sale = true -%} | |
{%- endif -%} | |
{%- comment -%} | |
Acquire the items quantity amount. | |
{%- endcomment -%} | |
{%- assign qty = 0 -%} | |
{%- for variant in product.variants -%} | |
{%- if variant.inventory_quantity > 0 -%} | |
{%- assign qty = qty | plus: variant.inventory_quantity -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- comment -%} | |
Set Product title name | |
{%- endcomment -%} | |
{%- if product.metafields.global.short_name -%} | |
{%- assign product_title = product.metafields.global.short_name -%} | |
{%- else -%} | |
{%- assign product_title = product.title -%} | |
{%- endif -%} | |
{%- comment -%} | |
Set Product color name | |
{% endcomment %} | |
{%- if product.metafields.global.product_color -%} | |
{%- assign color = product.metafields.global.product_color -%} | |
{%- endif -%} | |
{%- if on_sale -%} | |
{%- if product.price_varies -%} | |
{%- assign sale_price = product.price | money -%} | |
{%- else -%} | |
{%- assign price = product.price | money -%} | |
{%- assign compare = product.compare_at_price | money %} | |
{%- endif -%} | |
{% else %} | |
{%- if product.price_varies -%} | |
{%- assign price = product.price | money -%} | |
{%- else -%} | |
{%- assign price = product.price | money -%} | |
{%- endif -%} | |
{%- endif -%} | |
{%- comment -%} | |
Set sale property value | |
{%- endcomment -%} | |
{%- if on_sale -%} | |
{%- unless sold_out -%} | |
{% if product.compare_at_price > product.price %} | |
{%- assign sale = product.compare_at_price | |
| minus: product.price | |
| times: 100.0 | |
| divided_by: product.compare_at_price | |
| times: 100 | |
| divided_by: 100 | |
| floor | |
| append: '% OFF' %} | |
{% endif %} | |
{%- endunless -%} | |
{%- endif -%} | |
{%- comment -%} | |
Applies different stock badge texts based on season. | |
{%- endcomment -%} | |
{%- if product.vendor == 'Autumn / Winter 18' -%} | |
{%- assign status = 'COMING SOON' -%} | |
{%- else -%} | |
{%- assign status = 'OUT OF STOCK' -%} | |
{%- endif -%} | |
{%- comment -%} | |
Build JSON response | |
{%- endcomment -%} | |
{ | |
"id": {{ product.id | json }}, | |
"title": {{ product_title | json }}, | |
"color": {%- if color -%}{{ color | json }}{%- else -%}false{%- endif -%}, | |
"url": {{ product.url | within: product.collections.last | json }}, | |
"image": {{ product.featured_image.src | product_img_url: 'x560' | json }}, | |
"price": {{ price | json }}, | |
"compare": {%- if compare -%}{{ compare | json }}{%- else -%}false{%- endif -%}, | |
"sale": {%- if sale -%}{{ sale | json }}{%- else -%}false{%- endif -%}, | |
"quantity": {{ qty | strip }}, | |
"status": {%- if status -%}{{ status | json }}{%- else -%}false{%- endif -%} | |
} | |
{%- unless forloop.last -%},{%- endunless -%} | |
{%- endunless -%} | |
{%- endfor -%} | |
{%- endcapture -%} | |
{%- comment -%} | |
Return response array | |
{%- endcomment -%} | |
{ | |
"results_count": {{ search.results_count | strip }}, | |
"results": [{{ results | strip }}] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment