Hello, I am struggeling with building a custom search bar for my vacancies.
I currently have a repeater field where I make <select> with the options out of the hubDB. here I type manually in the column I like to filter.
This works great but now I want to be able to search on the column job_position.
I want to be able to type in a part of the code so for example the job_position of a row is “Junior webdeveloper”. I want to find this vacature with typing in ‘junior’ in the search box.
This is my module:
{{ require_css(get_asset_url('/hlb-website-demo/web/assets/styles/generic/3-components/pagination.css'), { async: true }) }}
{{ require_css(get_asset_url("/hlb-website-demo/web/modules/listing-filtered-vacancies/style/listing-filtered-vacancies.css"), { async: true} ) }}
{% from '/hlb-website-demo/web/modules/listing-filtered-vacancies/macros/listing-filtered-vacancies.html' import create_filter_url %}
{% from '/hlb-website-demo/web/modules/listing-filtered-vacancies/macros/listing-filtered-vacancies.html' import create_excluding_filter_url %}
{% from '/hlb-website-demo/web/modules/listing-filtered-vacancies/macros/listing-filtered-vacancies.html' import add_filters %}
{# page number #}
{% set page_num_filter = 'list_page_num' %}
{% set page_num = request.query_dict[page_num_filter] ? request.query_dict[page_num_filter]|int : 1 %}
{# categories order #}
{# output #}
{% set output = {} %}
{% set list_tags = [{title: '', column_name: 'category', excluding: false},{title: '', column_name: 'experience_type', excluding: true}] %}
{{ add_filters(module.vacancies_table, list_tags, module.filters, output, page_num_filter) }}
{% set module_classes = module.module_settings.top_padding %}
{% set module_classes = module.module_settings.bottom_padding ~ ' ' ~ module_classes %}
<section {{ 'id="{{ module.module_settings.section_id }}"' if module.module_settings.section_id }} class="m-listing-filtered-vacancies {{ module_classes }}" {{ 'data-has-filters="true"' if request.query_dict.used_filters or request.query_dict[page_num_filter] }}>
{% if module.title %}
<div class="container m-listing-filtered-vacancies__title">
<h2>{{ module.title }}</h2>
</div>
{% endif %}
<div class="m-listing-filtered-vacancies__filters">
<div class="container">
<div class="m-listing-filtered-vacancies__filter-categories">
<div class="m-listing-filtered-vacancies__filter-select-wrapper">
<div class="m-listing-filtered-vacancies__filter-select">
{% for category in output.filter_categories|selectattr('type', 'equalto','select') %}
<div>
<select data-filter-category>
<option value="{{ create_filter_url(page_num_filter, 1, category.name)|trim }}" {{ 'selected disabled' if not request.query_dict[category.name] }}>{{ request.query_dict[category.name] is defined ? module.translations.reset : category.label }}</option>
{% set sorter = category.name == 'experience_type' || category.name == 'education_level' ? 'order' : 'text' %}
{% for item in category.filters|sort(false,false,sorter) %}
<option value="{{- item.url|trim -}}" {{ 'selected' if item.text|replace('&', '') == request.query_dict[category.name]|replace('&', '') }}>{{ item.text }}</option>
{% endfor %}
</select>
<select class="display_is-hidden" data-filter-hidden>
<option></option>
</select>
</div>
{% endfor %}
</div>
{# Sort by newest/oldest #}
<div class="m-listing-filtered-vacancies__sort">
<select data-filter-category>
<option {{ 'selected' if request.query_dict.order_by == 'date' or request.query_dict.order_by is not defined }} value="{{ create_filter_url('order_by', "date", page_num_filter)|trim }}">{{ module.translations.sort_by_newest }}</option>
<option {{ 'selected' if request.query_dict.order_by == 'az' }} value="{{ create_filter_url('order_by', "az", page_num_filter)|trim }}">{{ module.translations.sort_alphabetically }}</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="m-listing-filtered-vacancies__results">
<div class="container">
{% if output.results|length > 0 %}
{% set ordered_results = output.results %}
{% set order_by_newest = request.query_dict.order_by is not defined or request.query_dict.order_by == 'date' %}
{% if order_by_newest %}
{% set ordered_results = ordered_results|sort(True, False, 'date_posted') %}
{% elif request.query_dict.order_by == 'az' %}
{% set ordered_results = ordered_results|sort(False, False, 'job_position') %}
{% endif %}
{% set pages = ordered_results|slice(module.results_per_page, ' ') %}
{% for current_page in pages %}
{% if loop.index == page_num %}
<p class="m-listing-filtered-vacancies__results-count"><strong>{{ ordered_results|length }}</strong> {{ module.translations.results_text }}</p>
{% for item in current_page|selectattr('hs_id', "defined") %}
<div class="m-listing-filtered-vacancies__vacancy-card">
{% if item.featured_image.url %}
<div class="m-listing-filtered-vacancies__visual">
<picture class="m-listing-filtered-vacancies__thumbnail media_image-cover">
<img class="media_image-responsive" src="{{ item.featured_image.url }}" alt="{{ item.job_position }}" loading="lazy" width="990">
{% if item.overlay_image.url %}
<img class="media_image-responsive overlay-image" src="{{ item.overlay_image.url }}" alt="{{ item.job_position }}" loading="lazy" width="990">
{% endif %}
</picture>
</div>
{% endif %}
<div class="m-listing-filtered-vacancies__job-description">
<div class="top-row">
<div class="job-description">
<div class="job-header">
{% for tag in item.category %}
<span>{{ tag.name }}</span>
{% endfor %}
<h3 class="keep-default">{{ item.job_position }}</h3>
</div>
</div>
</div>
<div class="bottom-row">
<div class="job-meta">
{% if item.education_level %}
<p class="keep-default education">{{ item.education_level|map('name')|join(', ') }}</p>
{% endif %}
{% if item.city|length > 0 %}
<p class="keep-default location">
{% for city in item.city %}
{{ city.name }}{{ ',' if not loop.last }}
{% endfor %}
</p>
{% endif %}
{% if item.contract_type %}
<p class="keep-default time">{{ item.contract_type|map('name')|join(', ') }}</p>
{% endif %}
</div>
{% from '/hlb-website-demo/web/macros/shared.html' import add_cta_button %}
{% set link = { url : { href: item.vacancy_detail_url } } %}
{{ add_cta_button("button", null, null, "alternative button__icon button__icon--circle-arrow", module.translations.button_text, link, "keep-default") }}
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
{% elif module.message_for_no_results %}
<div class="rich-text-container">
{{ module.message_for_no_results }}
</div>
{% endif %}
</div>
</div>
{# Pagination #}
{% from '/hlb-website-demo/web/modules/listing-filtered-vacancies/macros/listing-filtered-vacancies.html' import add_pagination %}
{{ add_pagination(output.results, module.results_per_page, page_num, module.translations.more_results, page_num_filter, "m-listing-filtered-vacancies__pagination") }}
{# End Pagination #}
</section>
This is my macro file:
<!--
templateType: "none"
isAvailableForNewContent: false
-->
{# Construct url #}
{% macro create_filter_url(replace_key, replace_value, ignore_key) -%}
{% set constructed_url = request.full_url %}
{% set urlObj = {} %}
{% set operator = {} %}
{% set known_keys = request.query_dict.items()|map("key") %}
{% for key in known_keys %}
{% set operator_value = (operator.value is not defined or operator.value == '') ? '?' : '&' %}
{% do operator.update({value: operator_value}) %}
{% if loop.first && key == ignore_key %}
{% do operator.update({value: ''}) %}
{% endif %}
{% if key == replace_key %}
{% set constructed_url = constructed_url ~ operator.value ~ key ~ '=' ~ replace_value %}
{% do urlObj.update({value: constructed_url}) %}
{% elif key != ignore_key %}
{% set constructed_url = constructed_url ~ operator.value ~ key ~ '=' ~ request.query_dict[key]|replace('&','&')|urlencode %}
{% do urlObj.update({value: constructed_url}) %}
{% endif %}
{% endfor %}
{% if replace_key is not within known_keys %}
{% set operator_value = (operator.value is defined and operator.value != '') ? '&' : '?' %}
{% set constructed_url = urlObj.value ~ operator_value ~ replace_key ~ '=' ~ replace_value %}
{% do urlObj.update({value: constructed_url}) %}
{% endif %}
{% if 'used_filters' is not within known_keys and key != ignore_key %}
{% do urlObj.update({value: urlObj.value ~ '&used_filters=true'}) %}
{% endif %}
{{ urlObj.value }}
{%- endmacro %}
{# End construct url #}
{# Construct excluding url #}
{% macro create_excluding_filter_url(new_key, new_value) -%}
{% set constructed_url = request.full_url %}
{% set urlObj = {} %}
{% set operator = {} %}
{% set known_keys = request.query_dict.items()|map("key") %}
{% if 'hs_preview' in known_keys %}
{% set operator_value = operator.value is not defined ? '?' : '&' %}
{% do operator.update({value: operator_value}) %}
{% set constructed_url = constructed_url ~ operator.value ~ 'hs_preview=' ~ request.query_dict.hs_preview %}
{% do urlObj.update({value: constructed_url}) %}
{% endif %}
{% set operator_value = operator.value is defined ? '&' : '?' %}
{% set constructed_url = urlObj.value ~ operator_value ~ new_key ~ '=' ~ new_value|replace('&','&')|escapejs %}
{% do urlObj.update({value: constructed_url }) %}
{% if new_key is defined %}
{% do urlObj.update({value: urlObj.value ~ '&used_filters=true' }) %}
{% endif %}
{{ urlObj.value }}
{%- endmacro %}
{# End construct excluding url #}
{# Add filter #}
{% macro add_filter(row, filter_list, filter, fallback_filter) -%}
{% if request.query_dict.experience_type and filter.name != 'experience_type' %}
{% if request.query_dict.experience_type is within row.experience_type|map('name') %}
{% for value in row[filter.name] %}
{% set filter_val = value.name ? value.name : value %}
{% if filter_val is not within filter_list|map('text') %}
{% set filter_url = (filter.type == 'list' and filter.excluding == true) ? create_excluding_filter_url(filter.name, filter_val|urlencode) : create_filter_url(filter.name, filter_val|urlencode, fallback_filter) %}
{% do filter_list.append({ url: filter_url, text: filter_val, order: value.order }) %}
{% endif %}
{% endfor %}
{% endif %}
{% else %}
{% for value in row[filter.name] %}
{% set filter_val = value.name ? value.name : value %}
{% if filter_val is not within filter_list|map('text') %}
{% set filter_url = (filter.type == 'list' and filter.excluding == true) ? create_excluding_filter_url(filter.name, filter_val|urlencode) : create_filter_url(filter.name, filter_val|urlencode, fallback_filter) %}
{% do filter_list.append({ url: filter_url, text: filter_val, order: value.order }) %}
{% endif %}
{% endfor %}
{% endif %}
{%- endmacro %}
{# End add filter #}
{# Add filters #}
{% macro add_filters(hubdb_table_id, list_column_names, select_column_names, output, page_num_filter="list_page_num") -%}
{% set filters = [] %}
{% for column in list_column_names %}
{% do filters.append({name: column.column_name, label: column.title, type: 'list', excluding: column.excluding}) %}
{% endfor %}
{% for column in select_column_names %}
{% do filters.append({name: column.column_name, label: column.title, type: 'select'}) %}
{% endfor %}
{% set all_filters = [] %}
{% set query = '&vacancy_detail_url__not_null=' %}
{% set table_rows = hubdb_table_rows(hubdb_table_id, query) %}
{% set unfiltered_rows = table_rows %}
{% for item in filters %}
{% set filters = [] %}
{% for row in table_rows %}
{{ add_filter(row, filters, item, page_num_filter) }}
{% endfor %}
{% do all_filters.append({ name: item.name, label: item.label, filters: filters, type: item.type }) %}
{% endfor %}
{# filtered results #}
{% set indexesToRemove = [] %}
{% for item in all_filters %}
{% if request.query_dict[item.name] is defined %}
{% for row in unfiltered_rows %}
{% set atLeastOneMatch = {value: false } %}
{% for val in row[item.name] %}
{% set filter_name = val.name ? val.name : val %}
{% if request.query_dict[item.name]|replace('&', '') == filter_name|replace('&', '') %}
{% do atLeastOneMatch.update({value: true}) %}
{% endif %}
{% endfor %}
{% if !atLeastOneMatch.value %}
{% do indexesToRemove.append(row.hs_id) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% set filtered_rows = indexesToRemove|length > 0 ? unfiltered_rows|rejectattr("hs_id", "within", indexesToRemove) : unfiltered_rows %}
{% do output.update({ filter_categories: all_filters, results: filtered_rows }) %}
{%- endmacro %}
{# End Add filters #}
{# Pagination #}
{% macro add_pagination(results, limit, page_num, title="", page_num_filter = 'list_page_num', extra_classes="") %}
{% set total_pages = 1 %}
{% if limit %}
{% set total_pages = ((results | length) / limit) | round(0, 'ceil') %}
{% endif %}
{% set more_pages = total_pages - page_num %}
{% if total_pages > 1 %}
{% set first_page_url = create_filter_url(page_num_filter, 1) %}
<div class="{{ extra_classes }}">
<div class="container">
<div class="pagination">
{% if title %}
<p class="pagination__title">{{ title }}</p>
{% endif %}
<ul>
{% if page_num > 1 %}
<li><a class="prev" href="{{ create_filter_url(page_num_filter, page_num - 1) }}"></a></li>
{% endif %}
{% if more_pages == 0 %}
{% if page_num - 3 == 1 %}<li><a href="{{ first_page_url }}">{{ page_num - 3 }}</a></li>{% endif %}
{% if page_num - 3 > 1 %}<li><a href="{{ create_filter_url(page_num_filter, page_num - 3) }}">{{ page_num - 3 }}</a></li>{% endif %}
{% endif %}
{% if more_pages <= 1 %}
{% if page_num - 2 == 1 %}<li><a href="{{ first_page_url }}">{{ page_num - 2 }}</a></li>{% endif %}
{% if page_num - 2 > 1 %}<li><a href="{{ create_filter_url(page_num_filter, page_num - 2) }}">{{ page_num - 2 }}</a></li>{% endif %}
{% endif %}
{% if page_num - 1 == 1 %}<li><a href="{{ first_page_url }}">{{ page_num - 1 }}</a></li>{% endif %}
{% if page_num - 1 > 1 %}<li><a href="{{ create_filter_url(page_num_filter, page_num - 1) }}">{{ page_num - 1 }}</a></li>{% endif %}
<li class="active"><a
href="{% if page_num==1 %}{{ first_page_url }}{% else %}{{ create_filter_url(page_num_filter, page_num) }}{% endif %}">{{ page_num }}</a>
</li>
{% if page_num + 1 <= total_pages %}<li><a href="{{ create_filter_url(page_num_filter, page_num + 1) }}">{{ page_num + 1 }}</a></li>{% endif %}
{% if page_num + 2 <= total_pages %}<li><a href="{{ create_filter_url(page_num_filter, page_num + 2) }}">{{ page_num + 2 }}</a></li>{% endif %}
{% if page_num == 1 %}
{% if page_num + 3 <= total_pages %}<li><a href="{{ create_filter_url(page_num_filter, page_num + 3) }}">{{ page_num + 3 }}</a></li>{% endif %}
{% endif %}
{% if more_pages > 0 %}
<li><a class="next" href="{{ create_filter_url(page_num_filter, page_num + 1) }}"></a></li>
{% endif %}
</ul>
</div>
</div>
</div>
{% endif %}
{% endmacro %}
{# End Pagination #}