Skip to content

Commit 3395f83

Browse files
WIP: implement LIST checkbox filtering by tag see #514
1 parent a0d0ee5 commit 3395f83

File tree

3 files changed

+111
-4
lines changed

3 files changed

+111
-4
lines changed

app/class/Optlist.php

Lines changed: 66 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
/**
3133
* @param array<string, mixed> $datas
3234
*/
@@ -52,6 +54,9 @@ public function getcode(): string
5254
*/
5355
public function listhtml(array $pagelist, Page $currentpage): string
5456
{
57+
$pagecount = count($pagelist);
58+
$html = '';
59+
5560
if ($this->hidecurrent && key_exists($currentpage->id(), $pagelist)) {
5661
unset($pagelist[$currentpage->id()]);
5762
}
@@ -137,16 +142,63 @@ public function listhtml(array $pagelist, Page $currentpage): string
137142
$thumbnail->setAttribute('alt', htmlspecialchars($page->title()));
138143
$parent->appendChild($thumbnail);
139144
}
145+
if ($this->checkbox) {
146+
$tags = $page->tag();
147+
$this->addusefulltags($tags);
148+
foreach ($tags as $tag) {
149+
$parent->setAttribute("data-tag_$tag", '1');
150+
}
151+
}
140152
}
141-
142153
$dom->appendChild($ul);
143154

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

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

151203

152204

@@ -188,6 +240,11 @@ public function hidecurrent(): bool
188240
return $this->hidecurrent;
189241
}
190242

243+
public function checkbox(): bool
244+
{
245+
return $this->checkbox;
246+
}
247+
191248
public function style(): string
192249
{
193250
return $this->style;
@@ -231,7 +288,12 @@ public function sethidecurrent(bool $hidecurrent): void
231288
$this->hidecurrent = $hidecurrent;
232289
}
233290

234-
public function setstyle(string $style): void
291+
public function setcheckbox($checkbox)
292+
{
293+
$this->checkbox = boolval($checkbox);
294+
}
295+
296+
public function setstyle(string $style)
235297
{
236298
if (key_exists($style, self::STYLES)) {
237299
$this->style = $style;

app/class/Servicerender.php

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

52+
/** @var bool True if the page need to join a JS checkbox file */
53+
protected bool $checkboxjs = false;
54+
5255
/**
5356
* @var Bookmark[] Associative array of Bookmarks using fullmatch as key
5457
* */
@@ -260,6 +263,10 @@ protected function gethead(): string
260263
} catch (RuntimeException $e) {
261264
Logger::warningex($e);
262265
}
266+
if ($this->checkboxjs) {
267+
$checkboxjs = Model::jspath() . 'pagecheckbox.bundle.js';
268+
$head .= "<script type=\"module\" src=\"$checkboxjs\" async/></script>\n";
269+
}
263270
if (!empty($this->page->javascript())) {
264271
$head .= "<script src=\"$renderpath$id.js\" async/></script>\n";
265272
}
@@ -707,6 +714,10 @@ protected function pageoptlist(string $text): string
707714

708715
$optlist->hydrate($options);
709716

717+
if ($optlist->checkbox()) {
718+
$this->checkboxjs = true;
719+
}
720+
710721
$pagetable = $this->pagemanager->pagetable($this->pagemanager->pagelist(), $optlist);
711722
$content = $optlist->listhtml($pagetable, $this->page);
712723
$text = str_replace($match->fullmatch(), $content, $text);

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)