Skip to content

Commit 8172c0a

Browse files
committed
Cleaned up webform import list
1 parent db5b507 commit 8172c0a

6 files changed

Lines changed: 134 additions & 22 deletions

File tree

assets/css/webform-index.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.os2forms-sync-webform-index [type="search"] {
2+
width: 100%;
3+
}
4+
5+
.os2forms-sync-webform-index .div + div {
6+
margin-top: 1em;
7+
}
8+
9+
.os2forms-sync-webform-index .metadata {
10+
display: flex;
11+
justify-content: space-between;
12+
}
13+
14+
.os2forms-sync-webform-index .metadata .category .label::after {
15+
content: ': ';
16+
}
17+
18+
.os2forms-sync-webform-index .metadata div + div {
19+
margin-top: 0;
20+
}
21+
22+
.os2forms-sync-webform-index .fieldset__wrapper {
23+
margin-bottom: 0;
24+
}

assets/js/webform-index.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,22 @@ document.addEventListener('DOMContentLoaded', () => {
22
const webforms = document.querySelectorAll('.os2forms-sync-webform-index .os2forms-sync-webform')
33
const searchInput = document.querySelector('.os2forms-sync-webform-index [type="search"]')
44

5+
/**
6+
* Combine values of all `data-indexed` attributes on descendants.
7+
*/
8+
const index = (el) => {
9+
return [...el.querySelectorAll('[data-indexed]')]
10+
.map(e => e.dataset.indexed)
11+
.join(' ')
12+
}
13+
514
const liveSearch = () => {
6-
console.log('liveSearch', searchInput.value)
7-
const query = searchInput.value
15+
const query = searchInput.value.toLowerCase()
816
webforms.forEach(webform => {
9-
webform.hidden = !webform.innerText.toLowerCase().includes(query)
17+
if (!webform.indexed) {
18+
webform.indexed = index(webform).toLowerCase()
19+
}
20+
webform.hidden = !webform.indexed.includes(query)
1021
})
1122
}
1223

os2forms_sync.libraries.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
webform-index:
22
version: 1.x
3+
css:
4+
theme:
5+
assets/css/webform-index.css: {}
36
js:
47
assets/js/webform-index.js: {}

os2forms_sync.services.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,7 @@ services:
2121
Drupal\os2forms_sync\Helper\JsonAPISerializer:
2222

2323
Drupal\os2forms_sync\Twig\TwigExtension:
24+
arguments:
25+
- '@renderer'
2426
tags:
2527
- { name: twig.extension }

src/Twig/TwigExtension.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,31 @@
22

33
namespace Drupal\os2forms_sync\Twig;
44

5+
use Drupal\Component\Utility\Random;
6+
use Drupal\Core\Render\RendererInterface;
7+
use Drupal\webform\Entity\Webform;
58
use Symfony\Component\Yaml\Yaml;
69
use Twig\Extension\AbstractExtension;
710
use Twig\TwigFilter;
11+
use Twig\TwigFunction;
812

913
/**
1014
* Twig extension.
1115
*/
1216
class TwigExtension extends AbstractExtension {
17+
/**
18+
* The renderer.
19+
*
20+
* @var \Drupal\Core\Render\RendererInterface
21+
*/
22+
private RendererInterface $renderer;
23+
24+
/**
25+
* Constructor.
26+
*/
27+
public function __construct(RendererInterface $renderer) {
28+
$this->renderer = $renderer;
29+
}
1330

1431
/**
1532
* {@inheritdoc}
@@ -20,6 +37,18 @@ public function getFilters() {
2037
];
2138
}
2239

40+
/**
41+
* {@inheritdoc}
42+
*/
43+
public function getFunctions() {
44+
return [
45+
new TwigFunction('render_webform_elements', [
46+
$this,
47+
'renderWebformElements',
48+
]),
49+
];
50+
}
51+
2352
/**
2453
* Yaml encode.
2554
*
@@ -30,4 +59,27 @@ public function yamlEncode($value): string {
3059
return Yaml::dump($value);
3160
}
3261

62+
/**
63+
* Render webform elements.
64+
*/
65+
public function renderWebformElements(array $elements): string {
66+
$webform = Webform::create([
67+
'id' => (new Random())->name(32),
68+
'elements' => Yaml::dump($elements),
69+
]);
70+
71+
// Hack: Needed to prevent an error in the webform module.
72+
$prop = new \ReflectionProperty($webform, 'settingsOriginal');
73+
$prop->setAccessible(TRUE);
74+
$prop->setValue($webform, []);
75+
76+
$submissionForm = $webform->getSubmissionForm();
77+
$content = $this->renderer->render($submissionForm);
78+
79+
// Make sure that the form cannot be submitted (hopefully).
80+
$content = str_replace('<form', '<form onsubmit="return false"', $content);
81+
82+
return $content;
83+
}
84+
3385
}

templates/os2forms-sync-webform-index.html.twig

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,56 @@
11
{{ attach_library('os2forms_sync/webform-index') }}
22

33
<section class="os2forms-sync-webform-index">
4-
<h1>{{ 'Webforms'|t }}</h1>
4+
<h1>{{ 'Import webform'|t }}</h1>
55
{% if webforms %}
66
<div>
7-
<input type="search" class="form-element form-autocomplete" placeholder="{{ 'Search …'|t }}" />
7+
<input type="search" class="form-element form-autocomplete" placeholder="{{ 'Search title, description and category '|t }}" />
88
</div>
9-
<form method="post">
10-
{% for webform in webforms %}
11-
<div class="os2forms-sync-webform">
12-
<h2>{{ webform.attributes.title|raw }}</h2>
13-
<div class="description">
9+
{% for webform in webforms %}
10+
<fieldset class="form-item os2forms-sync-webform">
11+
<legend class="fieldset__legend">
12+
<h2 class="fieldset__label">{{ webform.attributes.title|raw }}</h2>
13+
</legend>
14+
15+
<div class="fieldset__wrapper">
16+
<div class="description" data-indexed="{{webform.attributes.description|striptags}}">
1417
{{ webform.attributes.description|raw }}
1518
</div>
16-
<div class="category">
17-
{{ webform.attributes.category }}
18-
</div>
1919

20-
<details>
21-
<summary>{{ 'Elements'|t }}</summary>
20+
<div>
21+
<details class="form-wrapper claro-details">
22+
<summary class="claro-details__summary">{{ 'Form display'|t }}</summary>
23+
24+
<div class="claro-details__wrapper details-wrapper">
25+
{{ render_webform_elements(webform.attributes.elements)|raw }}
26+
</div>
27+
</details>
28+
29+
<details class="container-inline js-form-wrapper form-wrapper claro-details">
30+
<summary class="claro-details__summary">{{ 'Elements'|t }}</summary>
31+
32+
<div class="claro-details__wrapper details-wrapper">
33+
<pre>{{ webform.attributes.elements|yaml_encode }}</pre>
34+
</div>
35+
</details>
36+
</div>
2237

23-
<pre>{{ webform.attributes.elements|yaml_encode }}</pre>
24-
</details>
38+
<div class="form-item metadata">
39+
<div class="category" data-indexed="{{webform.attributes.category|striptags}}">
40+
<span class="label">{{ 'Category'|t }}</span> {{ webform.attributes.category }}
41+
</div>
2542

26-
<div class="source">
27-
<a href="{{ webform.links.self }}">{{ webform.links.self }}</a>
43+
<div class="source" data-indexed="{{webform.links.self|striptags}}">
44+
<a href="{{ webform.links.self }}">{{ webform.links.self }}</a>
45+
</div>
2846
</div>
2947

30-
<button class="button" formaction="{{ path('os2forms_sync.webform.import', {url: webform.links.self}) }}">{{ 'Import webform'|t }}</button>
48+
<form method="post">
49+
<button class="button" formaction="{{ path('os2forms_sync.webform.import', {url: webform.links.self}) }}">{{ 'Import webform'|t }}</button>
50+
</form>
3151
</div>
32-
{% endfor %}
33-
</form>
52+
</fieldset>
53+
{% endfor %}
3454
{% else %}
3555
<div class="alert alert-warning">{{ 'No webforms'|t }}</div>
3656
{% endif %}

0 commit comments

Comments
 (0)