ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
class.ilOrgUnitGenericMultiInputGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\UI\Factory as UIFactory;
22use ILIAS\UI\Renderer as UIRenderer;
24
31{
32 public const HOOK_IS_LINE_REMOVABLE = "hook_is_line_removable";
33 public const HOOK_IS_INPUT_DISABLED = "hook_is_disabled";
34 public const HOOK_BEFORE_INPUT_RENDER = "hook_before_render";
35
36 public const MULTI_FIELD_ID = "id";
37 public const MULTI_FIELD_OVER = "over";
38 public const MULTI_FIELD_SCOPE = "scope";
39
40 protected array $cust_attr = [];
41 protected $value;
42 protected array $inputs = [];
43 protected array $input_options = [];
44 protected array $hooks = [];
45 protected array $line_values = [];
46 protected string $template_dir = '';
47 protected array $post_var_cache = [];
48 protected bool $show_label = false;
49 protected bool $show_label_once = false;
50 protected array $hidden_inputs = [];
51 protected int $counter = 0;
52 protected bool $show_info = false;
53 protected bool $render_one_for_empty_value = true;
54
55 protected UIFactory $ui_factory;
56 protected UIRenderer $ui_renderer;
57
58 public function __construct(string $a_title = "", string $a_postvar = "")
59 {
60 parent::__construct($a_title, $a_postvar);
61 $this->setType("line_select");
62 $this->setMulti(true);
63 $this->initCSSandJS();
64
65 global $DIC;
66 $this->ui_factory = $DIC['ui.factory'];
67 $this->ui_renderer = $DIC['ui.renderer'];
68 }
69
70 public function getHook(string $key)
71 {
72 return $this->hooks[$key] ?? false;
73 }
74
75 public function addHook(string $key, array $options): void
76 {
77 $this->hooks[$key] = $options;
78 }
79
80 public function removeHook(string $key): bool
81 {
82 if (isset($this->hooks[$key])) {
83 unset($this->hooks[$key]);
84
85 return true;
86 }
87
88 return false;
89 }
90
91 public function addInput(\ilFormPropertyGUI $input, array $options = []): void
92 {
93 $this->inputs[$input->getPostVar()] = $input;
94 $this->input_options[$input->getPostVar()] = $options;
95 $this->counter++;
96 }
97
98 public function getTemplateDir(): string
99 {
100 return $this->template_dir;
101 }
102
103 public function setTemplateDir(string $template_dir): void
104 {
105 $this->template_dir = $template_dir;
106 }
107
108 public function isShowLabel(): bool
109 {
110 return $this->show_label;
111 }
112
113 public function setShowLabel(bool $show_label): void
114 {
115 $this->show_label = $show_label;
116 }
117
122 public function getInputs(): array
123 {
124 return $this->inputs;
125 }
126
127 #[\Override]
128 public function setMulti(bool $a_multi, bool $a_sortable = false, bool $a_addremove = true): void
129 {
130 $this->multi = $a_multi;
131 }
132
133 public function setValue(array $value): void
134 {
135 $this->value = $value;
136
137 foreach ($this->inputs as $key => $item) {
138 if ($item instanceof \ilDateTimeInputGUI) {
139 $item->setDate(new \ilDate($value[$key]['date'], IL_CAL_DATE));
140 } elseif (array_key_exists($key, $value)) {
141 $item->setValue((string) $value[$key]);
142 }
143 }
144 }
145
146 public function getValue(): array
147 {
148 $out = [];
149 foreach ($this->inputs as $key => $item) {
150 $out[$key] = $item->getValue();
151 }
152
153 return $out;
154 }
155
156 public function setValueByArray(array $a_values): void
157 {
158 $data = $a_values[$this->getPostVar()] ?? [];
159 if ($this->getMulti()) {
160 $this->line_values = $data;
161 } else {
162 $this->setValue($data);
163 }
164 }
165
170 #[\Override]
171 public function checkInput(): bool
172 {
173 $key = $this->getPostVar();
174 $post = $this->raw($key);
175
176 if (is_array($post)) {
177 foreach ($post as $authority) {
178 if (!(
179 array_key_exists(self::MULTI_FIELD_ID, $authority) &&
180 array_key_exists(self::MULTI_FIELD_OVER, $authority) &&
181 array_key_exists(self::MULTI_FIELD_SCOPE, $authority) &&
182 trim((string) $authority[self::MULTI_FIELD_OVER]) !== '' &&
183 trim((string) $authority[self::MULTI_FIELD_SCOPE]) !== ''
184 )) {
185 $this->setAlert($this->lng->txt("msg_input_is_required"));
186 return false;
187 }
188 }
189 }
190
191 return true;
192 }
193
194 public function addCustomAttribute(string $key, string $value, bool $override = false): void
195 {
196 if (isset($this->cust_attr[$key]) && !$override) {
197 $this->cust_attr[$key] .= ' ' . $value;
198 } else {
199 $this->cust_attr[$key] = $value;
200 }
201 }
202
203 public function getCustomAttributes(): array
204 {
205 return $this->cust_attr;
206 }
207
208 private function createInputPostVar(string $iterator_id, \ilFormPropertyGUI $input): string
209 {
210 if ($this->getMulti()) {
211 return $this->getPostVar() . '[' . $iterator_id . '][' . $input->getPostVar() . ']';
212 }
213 return $this->getPostVar() . '[' . $input->getPostVar() . ']';
214 }
215
216 public function render(int|string $iterator_id = 0, bool $clean_render = false): string
217 {
218 $first_label = true;
219 $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
220
221 $class = 'multi_input_line';
222 $this->addCustomAttribute('class', $class, true);
223 foreach ($this->getCustomAttributes() as $key => $value) {
224 $tpl->setCurrentBlock('cust_attr');
225 $tpl->setVariable('CUSTOM_ATTR_KEY', $key);
226 $tpl->setVariable('CUSTOM_ATTR_VALUE', $value);
227 $tpl->parseCurrentBlock();
228 }
230 foreach ($inputs as $key => $input) {
231 $input = clone $input;
232 $is_hidden = false;
233 $is_ta = false;
234 if (!method_exists($input, 'render')) {
235 switch (true) {
236 case ($input instanceof \ilHiddenInputGUI):
237 $is_hidden = true;
238 break;
239 case ($input instanceof \ilTextAreaInputGUI):
240 $is_ta = true;
241 break;
242 default:
243 throw new \ilException(
244 "Method " . $input::class
245 . "::render() does not exists! You cannot use this input-type in ilMultiLineInputGUI"
246 );
247 }
248 }
249
250 $is_disabled_hook = $this->getHook(self::HOOK_IS_INPUT_DISABLED);
251 if ($is_disabled_hook !== false && !$clean_render) {
252 $input->setDisabled($is_disabled_hook($this->getValue()));
253 }
254 if ($this->getDisabled()) {
255 $input->setDisabled(true);
256 }
257 if ($iterator_id == 0 && !isset($this->post_var_cache[$key])) {
258 $this->post_var_cache[$key] = $input->getPostVar();
259 } else {
260 // Reset post var
261 $input->setPostVar($this->post_var_cache[$key]);
262 }
263 $post_var = $this->createInputPostVar((string) $iterator_id, $input);
264 $input->setPostVar($post_var);
265 $before_render_hook = $this->getHook(self::HOOK_BEFORE_INPUT_RENDER);
266 if ($before_render_hook !== false && !$clean_render) {
267 $input = $before_render_hook($this->getValue(), $key, $input);
268 }
269 switch (true) {
270 case $is_hidden:
271 $tpl->setCurrentBlock('hidden');
272 $tpl->setVariable('NAME', $post_var);
273 $tpl->setVariable('VALUE', ilLegacyFormElementsUtil::prepareFormOutput($input->getValue()));
274 break;
275 case $is_ta:
276 if ($this->isShowLabel() || ($this->isShowLabelOnce() && $first_label)) {
277 $tpl->setCurrentBlock('input_label');
278 $tpl->setVariable('LABEL', $input->getTitle());
279 $tpl->setVariable('CONTENT', $input->getHTML());
280 $tpl->parseCurrentBlock();
281 $first_label = false;
282 } else {
283 $tpl->setCurrentBlock('input');
284 $tpl->setVariable('CONTENT', $input->getHTML());
285 }
286 break;
287 default:
288 if ($this->isShowLabel() || ($this->isShowLabelOnce() && $first_label)) {
289 $tpl->setCurrentBlock('input_label');
290 $tpl->setVariable('LABEL', $input->getTitle());
291 $tpl->setVariable('CONTENT', $input->render());
292 $first_label = false;
293 } else {
294 $tpl->setCurrentBlock('input');
295 $tpl->setVariable('CONTENT', $input->render());
296 }
297 break;
298 }
299 if ($this->isShowInfo()) {
300 if ($this->isShowLabel()) {
301 $tpl->setCurrentBlock('input_info_label');
302 $tpl->setVariable('INFO_LABEL', $input->getInfo());
303 $tpl->parseCurrentBlock();
304 } else {
305 $tpl->setCurrentBlock('input_info');
306 $tpl->setVariable('INFO', $input->getInfo());
307 $tpl->parseCurrentBlock();
308 }
309 }
310 $tpl->parseCurrentBlock();
311 }
312 if ($this->getMulti() && !$this->getDisabled()) {
313 $is_removeable_hook = $this->getHook(self::HOOK_IS_LINE_REMOVABLE);
314 if ($is_removeable_hook !== false && !$clean_render) {
315 $show_remove = $is_removeable_hook($this->getValue());
316 }
317 $tpl->setCurrentBlock('multi_icons');
318 $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
319 $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
320 $tpl->parseCurrentBlock();
321 }
322
323 return $tpl->get();
324 }
325
326 public function initCSSandJS(): void
327 {
328 $this->global_tpl->addJavascript('assets/js/generic_multi_line_input.js');
329 }
330
335 public function insert(\ilTemplate $a_tpl): void
336 {
337 $output = "";
338
339 $output .= $this->render(0, true);
340 if ($this->getMulti() && is_array($this->line_values) && count($this->line_values) > 0) {
341 $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
342 $tpl->setVariable('ADDITIONAL_ATTRS', "id='multi_line_add_button' style='display:none'");
343 $tpl->setCurrentBlock('multi_icons');
344 $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
345 $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
346 $tpl->parseCurrentBlock();
347 $output .= $tpl->get();
348 foreach ($this->line_values as $run => $data) {
349 $object = $this;
350 $object->setValue($data);
351 $output .= $object->render($run);
352 }
353 } elseif ($this->render_one_for_empty_value) {
354 $output .= $this->render(0, true);
355 } else {
356 $tpl = new ilTemplate("tpl.prop_generic_multi_line.html", true, true, 'components/ILIAS/OrgUnit');
357 $tpl->setVariable('ADDITIONAL_ATTRS', "id='multi_line_add_button'");
358 $tpl->setCurrentBlock('multi_icons');
359 $tpl->setVariable('IMAGE_PLUS', $this->getGlyph('add'));
360 $tpl->setVariable('IMAGE_MINUS', $this->getGlyph('remove'));
361
362 $tpl->parseCurrentBlock();
363 $output .= $tpl->get();
364 }
365 if ($this->getMulti()) {
366 $output = "<div style=\"display:none;\" id='{$this->getFieldId()}' class='multi_line_input'>{$output}</div>";
367 $config = json_encode($this->input_options);
368 $options = json_encode([
369 'limit' => 999999,
370 'sortable' => false,
371 'locale' => $this->lng->getLangKey()
372 ]);
373 global $tpl;
374 $tpl->addOnLoadCode(
375 "
376 il.DataCollection.genericMultiLineInit('{$this->getFieldId()}',$config,$options);
377 document.body.querySelector('#{$this->getFieldId()}').removeAttribute('style');
378 "
379 );
380 }
381
382 $a_tpl->setCurrentBlock("prop_generic");
383 $a_tpl->setVariable("PROP_GENERIC", $output);
384 $a_tpl->parseCurrentBlock();
385 }
386
390 public function getTableFilterHTML(): string
391 {
392 return $this->render();
393 }
394
398 public function getToolbarHTML(): string
399 {
400 return $this->render("toolbar");
401 }
402
403 public function isShowLabelOnce(): bool
404 {
406 }
407
408 public function setShowLabelOnce(bool $show_label_once): void
409 {
410 $this->setShowLabel(false);
411 $this->show_label_once = $show_label_once;
412 }
413
414 public function isShowInfo(): bool
415 {
416 return $this->show_info;
417 }
418
419 public function setShowInfo(bool $show_info): void
420 {
421 $this->show_info = $show_info;
422 }
423
424 public function isRenderOneForEmptyValue(): bool
425 {
427 }
428
430 {
431 $this->render_one_for_empty_value = $render_one_for_empty_value;
432 }
433
434 private function getGlyph(string $which): string
435 {
436 $symbol = $this->ui_factory->symbol()->glyph()->$which();
437
439 $symbol = $symbol
440 ->withAdditionalOnLoadCode(
441 fn($id): string => "document.getElementById('" . $id . "').classList.add('{$which}_button');"
442 );
443
444 return $this->ui_renderer->render($symbol);
445 }
446}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$out
Definition: buildRTE.php:24
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
const IL_CAL_DATE
This class represents a date/time property in a property form.
Class for single dates.
This class represents a property in a property form.
This class represents a hidden form property in a property form.
static prepareFormOutput($a_str, bool $a_strip=false)
__construct(string $a_title="", string $a_postvar="")
setRenderOneForEmptyValue(bool $render_one_for_empty_value)
setMulti(bool $a_multi, bool $a_sortable=false, bool $a_addremove=true)
insert(\ilTemplate $a_tpl)
Insert property html.
addInput(\ilFormPropertyGUI $input, array $options=[])
addCustomAttribute(string $key, string $value, bool $override=false)
render(int|string $iterator_id=0, bool $clean_render=false)
createInputPostVar(string $iterator_id, \ilFormPropertyGUI $input)
special template class to simplify handling of ITX/PEAR
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
This class represents a text area property in a property form.
An entity that renders components to a string output.
Definition: Renderer.php:31
$post
Definition: ltitoken.php:46
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26