19declare(strict_types=1);
52 return $default_renderer->render($component->getInputs());
56 return $this->
renderMode($component, $default_renderer);
65 $tpl = $this->
getTemplate(
"tpl.viewcontrol_fieldselection.html",
true,
true);
68 $set_values = $component->
getValue() ?? [];
69 foreach ($component->
getOptions() as $opt_value => $opt_label) {
70 $tpl->setCurrentBlock(
"option");
72 $tpl->setVariable(
"OPTION_VALUE", $opt_value);
73 $tpl->setVariable(
"OPTION_LABEL", $opt_label);
74 if (in_array($opt_value, $set_values)) {
75 $tpl->setVariable(
"CHECKED",
'checked');
77 $tpl->parseCurrentBlock();
79 if (in_array($opt_value, $set_values)) {
80 $tpl->setCurrentBlock(
"value");
81 $tpl->setVariable(
"NAME", $component->
getName());
82 $tpl->setVariable(
"VALUE", $opt_value);
83 $tpl->parseCurrentBlock();
88 $param_name = $component->
getName();
91 fn(
$id) =>
"il.UI.Input.Viewcontrols.FieldSelection.init(
92 document.getElementById('{$id}'),
94 '{$container_submit_signal}',
100 $component = $component
103 "$('#{$id} > .dropdown-menu').on('click', (event) => event.stopPropagation());"
104 )->withAdditionalOnLoadCode(
106 "il.UI.dropdown.init(document.getElementById('{$id}'));"
113 $button = $ui_factory->button()->standard($button_label,
'#')
114 ->withOnClick($internal_signal);
116 $tpl->setVariable(
'ID',
$id);
117 $tpl->setVariable(
"ID_MENU",
$id .
'_ctrl');
118 $tpl->setVariable(
"ARIA_LABEL", $this->
txt(self::DEFAULT_DROPDOWN_LABEL));
119 $tpl->setVariable(
"BUTTON", $default_renderer->render($button));
126 $tpl = $this->
getTemplate(
"tpl.viewcontrol_sortation.html",
true,
true);
129 foreach ($component->
getOptions() as $opt_label => $order) {
130 $opt_value = $order->join(
':', fn($ret, $key, $value) => [$key, $value]);
132 $internal_signal->addOption(
'value', $opt_value);
133 $item = $ui_factory->button()->shy((
string) $opt_label,
'#')
134 ->withOnClick($internal_signal);
135 $tpl->setCurrentBlock(
"option");
136 $tpl->setVariable(
"OPTION", $default_renderer->render($item));
138 if ($opt_value === $component->
getValue()) {
139 $tpl->touchBlock(
"selected");
140 $tpl->setCurrentBlock(
"option");
142 $tpl->parseCurrentBlock();
147 fn(
$id) =>
"il.UI.Input.Viewcontrols.Sortation.init(
148 document.getElementById('{$id}'),
149 '{$internal_signal}',
150 '{$container_submit_signal}',
156 fn(
$id) =>
"il.UI.dropdown.init(document.getElementById('{$id}'));"
161 $tpl->setVariable(
'ID',
$id);
162 $tpl->setVariable(
"ID_MENU",
$id .
'_ctrl');
163 $tpl->setVariable(
"ARIA_LABEL", $this->
txt(self::DEFAULT_SORTATION_DROPDOWN_LABEL));
167 $default_renderer->render(
183 if ($page_limit >= $total_count) {
184 return [$data_factory->range(0, $page_limit)];
186 foreach (range(0, $total_count - 1, $page_limit) as $idx => $start) {
187 $ranges[] = $data_factory->range($start, $page_limit);
197 foreach ($ranges as $idx =>
$range) {
198 if ($offset >=
$range->
getStart() && $offset < $range->getEnd()) {
202 throw new LogicException(
'offset is not in any range');
211 $first = reset($ranges);
212 $last = end($ranges);
214 $start = max(0, $current - floor(($number_of_visible_entries - 1) / 2));
215 if ($start + $number_of_visible_entries >= count($ranges)) {
216 $start = max(0, count($ranges) - $number_of_visible_entries);
219 $entries = array_slice($ranges, (
int) $start, $number_of_visible_entries);
221 if (! in_array($first, $entries)) {
222 array_shift($entries);
223 array_unshift($entries, $first);
225 if (! in_array($last, $entries)) {
227 array_push($entries, $last);
234 $tpl = $this->getTemplate(
"tpl.viewcontrol_pagination.html",
true,
true);
235 $ui_factory = $this->getUIFactory();
241 $limit = $limit > 0 ? $limit : reset($limit_options);
242 $offset = $offset >= $total_count ? 0 : $offset;
244 if (! $total_count) {
245 $input = $ui_factory->input()->field()->numeric(
'offset')->withValue($offset);
246 $apply = $ui_factory->button()->standard(
'apply',
'');
247 $tpl->setVariable(
"INPUT", $default_renderer->render($input));
248 $tpl->setVariable(
"BUTTON", $default_renderer->render($apply));
250 $ranges = $this->buildRanges($total_count, $limit);
251 $current = $this->findCurrentPage($ranges, $offset);
253 if ($limit >= $total_count) {
259 if (count($entries) > 1) {
260 foreach ($ranges as $idx =>
$range) {
261 if (in_array(
$range, $entries)) {
262 $signal = clone $internal_signal;
264 $signal->addOption(
'limit', $limit);
265 $tpl->setCurrentBlock(
"entry");
266 $entry = $ui_factory->button()->shy((
string) ($idx + 1),
'#')->withOnClick($signal);
267 if ($idx === $current) {
268 $entry = $entry->withEngagedState(
true);
270 $tpl->setVariable(
"ENTRY", $default_renderer->render($entry));
271 $tpl->parseCurrentBlock();
272 } elseif ($idx === 1 || $idx === count($ranges) - 2) {
273 $tpl->setCurrentBlock(
"entry");
274 $tpl->touchBlock(
"spacer");
275 $tpl->parseCurrentBlock();
280 $range = $ranges[$current - 1];
281 $signal = clone $internal_signal;
283 $signal->addOption(
'limit', $limit);
284 $btn_left = $ui_factory->button()->shy(
'', $signal ??
'#')
285 ->withSymbol($ui_factory->symbol()->glyph()->back());
286 $tpl->setVariable(
"LEFT_ROCKER", $default_renderer->render($btn_left));
289 if ($current < count($ranges) - 1) {
290 $range = $ranges[$current + 1];
291 $signal = clone $internal_signal;
293 $signal->addOption(
'limit', $limit);
294 $btn_right = $ui_factory->button()->shy(
'', $signal ??
'#')
295 ->withSymbol($ui_factory->symbol()->glyph()->next());
296 $tpl->setVariable(
"RIGHT_ROCKER", $default_renderer->render($btn_right));
302 $signal = clone $internal_signal;
303 $signal->addOption(
'offset', $offset);
304 $signal->addOption(
'limit', (
string) $option);
305 $option_label = $option === \PHP_INT_MAX ? $this->txt(
'ui_pagination_unlimited') : (string) $option;
307 $item = $ui_factory->button()->shy($option_label,
'#')
308 ->withOnClick($signal);
309 $tpl->setCurrentBlock(
"option_limit");
310 $tpl->setVariable(
"OPTION_LIMIT", $default_renderer->render($item));
311 if ($option === $limit) {
312 $tpl->touchBlock(
"selected");
313 $tpl->setCurrentBlock(
"option_limit");
315 $tpl->parseCurrentBlock();
320 fn(
$id) =>
"il.UI.Input.Viewcontrols.Pagination.init(
321 document.getElementById('{$id}'),
322 '{$internal_signal}',
323 '{$container_submit_signal}',
331 document.getElementById('{$id}').querySelector(
332 '.dropdown.il-viewcontrol-pagination__num-of-items'
337 $id = $this->bindJavaScript($component);
339 $tpl->setVariable(
'ID',
$id);
340 $tpl->setVariable(
"ID_MENU_OFFSET",
$id .
'_ctrl_offset');
341 $tpl->setVariable(
"ARIA_LABEL_OFFSET", $this->txt(self::DEFAULT_DROPDOWN_LABEL_OFFSET));
342 $tpl->setVariable(
"ID_MENU_LIMIT",
$id .
'_ctrl_limit');
343 $tpl->setVariable(
"ARIA_LABEL_LIMIT", $this->txt(self::DEFAULT_DROPDOWN_LABEL_LIMIT));
347 $default_renderer->render(
356 protected function renderMode(
Mode $component, RendererInterface $default_renderer): string
358 $tpl = $this->getTemplate(
"tpl.viewcontrol_mode.html",
true,
true);
359 $ui_factory = $this->getUIFactory();
366 foreach (
$options as $opt_value => $opt_label) {
367 $out[] = $ui_factory->button()->standard($opt_label,
'#')
368 ->withEngagedState($opt_value === $set_value)
370 static fn(
$id):
string =>
371 "il.UI.Input.Viewcontrols.Mode.init(
372 document.getElementById('{$id}'),
374 '{$container_submit_signal}',
378 $tpl->setVariable(
'BUTTONS', $default_renderer->render(
$out));
379 $tpl->setVariable(
'VALUE', $set_value);
380 $tpl->setVariable(
"NAME", $component->
getName());
381 $tpl->setVariable(
"ARIA_LABEL", $this->txt(self::DEFAULT_MODE_LABEL));
383 $id = $this->bindJavaScript($component);
392 parent::registerResources($registry);
393 $registry->
register(
'assets/js/dropdown.js');
394 $registry->
register(
'assets/js/input.viewcontrols.min.js');
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Base class for all component renderers.
cannotHandleComponent(Component $component)
This method MUST be called by derived component renderers, if.
txt(string $id)
Get a text from the language file.
createId()
Get a fresh unique id.
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.
addTriggererOnLoadCode(Triggerer $triggerer)
Add onload-code for triggerer.
getUIFactory()
Get a UI factory.
getTemplate(string $name, bool $purge_unfilled_vars, bool $purge_unused_blocks)
Get template of component this renderer is made for.
withAdditionalOnLoadCode(Closure $binder)
Add some onload-code to the component instead of replacing the existing one.
Registry for resources required by rendered output like Javascript or CSS.
register(string $name)
Add a dependency.
An entity that renders components to a string output.