Skip to content

Commit

Permalink
Changed price filter to use text input (#3280)
Browse files Browse the repository at this point in the history
* Changed price filter to use text input

* Removed stepping and enabled all meta key inputs

* Turned price filter into a snippet to remove duplicate code

* Removed need for nbsp, added escape and apostrophe, slightly changed debounce delay

* Retain focus in text inputs
  • Loading branch information
tyleralsbury authored Mar 15, 2024
1 parent 609435a commit b10f312
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 184 deletions.
34 changes: 23 additions & 11 deletions assets/facets.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class FacetFiltersForm extends HTMLElement {

this.debouncedOnSubmit = debounce((event) => {
this.onSubmitHandler(event);
}, 500);
}, 800);

const facetForm = this.querySelector('form');
facetForm.addEventListener('input', this.debouncedOnSubmit.bind(this));
Expand Down Expand Up @@ -128,6 +128,7 @@ class FacetFiltersForm extends HTMLElement {
const jsFilter = event ? event.target.closest('.js-filter') : undefined;
return jsFilter ? element.id === jsFilter.id : false;
};

const facetsToRender = Array.from(facetDetailsElementsFromFetch).filter((element) => !matchesId(element));
const countsToRender = Array.from(facetDetailsElementsFromFetch).find(matchesId);

Expand Down Expand Up @@ -167,7 +168,10 @@ class FacetFiltersForm extends HTMLElement {
? `.mobile-facets__close-button`
: `.facets__summary`;
const newElementToActivate = newFacetDetailsElement.querySelector(newElementSelector);
if (newElementToActivate) newElementToActivate.focus();

const isTextInput = event.target.getAttribute('type') === 'text';

if (newElementToActivate && !isTextInput) newElementToActivate.focus();
}
}
}
Expand Down Expand Up @@ -298,9 +302,10 @@ FacetFiltersForm.setListeners();
class PriceRange extends HTMLElement {
constructor() {
super();
this.querySelectorAll('input').forEach((element) =>
element.addEventListener('change', this.onRangeChange.bind(this))
);
this.querySelectorAll('input').forEach((element) => {
element.addEventListener('change', this.onRangeChange.bind(this));
element.addEventListener('keydown', this.onKeyDown.bind(this));
});
this.setMinAndMaxValues();
}

Expand All @@ -309,20 +314,27 @@ class PriceRange extends HTMLElement {
this.setMinAndMaxValues();
}

onKeyDown(event) {
if (event.metaKey) return;

const pattern = /[0-9]|\.|,|'| |Tab|Backspace|Enter|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Delete|Escape/;
if (!event.key.match(pattern)) event.preventDefault();
}

setMinAndMaxValues() {
const inputs = this.querySelectorAll('input');
const minInput = inputs[0];
const maxInput = inputs[1];
if (maxInput.value) minInput.setAttribute('max', maxInput.value);
if (minInput.value) maxInput.setAttribute('min', minInput.value);
if (minInput.value === '') maxInput.setAttribute('min', 0);
if (maxInput.value === '') minInput.setAttribute('max', maxInput.getAttribute('max'));
if (maxInput.value) minInput.setAttribute('data-max', maxInput.value);
if (minInput.value) maxInput.setAttribute('data-min', minInput.value);
if (minInput.value === '') maxInput.setAttribute('data-min', 0);
if (maxInput.value === '') minInput.setAttribute('data-max', maxInput.getAttribute('data-max'));
}

adjustToValidValues(input) {
const value = Number(input.value);
const min = Number(input.getAttribute('min'));
const max = Number(input.getAttribute('max'));
const min = Number(input.getAttribute('data-min'));
const max = Number(input.getAttribute('data-max'));

if (value < min) input.value = min;
if (value > max) input.value = max;
Expand Down
191 changes: 18 additions & 173 deletions snippets/facets.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,13 @@
</facet-remove>
{%- endfor -%}
{% if filter.type == 'price_range' %}
{%- if filter.min_value.value != null or filter.max_value.value != null -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{%- if filter.min_value.value -%}
{{ filter.min_value.value | money }}
{%- else -%}
{{ 0 | money }}
{%- endif -%}
-
{%- if filter.max_value.value -%}
{{ filter.max_value.value | money }}
{%- else -%}
{{ filter.range_max | money }}
{%- endif -%}
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
{% render 'icon-close-small' %}
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
Expand Down Expand Up @@ -320,13 +312,6 @@
</div>
</details>
{% when 'price_range' %}
{% liquid
assign currencies_using_comma_decimals = 'ANG,ARS,BRL,BYN,BYR,CLF,CLP,COP,CRC,CZK,DKK,EUR,HRK,HUF,IDR,ISK,MZN,NOK,PLN,RON,RUB,SEK,UYU,VES,VND' | split: ','
assign uses_comma_decimals = false
if currencies_using_comma_decimals contains cart.currency.iso_code
assign uses_comma_decimals = true
endif
%}
<details
id="Details-{{ filter.param_name | escape }}-{{ section.id }}"
class="{% if filter_type == 'horizontal' %}disclosure-has-popup facets__disclosure{% else %} facets__disclosure-vertical{% endif %} js-filter"
Expand Down Expand Up @@ -359,61 +344,7 @@
{%- endif -%}
</div>
<price-range class="facets__price">
<span class="field-currency">{{ cart.currency.symbol }}</span>
<div class="field">
<input
class="field__input"
name="{{ filter.min_value.param_name }}"
id="Filter-{{ filter.label | escape }}-GTE"
{%- if filter.min_value.value -%}
{%- if uses_comma_decimals -%}
value="{{ filter.min_value.value | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
value="{{ filter.min_value.value | money_without_currency | replace: ',', '' }}"
{%- endif %}
{%- endif -%}
type="number"
placeholder="0"
min="0"
{%- if uses_comma_decimals -%}
max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
max="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
{% endif %}
>
<label class="field__label" for="Filter-{{ filter.label | escape }}-GTE">
{{- 'products.facets.from' | t -}}
</label>
</div>
{%- if filter_type != 'vertical' -%}
<span class="field-currency">{{ cart.currency.symbol }}</span>
{%- endif -%}
<div class="field">
<input
class="field__input"
name="{{ filter.max_value.param_name }}"
id="Filter-{{ filter.label | escape }}-LTE"
{%- if filter.max_value.value -%}
{%- if uses_comma_decimals -%}
value="{{ filter.max_value.value | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
value="{{ filter.max_value.value | money_without_currency | replace: ',', '' }}"
{%- endif %}
{%- endif -%}
type="number"
min="0"
{%- if uses_comma_decimals -%}
placeholder="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
placeholder="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
max="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
{% endif %}
>
<label class="field__label" for="Filter-{{ filter.label | escape }}-LTE">
{{- 'products.facets.to' | t -}}
</label>
</div>
{% render 'price-facet', filter: filter, id_prefix: 'Filter-', filter_type: filter_type %}
</price-range>
</div>
</details>
Expand All @@ -436,21 +367,13 @@
</facet-remove>
{%- endfor -%}
{% if filter.type == 'price_range' %}
{%- if filter.min_value.value != null or filter.max_value.value != null -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{%- if filter.min_value.value -%}
{{ filter.min_value.value | money }}
{%- else -%}
{{ 0 | money }}
{%- endif -%}
-
{%- if filter.max_value.value -%}
{{ filter.max_value.value | money }}
{%- else -%}
{{ filter.range_max | money }}
{%- endif -%}
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
{% render 'icon-close-small' %}
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
Expand Down Expand Up @@ -761,13 +684,6 @@
</div>
</details>
{% when 'price_range' %}
{% liquid
assign currencies_using_comma_decimals = 'ANG,ARS,BRL,BYN,BYR,CLF,CLP,COP,CRC,CZK,DKK,EUR,HRK,HUF,IDR,ISK,MZN,NOK,PLN,RON,RUB,SEK,UYU,VES,VND' | split: ','
assign uses_comma_decimals = false
if currencies_using_comma_decimals contains cart.currency.iso_code
assign uses_comma_decimals = true
endif
%}
<details
id="Details-Mobile-{{ filter.param_name | escape }}-{{ section.id }}"
class="mobile-facets__details js-filter"
Expand Down Expand Up @@ -798,62 +714,7 @@
</p>

<price-range class="facets__price">
<span class="field-currency">{{ cart.currency.symbol }}</span>
<div class="field">
<input
class="field__input"
name="{{ filter.min_value.param_name }}"
id="Mobile-Filter-{{ filter.label | escape }}-GTE"
{%- if filter.min_value.value -%}
{%- if uses_comma_decimals -%}
value="{{ filter.min_value.value | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
value="{{ filter.min_value.value | money_without_currency | replace: ',', '' }}"
{%- endif %}
{%- endif -%}
type="number"
placeholder="0"
min="0"
inputmode="decimal"
{%- if uses_comma_decimals -%}
max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
max="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
{% endif %}
>
<label class="field__label" for="Mobile-Filter-{{ filter.label | escape }}-GTE">
{{- 'products.facets.from' | t -}}
</label>
</div>

<span class="field-currency">{{ cart.currency.symbol }}</span>
<div class="field">
<input
class="field__input"
name="{{ filter.max_value.param_name }}"
id="Mobile-Filter-{{ filter.label | escape }}-LTE"
{%- if filter.max_value.value -%}
{%- if uses_comma_decimals -%}
value="{{ filter.max_value.value | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
value="{{ filter.max_value.value | money_without_currency | replace: ',', '' }}"
{%- endif %}
{%- endif -%}
type="number"
min="0"
inputmode="decimal"
{%- if uses_comma_decimals -%}
placeholder="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '.' }}"
{%- else -%}
placeholder="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
max="{{ filter.range_max | money_without_currency | replace: ',', '' }}"
{% endif %}
>
<label class="field__label" for="Mobile-Filter-{{ filter.label | escape }}-LTE">
{{- 'products.facets.to' | t -}}
</label>
</div>
{% render 'price-facet', filter: filter, id_prefix: 'Mobile-Filter-' %}
</price-range>
<div class="mobile-facets__footer">
<facet-remove class="mobile-facets__clear-wrapper">
Expand Down Expand Up @@ -954,21 +815,13 @@
{%- endfor -%}

{%- if filter.type == 'price_range' -%}
{%- if filter.min_value.value != null or filter.max_value.value != null -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{%- if filter.min_value.value -%}
{{ filter.min_value.value | money }}
{%- else -%}
{{ 0 | money }}
{%- endif -%}
-
{%- if filter.max_value.value -%}
{{ filter.max_value.value | money }}
{%- else -%}
{{ filter.range_max | money }}
{%- endif -%}
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
{% render 'icon-close-small' %}
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
Expand Down Expand Up @@ -1065,21 +918,13 @@
{%- endfor -%}

{%- if filter.type == 'price_range' -%}
{%- if filter.min_value.value != null or filter.max_value.value != null -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{%- if filter.min_value.value -%}
{{ filter.min_value.value | money }}
{%- else -%}
{{ 0 | money }}
{%- endif -%}
-
{%- if filter.max_value.value -%}
{{ filter.max_value.value | money }}
{%- else -%}
{{ filter.range_max | money }}
{%- endif -%}
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
{% render 'icon-close-small' %}
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
Expand Down
45 changes: 45 additions & 0 deletions snippets/price-facet.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<span class="field-currency">{{ cart.currency.symbol }}</span>

<div class="field">
<input
class="field__input"
name="{{ filter.min_value.param_name }}"
id="{{ id_prefix }}{{ filter.label | escape }}-GTE"
{%- if filter.min_value.value -%}
value="{{ filter.min_value.value | money_without_currency }}"
{%- endif -%}
type="text"
inputmode="decimal"
placeholder="0"
data-pattern="\d| |,|\."
data-min="0"
data-max="{{ filter.range_max | money_without_currency }}"
>
<label class="field__label" for="{{ id_prefix }}{{ filter.label | escape }}-GTE">
{{- 'products.facets.from' | t -}}
</label>
</div>

{%- if filter_type != 'vertical' -%}
<span class="field-currency">{{ cart.currency.symbol }}</span>
{%- endif -%}

<div class="field">
<input
class="field__input"
name="{{ filter.max_value.param_name }}"
id="{{ id_prefix }}{{ filter.label | escape }}-LTE"
{%- if filter.max_value.value -%}
value="{{ filter.max_value.value | money_without_currency }}"
{%- endif -%}
type="text"
inputmode="decimal"
placeholder="{{ filter.range_max | money_without_currency }}"
data-pattern="\d| |,|\."
data-min="0"
data-max="{{ filter.range_max | money_without_currency }}"
>
<label class="field__label" for="{{ id_prefix }}{{ filter.label | escape }}-LTE">
{{- 'products.facets.to' | t -}}
</label>
</div>

0 comments on commit b10f312

Please sign in to comment.