diff --git a/assets/css/app.css b/assets/css/app.css
index d4a8ce0b..e4902527 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -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;
}
\ No newline at end of file
diff --git a/assets/ts_src/ajax_ui.ts b/assets/ts_src/ajax_ui.ts
index d621362b..0ff6825b 100644
--- a/assets/ts_src/ajax_ui.ts
+++ b/assets/ts_src/ajax_ui.ts
@@ -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;
}
diff --git a/src/Form/Part/PricedetailType.php b/src/Form/Part/PricedetailType.php
index 1fa52a70..7b929adf 100644
--- a/src/Form/Part/PricedetailType.php
+++ b/src/Form/Part/PricedetailType.php
@@ -82,6 +82,7 @@ class PricedetailType extends AbstractType
$builder->add('currency', CurrencyEntityType::class, [
'required' => false,
'label' => false,
+ 'short' => true,
]);
}
diff --git a/src/Form/Type/CurrencyEntityType.php b/src/Form/Type/CurrencyEntityType.php
index 38b7501b..e69a9724 100644
--- a/src/Form/Type/CurrencyEntityType.php
+++ b/src/Form/Type/CurrencyEntityType.php
@@ -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('', $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('%s', $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;
- }
}
diff --git a/src/Form/Type/StructuralEntityType.php b/src/Form/Type/StructuralEntityType.php
index bcbe41f9..b5cd793e 100644
--- a/src/Form/Type/StructuralEntityType.php
+++ b/src/Form/Type/StructuralEntityType.php
@@ -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, '');
+
+ if ($options['show_fullpath_in_subtext'] && null !== $choice->getParent()) {
+ $html .= ' ' . trim(htmlspecialchars($choice->getParent()->getFullPath())) . '';
+ }
+
+ if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
+ $html .= ' ' . trim(htmlspecialchars($choice->getFiletypeFilter())) . '';
+ }
+
+ 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 = " "): string
{
/** @var AbstractStructuralDBElement|null $parent */
$parent = $options['subentities_of'];
@@ -271,9 +295,15 @@ class StructuralEntityType extends AbstractType
$level -= $parent->getLevel() - 1;
}
- $tmp = str_repeat(' ', $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, " ");
+ }
}