Improved StructuralEntityType rendering on frontend.

This commit is contained in:
Jan Böhmer 2022-07-26 23:07:04 +02:00
parent 41b1d8b59e
commit 8c450599cb
5 changed files with 74 additions and 35 deletions

View file

@ -69,8 +69,6 @@ body {
/*noinspection CssUnknownProperty*/
scrollbar-width: none;
}
}
/*noinspection W3CssValidation*/
@ -852,4 +850,19 @@ div.dataTables_wrapper div.dataTables_info {
***********************************************/
.typeahead-image {
width: 100%;
}
/***********************************************
* Special level whitespace characters that only show up when inside a bootstrap-select dropdown
***********************************************/
.dropdown-item span.picker-level::after {
content: "\00a0\00a0\00a0"; /* 3 spaces */
}
/** Bootstrap-select Hide on Selected element */
.picker-hs {
display: none;
}
.dropdown-item .picker-hs {
display: inherit;
}

View file

@ -181,6 +181,7 @@ class AjaxUI {
ajaxUI.initTree("#" + target_id, 'tree/tools');
break;
case "devices":
ajaxUI.initTree("#" + target_id, 'tree/devices');
ajaxUI.initTree("#" + target_id, 'tree/devices');
break;
}

View file

@ -82,6 +82,7 @@ class PricedetailType extends AbstractType
$builder->add('currency', CurrencyEntityType::class, [
'required' => false,
'label' => false,
'short' => true,
]);
}

View file

@ -42,6 +42,7 @@ declare(strict_types=1);
namespace App\Form\Type;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\PriceInformations\Currency;
use App\Services\Trees\NodesListBuilder;
@ -50,6 +51,9 @@ use Symfony\Component\Intl\Currencies;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* An entity to select a currency shortly
*/
class CurrencyEntityType extends StructuralEntityType
{
protected $base_currency;
@ -82,51 +86,41 @@ class CurrencyEntityType extends StructuralEntityType
return Currencies::getSymbol($iso_code);
});
$resolver->setDefault('used_to_select_parent', false);
//If short is set to true, then the name of the entity will only shown in the dropdown list not in the selected value.
$resolver->setDefault('short', false);
}
public function generateChoiceLabels(AbstractStructuralDBElement $choice, $key, $value, $options): string
protected function getChoiceContent(AbstractStructuralDBElement $choice, $key, $value, $options): string
{
//Similar to StructuralEntityType, but we use the currency symbol instead if available
if (!$choice instanceof Currency) {
throw new \InvalidArgumentException('$choice must be an currency object!');
if(!$choice instanceof Currency) {
throw new \RuntimeException('$choice must be an instance of Currency!');
}
//Generate the level spacing
/** @var AbstractStructuralDBElement|null $parent */
$parent = $options['subentities_of'];
/*** @var Currency $choice */
/*** @var AbstractStructuralDBElement $choice */
$level = $choice->getLevel();
//If our base entity is not the root level, we need to change the level, to get zero position
if (null !== $options['subentities_of']) {
$level -= $parent->getLevel() - 1;
}
$tmp = str_repeat('   ', $level); //Use 3 spaces for intendation
if (empty($choice->getIsoCode())) {
$tmp .= htmlspecialchars($choice->getName());
} else {
$tmp = str_repeat('<span class="picker-level"></span>', $level);
//Show currency symbol or ISO code and the name of the currency
if(!empty($choice->getIsoCode())) {
$tmp .= Currencies::getSymbol($choice->getIsoCode());
//Add currency name as badge
$tmp .= sprintf('<span class="badge bg-primary ms-2 %s">%s</span>', $options['short'] ? 'picker-hs' : '' , htmlspecialchars($choice->getName()));
} else {
$tmp .= htmlspecialchars($choice->getName());
}
return $tmp;
}
protected function generateChoiceAttr(AbstractStructuralDBElement $choice, $key, $value, $options): array
{
/** @var Currency $choice */
$tmp = [];
if (!empty($choice->getIsoCode())) {
//Show the name of the currency
$tmp += ['data-subtext' => $choice->getName()];
}
//Disable attribute if the choice is marked as not selectable
if ($options['disable_not_selectable'] && $choice->isNotSelectable()) {
$tmp += ['disabled' => 'disabled'];
}
return $tmp;
}
}

View file

@ -239,13 +239,34 @@ class StructuralEntityType extends AbstractType
return $this->em->find($options['class'], $value->getID());
}
/**
* This generates the HTML code that will be rendered by selectpicker
* @return string
*/
protected function getChoiceContent(AbstractStructuralDBElement $choice, $key, $value, $options): string
{
$html = "";
//Add element name, use a class as whitespace which hides when not used in dropdown list
$html .= $this->getElementNameWithLevelWhitespace($choice, $options, '<span class="picker-level"></span>');
if ($options['show_fullpath_in_subtext'] && null !== $choice->getParent()) {
$html .= '<span class="ms-3 badge rounded-pill bg-secondary float-end"><i class="fa-solid fa-folder-tree"></i>&nbsp;' . trim(htmlspecialchars($choice->getParent()->getFullPath())) . '</span>';
}
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
$html .= '<span class="ms-3 badge bg-warning"><i class="fa-solid fa-file-circle-exclamation"></i>&nbsp;' . trim(htmlspecialchars($choice->getFiletypeFilter())) . '</span>';
}
return $html;
}
protected function generateChoiceAttr(AbstractStructuralDBElement $choice, $key, $value, $options): array
{
$tmp = [];
if ($options['show_fullpath_in_subtext'] && null !== $choice->getParent()) {
$tmp += ['data-subtext' => $choice->getParent()->getFullPath()];
}
//Disable attribute if the choice is marked as not selectable
if ($options['disable_not_selectable'] && $choice->isNotSelectable()) {
@ -256,10 +277,13 @@ class StructuralEntityType extends AbstractType
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
}
//Add the HTML content that will be shown finally in the selectpicker
$tmp += ['data-content' => $this->getChoiceContent($choice, $key, $value, $options)];
return $tmp;
}
protected function generateChoiceLabels(AbstractStructuralDBElement $choice, $key, $value, $options): string
protected function getElementNameWithLevelWhitespace(AbstractStructuralDBElement $choice, $options, $whitespace = "&nbsp;&nbsp;&nbsp;"): string
{
/** @var AbstractStructuralDBElement|null $parent */
$parent = $options['subentities_of'];
@ -271,9 +295,15 @@ class StructuralEntityType extends AbstractType
$level -= $parent->getLevel() - 1;
}
$tmp = str_repeat('&nbsp;&nbsp;&nbsp;', $level); //Use 3 spaces for intendation
$tmp = str_repeat($whitespace, $level); //Use 3 spaces for intendation
$tmp .= htmlspecialchars($choice->getName());
return $tmp;
}
protected function generateChoiceLabels(AbstractStructuralDBElement $choice, $key, $value, $options): string
{
//Just for compatibility reasons for the case selectpicker should not work. The real value is generated in the getChoiceContent() method
return $this->getElementNameWithLevelWhitespace($choice, $options, " ");
}
}