Post by Mosstyn » Wed Jul 20, 2022 10:29 pm

I'd thought I'd write a really quick, and easy guide on how to change the default Opencart filters into collapse-able ones that are neater and can be used in mobile layouts for those of us, like me, who aren't great coders, but can just about muddle through.

I can't seem to post pictures at the moment but will do so when I can.

Basically, I used an accordion tutorial from W3Schools and adapted it for OC. - https://www.w3schools.com/w3css/tryit.a ... _accordion

OK, the file we are going to edit is filter.twig, located in catalog/view/theme/YOUR THEME/template/extension/module/
If you don't have it, copy and paste it from catalog/view/theme/default/template/extension/module/

First we'll insert the button code and the 'panel' div.

The first four lines of your existing code will look like this:

Code: Select all

<div class="panel panel-default">
  <div class="panel-heading">{{ heading_title }}</div>
  <div class="list-group"> {% for filter_group in filter_groups %} <a class="list-group-item">{{ filter_group.name }}</a>
    <div class="list-group-item">
Insert the button code and div declaration as follows:

Code: Select all

<div class="panel panel-default">
  <div class="panel-heading">{{ heading_title }}</div>
  <div class="list-group"> {% for filter_group in filter_groups %} 
    <button class="accordion-filter"><a class="list-group-item">{{ filter_group.name }}</a></button>
    <div class="panel-filter">
      <div class="list-group-item">
Then insert the closing </div> in the correct place.
Change

Code: Select all

            <input type="checkbox" name="filter[]" value="{{ filter.filter_id }}" />
            {{ filter.name }}
            {% endif %}</label>
        </div>
        {% endfor %}</div>
    </div>
    {% endfor %}</div>
To:

Code: Select all

<input type="checkbox" name="filter[]" value="{{ filter.filter_id }}" />
            {{ filter.name }}
            {% endif %}</label>
        </div>
        {% endfor %}</div>
    </div></div>
    {% endfor %}</div>
OK, last thing for this file is to paste the javascript in.

Code: Select all

<script>
var acc = document.getElementsByClassName("accordion-filter");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
</script>
I just pasted it in below to the existing javascript at the bottom. You probably don't need two <script> tags, and I'm sure someone will correct me on best practice.

So you should have something like this (well, exactly like this)

Code: Select all

<div class="panel panel-default">
  <div class="panel-heading">{{ heading_title }}</div>
  <div class="list-group"> {% for filter_group in filter_groups %} 
    <button class="accordion-filter"><a class="list-group-item">{{ filter_group.name }}</a></button>
    <div class="panel-filter">
      <div class="list-group-item">
        <div id="filter-group{{ filter_group.filter_group_id }}">{% for filter in filter_group.filter %}
          <div class="checkbox">
          <label>{% if filter.filter_id in filter_category %}
            <input type="checkbox" name="filter[]" value="{{ filter.filter_id }}" checked="checked" />
            {{ filter.name }}
            {% else %}
            <input type="checkbox" name="filter[]" value="{{ filter.filter_id }}" />
            {{ filter.name }}
            {% endif %}</label>
        </div>
        {% endfor %}</div>
    </div></div>
    {% endfor %}</div>
  <div class="panel-footer text-right">
    <button type="button" id="button-filter" class="btn btn-primary">{{ button_filter }}</button>
  </div>
</div>
<script type="text/javascript"><!--
$('#button-filter').on('click', function() {
	filter = [];

	$('input[name^=\'filter\']:checked').each(function(element) {
		filter.push(this.value);
	});

	location = '{{ action }}&filter=' + filter.join(',');
});
//--></script> 
<script>
var acc = document.getElementsByClassName("accordion-filter");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
</script>
Finally, open your stylesheet.css located at catalogue/view/theme/YOUR THEME/styesheet/
and paste this CSS at the bottom. This gives you a basic white underlined accordion. But, obviously, you can change it to suit.
Again I will post pics when I'm able.

Code: Select all

.accordion-filter {
  background-color: white;
  color: #444;
  cursor: pointer;
  padding: 0;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active, .accordion:hover {
  background-color: #ccc; 
}


.panel-filter {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
}

.panel-filter .list-group-item {
background-color:white;
}
In your store admin click 'Extensions > Modifications and refresh, click on the settings wheel, top right on your admin home to refresh the theme and SASS cache.

That's it. Hope that helps someone out. Any constructive comments - if I can make things clearer, etc - are welcome.
Thanks.

New member

Posts

Joined
Tue Aug 01, 2017 7:02 am

Post by straightlight » Thu Jul 21, 2022 6:27 am

Why is this posted in the FAQ rather than creating an extension for this? The above suggests to alter core files which can affect countless extensions installed on a store.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON
Who is online

Users browsing this forum: No registered users and 1 guest