Skip to content

Commit 40d2799

Browse files
WIP: implement LIST checkbox filtering by tag see #514
1 parent 1ff8c2d commit 40d2799

File tree

3 files changed

+109
-4
lines changed

3 files changed

+109
-4
lines changed

app/class/Optlist.php

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Optlist extends Optcode
1717
protected bool $time = false;
1818
protected bool $author = false;
1919
protected bool $hidecurrent = false;
20-
protected bool $tags = false;
20+
protected bool $checkbox = false;
2121
protected string $style = self::LIST;
2222

2323
public const LIST = 'list';
@@ -27,6 +27,8 @@ class Optlist extends Optcode
2727
self::CARD, self::CARD,
2828
];
2929

30+
protected array $usefulltags = [];
31+
3032
public function __construct(array $datas = [])
3133
{
3234
parent::__construct($datas);
@@ -49,6 +51,9 @@ public function getcode(): string
4951
*/
5052
public function listhtml(array $pagelist, Page $currentpage): string
5153
{
54+
$pagecount = count($pagelist);
55+
$html = '';
56+
5257
if ($this->hidecurrent && key_exists($currentpage->id(), $pagelist)) {
5358
unset($pagelist[$currentpage->id()]);
5459
}
@@ -59,7 +64,6 @@ public function listhtml(array $pagelist, Page $currentpage): string
5964
$timeformatter = new IntlDateFormatter($lang, IntlDateFormatter::NONE, IntlDateFormatter::SHORT);
6065

6166
try {
62-
$dom = new DOMDocument();
6367
$dom = new DOMDocument('1.0', 'UTF-8');
6468

6569
$ul = $dom->createElement('ul');
@@ -135,16 +139,63 @@ public function listhtml(array $pagelist, Page $currentpage): string
135139
$thumbnail->setAttribute('alt', htmlspecialchars($page->title()));
136140
$parent->appendChild($thumbnail);
137141
}
142+
if ($this->checkbox) {
143+
$tags = $page->tag();
144+
$this->addusefulltags($tags);
145+
foreach ($tags as $tag) {
146+
$parent->setAttribute("data-tag_$tag", '1');
147+
}
148+
}
138149
}
139-
140150
$dom->appendChild($ul);
141151

142-
return $dom->saveHTML($dom->documentElement);
152+
if ($this->checkbox) {
153+
$domform = new DOMDocument('1.0', 'UTF-8');
154+
$form = $domform->createElement('form');
155+
foreach ($this->usefulltags as $tag => $count) {
156+
if ($count === $pagecount) {
157+
continue; // skip this tag as it's used by all pages
158+
}
159+
$span = $domform->createElement('span');
160+
$id = "checkbox-tag_$tag";
161+
$input = $domform->createElement('input');
162+
$input->setAttribute('id', $id);
163+
$input->setAttribute('value', $tag);
164+
$input->setAttribute('type', 'checkbox');
165+
$label = $domform->createElement('label', $tag);
166+
$label->setAttribute('for', $id);
167+
$span->appendChild($input);
168+
$span->appendChild($label);
169+
$form->appendChild($span);
170+
}
171+
$domform->appendChild($form);
172+
$html .= $domform->saveHTML($domform->documentElement);
173+
$html .= "\n";
174+
}
175+
176+
$html .= $dom->saveHTML($dom->documentElement);
177+
178+
return $html;
143179
} catch (DOMException $e) {
144180
throw new LogicException('bad DOM node used', 0, $e);
145181
}
146182
}
147183

184+
/**
185+
* merge list of tags within the list of usefull tags.
186+
* Tag names are stored as key and value count the time it's used.
187+
*/
188+
private function addusefulltags(array $tags): void
189+
{
190+
foreach ($tags as $tag) {
191+
if (key_exists($tag, $this->usefulltags)) {
192+
$this->usefulltags[$tag] ++;
193+
} else {
194+
$this->usefulltags[$tag] = 1;
195+
}
196+
}
197+
}
198+
148199

149200

150201

@@ -186,6 +237,11 @@ public function hidecurrent(): bool
186237
return $this->hidecurrent;
187238
}
188239

240+
public function checkbox(): bool
241+
{
242+
return $this->checkbox;
243+
}
244+
189245
public function style()
190246
{
191247
return $this->style;
@@ -229,6 +285,11 @@ public function sethidecurrent($hidecurrent)
229285
$this->hidecurrent = boolval($hidecurrent);
230286
}
231287

288+
public function setcheckbox($checkbox)
289+
{
290+
$this->checkbox = boolval($checkbox);
291+
}
292+
232293
public function setstyle($style)
233294
{
234295
if (is_string($style) && key_exists($style, self::STYLES)) {

app/class/Servicerender.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ abstract class Servicerender
4848
/** @var bool True if the page need post process */
4949
protected bool $postprocessaction = false;
5050

51+
/** @var bool True if the page need to join a JS checkbox file */
52+
protected bool $checkboxjs = false;
53+
5154
/**
5255
* @var Bookmark[] Associative array of Bookmarks using fullmatch as key
5356
* */
@@ -259,6 +262,10 @@ protected function gethead(): string
259262
} catch (RuntimeException $e) {
260263
Logger::warningex($e);
261264
}
265+
if ($this->checkboxjs) {
266+
$checkboxjs = Model::jspath() . 'pagecheckbox.bundle.js';
267+
$head .= "<script type=\"module\" src=\"$checkboxjs\" async/></script>\n";
268+
}
262269
if (!empty($this->page->javascript())) {
263270
$head .= "<script src=\"$renderpath$id.js\" async/></script>\n";
264271
}
@@ -697,6 +704,9 @@ protected function pageoptlist(string $text): string
697704
try {
698705
$optlist = new Optlist();
699706
$optlist->parsehydrate($match['options'], $this->page);
707+
if ($optlist->checkbox()) {
708+
$this->checkboxjs = true;
709+
}
700710

701711
if (!empty($optlist->bookmark())) {
702712
$bookmarkmanager = new Modelbookmark();

src/pagecheckbox.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
console.log('yoo');
2+
3+
const formFilter = document.querySelector('form');
4+
5+
function w_filterpagelist() {
6+
let tagCheckboxesChecked = document.querySelectorAll(
7+
'input[type="checkbox"]:checked'
8+
);
9+
10+
let pages = document.querySelectorAll('.pagelist li');
11+
let tagCount = tagCheckboxesChecked.length;
12+
13+
for (var li of pages) {
14+
li.classList.remove('w_filter-or-out');
15+
li.classList.remove('w_filter-and-out');
16+
if (tagCount > 0) {
17+
let counter = 0;
18+
for (var tag of tagCheckboxesChecked) {
19+
let dataAttr = 'data-tag_' + tag.value;
20+
if (li.hasAttribute(dataAttr)) {
21+
counter++;
22+
}
23+
}
24+
if (counter < 1) {
25+
li.classList.add('w_filter-or-out');
26+
}
27+
if (counter !== tagCount) {
28+
li.classList.add('w_filter-and-out');
29+
}
30+
}
31+
}
32+
}
33+
34+
formFilter.addEventListener('click', w_filterpagelist);

0 commit comments

Comments
 (0)