Don’t you think it would be more efficient to implement a non php filtering solution right away? Reloading the page for every filter isn’t very user friendly. Sonja suggested Isotope and Shuffle.js in her second post and I think she is right.
Edit: If you use AJAX, you avoid page reloading; the javascript solutions are not necessarily easier to implement, though, and add additional page weight to your site.
That’s strange… I’ll send you a link. Thanks![quote=“texnixe, post:22, topic:3946, full:true”]
I haven’t received anything …?
–
FYI: I deleted my license from config.php and replaced it with the invoice number for verification.
Hi texnixe, it’s me again. Here is a working solution based on jQuery. It’s a mix of your code with a nice plugin called multifilter.js (I know the script is not supposed to be anywhere near the template but hey : )
<script src="https://code.jquery.com/jquery-2.0.3.js"></script>
<script>(function($) {
"use strict";
$.fn.multifilter = function(options) {
var settings = $.extend( {
'target' : $('table'),
'method' : 'thead' // This can be thead or class
}, options);
jQuery.expr[":"].Equals = function(a, i, m) {
return (a.textContent || a.innerText || "").toUpperCase() === m[3].toUpperCase();
};
this.each(function() {
var $this = $(this);
var container = settings.target;
var row_tag = 'tr';
var item_tag = 'td';
var rows = container.find($(row_tag));
if (settings.method === 'thead') {
// Match the data-col attribute to the text in the thead
var col = container.find('th:Equals(' + $this.data('col') + ')');
var col_index = container.find($('thead th')).index(col);
};
if (settings.method === 'class') {
// Match the data-col attribute to the class on each column
var col = rows.first().find('td.' + $this.data('col'));
var col_index = rows.first().find('td').index(col);
};
$this.change(function() {
var filter = $this.val();
rows.each(function() {
var row = $(this);
var cell = $(row.children(item_tag)[col_index]);
if (filter) {
if (cell.text().toLowerCase().indexOf(filter.toLowerCase()) !== -1) {
cell.attr('data-filtered', 'positive');
} else {
cell.attr('data-filtered', 'negative');
}
if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
row.hide();
} else {
if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
row.show();
}
}
} else {
cell.attr('data-filtered', 'positive');
if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
row.hide();
} else {
if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
row.show();
}
}
}
});
return false;
}).click(function() {
$this.change();
});
});
};
})(jQuery);</script>
<link href='style.css' media='screen' rel='stylesheet' type='text/css' />
</head>
<script type='text/javascript'>
//<![CDATA[
$(document).ready(function() {
$('.filter').multifilter()
})
//]]>
</script>
<body>
<?php
// main menu items
$status = page('projects')->children()->pluck('status', null, true);
$year = page('projects')->children()->pluck('year', null, true);
// only show the menu if items are available
?>
<form id="filters" action="" method="post">
<select name="status" class='filter' data-col='status'/>
<option selected value="">Select a status</option>
<?php foreach($status as $item): ?>
//filter out empty items
<?php if ($item == "") continue; ?>
//set the option to selected if selected
<option <?php if((isset($_POST['status'])) && $_POST['status'] == $item) { echo "selected"; } ?> value="<?php echo $item->html() ?>"><?php echo $item->html() ?></option>
<?php endforeach ?>
</select>
<select name="year" class='filter' data-col='year'/>
<option selected value="">Select a year</option>
<?php foreach($year as $item): ?>
<?php if ($item == "") continue; ?>
<option <?php if((isset($_POST['year'])) && $_POST['year'] == $item) { echo "selected"; } ?> value="<?php echo $item->html() ?>"><?php echo $item->html() ?></option>
<?php endforeach ?>
</select>
</form>
<div class='container'>
<table>
<thead>
<th>title</th>
<th>status</th>
<th>year</th>
<th>cat</th>
</thead>
<tbody> <?php foreach(page('projects')->children()->visible() as $project): ?>
<tr>
<td>
<?php echo $project->id000()->html() ?> <a href="<?php echo $project->url() ?>"><?php echo $project->title()->html() ?></a>
</td>
<td>
<?php echo $project->status()->html() ?>
</td>
<td>
<?php echo $project->year()->html() ?>
</td>
<td>
<?php echo $project->cat()->html() ?>
</td>
</tr> <?php endforeach ?>
</tbody>
</table>
</div>
Is there a way you can share how ended up the Blueprint, Controller and Template? I´m also very new in Kirby and I´m on a project that needs this kind of filters.
The above example is complete, it does not need a controller, because the filtering is done with javascript. As regards the blueprint, all you need is the fields you want to filter by, in the example above that’s “year” and “status”.
In the docs you can find an example without javascript, with a form and the corresponding controller.
Hypothetical question, is there a way to integrate this with a param function?
For instance if we went to the url /category:drawing it would enable the page to bring up the results as if ‘drawing’ had been selected using the dropdown form?
I know its a shot in the dark, really appreciate your expertise!
@1-L-P Keep in mind that if you want to filter by multiple fields/params (that was the question in this thread), it makes more sense to use select fields.
Yes indeed as it’s currently not working for me. based on the java and selected fields how would the filter be set up with the param function? Apologies for the bloated code, I’m still just trying things out. the idea would be if I used the url say category:design it would auto select that in the form to bring up the results… based on the code in this thread. Hope this makes sense.