19declare(strict_types=1);
48 return $default_renderer->render($component->getInputs());
52 return $this->
renderMode($component, $default_renderer);
61 $tpl = $this->
getTemplate(
"tpl.viewcontrol_fieldselection.html",
true,
true);
64 $set_values = $component->
getValue() ?? [];
65 foreach ($component->
getOptions() as $opt_value => $opt_label) {
66 $tpl->setCurrentBlock(
"option");
68 $tpl->setVariable(
"OPTION_VALUE", $opt_value);
69 $tpl->setVariable(
"OPTION_LABEL", $opt_label);
70 if (in_array($opt_value, $set_values)) {
71 $tpl->setVariable(
"CHECKED",
'checked');
73 $tpl->parseCurrentBlock();
75 if (in_array($opt_value, $set_values)) {
76 $tpl->setCurrentBlock(
"value");
77 $tpl->setVariable(
"NAME", $component->
getName());
78 $tpl->setVariable(
"VALUE", $opt_value);
79 $tpl->parseCurrentBlock();
84 $param_name = $component->
getName();
87 fn(
$id) =>
"il.UI.Input.Viewcontrols.FieldSelection.init(
88 document.getElementById('{$id}'),
90 '{$container_submit_signal}',
96 $component = $component
99 "$('#{$id} > .dropdown-menu').on('click', (event) => event.stopPropagation());"
100 )->withAdditionalOnLoadCode(
102 "il.UI.dropdown.init(document.getElementById('{$id}'));"
109 $button = $ui_factory->button()->standard($button_label,
'#')
110 ->withOnClick($internal_signal);
112 $tpl->setVariable(
'ID',
$id);
113 $tpl->setVariable(
"ID_MENU",
$id .
'_ctrl');
114 $tpl->setVariable(
"ARIA_LABEL", $this->
txt(self::DEFAULT_DROPDOWN_LABEL));
115 $tpl->setVariable(
"BUTTON", $default_renderer->render($button));
122 $tpl = $this->
getTemplate(
"tpl.viewcontrol_sortation.html",
true,
true);
125 foreach ($component->
getOptions() as $opt_label => $order) {
126 $opt_value = $order->join(
':', fn($ret, $key, $value) => [$key, $value]);
128 $internal_signal->addOption(
'value', $opt_value);
129 $item = $ui_factory->button()->shy((
string) $opt_label,
'#')
130 ->withOnClick($internal_signal);
131 $tpl->setCurrentBlock(
"option");
132 $tpl->setVariable(
"OPTION", $default_renderer->render($item));
134 if ($opt_value === $component->
getValue()) {
135 $tpl->touchBlock(
"selected");
136 $tpl->setCurrentBlock(
"option");
138 $tpl->parseCurrentBlock();
143 fn(
$id) =>
"il.UI.Input.Viewcontrols.Sortation.init(
144 document.getElementById('{$id}'),
145 '{$internal_signal}',
146 '{$container_submit_signal}',
152 fn(
$id) =>
"il.UI.dropdown.init(document.getElementById('{$id}'));"
157 $tpl->setVariable(
'ID',
$id);
158 $tpl->setVariable(
"ID_MENU",
$id .
'_ctrl');
159 $tpl->setVariable(
"ARIA_LABEL", $this->
txt(self::DEFAULT_SORTATION_DROPDOWN_LABEL));
163 $default_renderer->render(
179 if ($page_limit >= $total_count) {
180 return [$data_factory->range(0, $page_limit)];
182 foreach (range(0, $total_count - 1, $page_limit) as $idx => $start) {
183 $ranges[] = $data_factory->range($start, $page_limit);
193 foreach ($ranges as $idx =>
$range) {
194 if ($offset >=
$range->
getStart() && $offset < $range->getEnd()) {
198 throw new LogicException(
'offset is not in any range');
207 $first = reset($ranges);
208 $last = end($ranges);
210 $start = max(0, $current - floor(($number_of_visible_entries - 1) / 2));
211 if ($start + $number_of_visible_entries >= count($ranges)) {
212 $start = max(0, count($ranges) - $number_of_visible_entries);
215 $entries = array_slice($ranges, (
int) $start, $number_of_visible_entries);
217 if (! in_array($first, $entries)) {
218 array_shift($entries);
219 array_unshift($entries, $first);
221 if (! in_array($last, $entries)) {
223 array_push($entries, $last);
230 $tpl = $this->getTemplate(
"tpl.viewcontrol_pagination.html",
true,
true);
231 $ui_factory = $this->getUIFactory();
237 $limit = $limit > 0 ? $limit : reset($limit_options);
238 $offset = $offset >= $total_count ? 0 : $offset;
240 if (! $total_count) {
241 $input = $ui_factory->input()->field()->numeric(
'offset')->withValue($offset);
242 $apply = $ui_factory->button()->standard(
'apply',
'');
243 $tpl->setVariable(
"INPUT", $default_renderer->render($input));
244 $tpl->setVariable(
"BUTTON", $default_renderer->render($apply));
246 $ranges = $this->buildRanges($total_count, $limit);
247 $current = $this->findCurrentPage($ranges, $offset);
249 if ($limit >= $total_count) {
255 if (count($entries) > 1) {
256 foreach ($ranges as $idx =>
$range) {
257 if (in_array(
$range, $entries)) {
258 $signal = clone $internal_signal;
260 $signal->addOption(
'limit', $limit);
261 $tpl->setCurrentBlock(
"entry");
262 $entry = $ui_factory->button()->shy((
string) ($idx + 1),
'#')->withOnClick($signal);
263 if ($idx === $current) {
264 $entry = $entry->withEngagedState(
true);
266 $tpl->setVariable(
"ENTRY", $default_renderer->render($entry));
267 $tpl->parseCurrentBlock();
268 } elseif ($idx === 1 || $idx === count($ranges) - 2) {
269 $tpl->setCurrentBlock(
"entry");
270 $tpl->touchBlock(
"spacer");
271 $tpl->parseCurrentBlock();
276 $range = $ranges[$current - 1];
277 $signal = clone $internal_signal;
279 $signal->addOption(
'limit', $limit);
280 $btn_left = $ui_factory->button()->shy(
'', $signal ??
'#')
281 ->withSymbol($ui_factory->symbol()->glyph()->back());
282 $tpl->setVariable(
"LEFT_ROCKER", $default_renderer->render($btn_left));
285 if ($current < count($ranges) - 1) {
286 $range = $ranges[$current + 1];
287 $signal = clone $internal_signal;
289 $signal->addOption(
'limit', $limit);
290 $btn_right = $ui_factory->button()->shy(
'', $signal ??
'#')
291 ->withSymbol($ui_factory->symbol()->glyph()->next());
292 $tpl->setVariable(
"RIGHT_ROCKER", $default_renderer->render($btn_right));
298 $signal = clone $internal_signal;
299 $signal->addOption(
'offset', $offset);
300 $signal->addOption(
'limit', (
string) $option);
301 $option_label = $option === \PHP_INT_MAX ? $this->txt(
'ui_pagination_unlimited') : (string) $option;
303 $item = $ui_factory->button()->shy($option_label,
'#')
304 ->withOnClick($signal);
305 $tpl->setCurrentBlock(
"option_limit");
306 $tpl->setVariable(
"OPTION_LIMIT", $default_renderer->render($item));
307 if ($option === $limit) {
308 $tpl->touchBlock(
"selected");
309 $tpl->setCurrentBlock(
"option_limit");
311 $tpl->parseCurrentBlock();
316 fn(
$id) =>
"il.UI.Input.Viewcontrols.Pagination.init(
317 document.getElementById('{$id}'),
318 '{$internal_signal}',
319 '{$container_submit_signal}',
327 document.getElementById('{$id}').querySelector(
328 '.dropdown.il-viewcontrol-pagination__num-of-items'
333 $id = $this->bindJavaScript($component);
335 $tpl->setVariable(
'ID',
$id);
336 $tpl->setVariable(
"ID_MENU_OFFSET",
$id .
'_ctrl_offset');
337 $tpl->setVariable(
"ARIA_LABEL_OFFSET", $this->txt(self::DEFAULT_DROPDOWN_LABEL_OFFSET));
338 $tpl->setVariable(
"ID_MENU_LIMIT",
$id .
'_ctrl_limit');
339 $tpl->setVariable(
"ARIA_LABEL_LIMIT", $this->txt(self::DEFAULT_DROPDOWN_LABEL_LIMIT));
343 $default_renderer->render(
352 protected function renderMode(
Mode $component, RendererInterface $default_renderer): string
354 $tpl = $this->getTemplate(
"tpl.viewcontrol_mode.html",
true,
true);
355 $ui_factory = $this->getUIFactory();
359 $set_value = $component->
getValue() ?? array_key_first($options);
362 foreach ($options as $opt_value => $opt_label) {
363 $out[] = $ui_factory->button()->standard($opt_label,
'#')
364 ->withEngagedState($opt_value === $set_value)
366 static fn(
$id):
string =>
367 "il.UI.Input.Viewcontrols.Mode.init(
368 document.getElementById('{$id}'),
370 '{$container_submit_signal}',
374 $tpl->setVariable(
'BUTTONS', $default_renderer->render(
$out));
375 $tpl->setVariable(
'VALUE', $set_value);
376 $tpl->setVariable(
"NAME", $component->
getName());
377 $tpl->setVariable(
"ARIA_LABEL", $this->txt(self::DEFAULT_MODE_LABEL));
379 $id = $this->bindJavaScript($component);
388 parent::registerResources($registry);
389 $registry->
register(
'assets/js/dropdown.js');
390 $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.
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.