diff --git a/config/packages/fos_ckeditor.yaml b/config/packages/fos_ckeditor.yaml index 7b5676a0..beced809 100644 --- a/config/packages/fos_ckeditor.yaml +++ b/config/packages/fos_ckeditor.yaml @@ -10,7 +10,6 @@ fos_ck_editor: complex_config: extraPlugins: ["bbcode"] toolbar: standard - height: 100 simple_config: extraPlugins: "bbcode" toolbar: basic diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php index 5730ae04..b1fb587c 100644 --- a/src/Form/Part/PartBaseType.php +++ b/src/Form/Part/PartBaseType.php @@ -37,6 +37,7 @@ use App\Entity\Parts\Manufacturer; use App\Entity\Parts\MeasurementUnit; use App\Entity\Parts\Part; use App\Entity\Parts\Storelocation; +use App\Form\Type\SIUnitType; use App\Form\Type\StructuralEntityType; use Doctrine\DBAL\Types\FloatType; use FOS\CKEditorBundle\Form\Type\CKEditorType; @@ -68,12 +69,8 @@ class PartBaseType extends AbstractType /** @var Part $part */ $part = $options['data']; - //Select the amount value type based on the - if($part->useFloatAmount()) { - $amount_class = NumberType::class; - } else { - $amount_class = IntegerType::class; - } + $part_unit_name = $part->getPartUnit() !== null ? $part->getPartUnit()->getUnit() : ""; + $use_si_prefix = $part->getPartUnit() !== null ? $part->getPartUnit()->isUseSIPrefix() : false; //Common section @@ -84,11 +81,10 @@ class PartBaseType extends AbstractType ->add('description', CKEditorType::class, ['required' => false, 'empty_data' => '', 'label' => 'description.label', 'help' => 'bbcode.hint', 'config_name' => 'description_config', 'attr' => ['placeholder' => 'part.description.placeholder', 'rows' => 2], - 'disabled' => !$this->security->isGranted('description.edit', $part), 'empty_data' => '' ]) - ->add('partUnit', StructuralEntityType::class, ['class'=> MeasurementUnit::class, - 'required' => false, 'disable_not_selectable' => true, 'label' => 'part.partUnit']) - ->add('minAmount', $amount_class, + 'disabled' => !$this->security->isGranted('description.edit', $part) ]) + ->add('minAmount', SIUnitType::class, ['attr' => ['min' => 0, 'placeholder' => 'part.mininstock.placeholder'], 'label' => 'mininstock.label', + 'show_prefix' => $use_si_prefix, "unit" => $part_unit_name, "is_integer" => !$part->useFloatAmount(), 'disabled' => !$this->security->isGranted('mininstock.edit', $part), ]) ->add('category', StructuralEntityType::class, ['class' => Category::class, 'label' => 'category.label', 'disable_not_selectable' => true, @@ -98,10 +94,7 @@ class PartBaseType extends AbstractType 'disabled' => !$this->security->isGranted('move', $part), ]) ->add('tags', TextType::class, ['required' => false, 'label' => 'part.tags', 'empty_data' => "", 'attr' => ['data-role' => 'tagsinput'], - 'disabled' => !$this->security->isGranted('edit', $part) ]) - ->add('comment', CKEditorType::class, ['required' => false, - 'label' => 'comment.label', 'attr' => ['rows' => 4], 'help' => 'bbcode.hint', - 'disabled' => !$this->security->isGranted('comment.edit', $part), 'empty_data' => '']); + 'disabled' => !$this->security->isGranted('edit', $part) ]); //Manufacturer section $builder->add('manufacturer', StructuralEntityType::class, ['class' => Manufacturer::class, @@ -114,11 +107,21 @@ class PartBaseType extends AbstractType 'empty_data' => '', 'label' => 'part.mpn', 'disabled' => !$this->security->isGranted('manufacturer.edit', $part)]); - //Options section + //Advanced section $builder->add('needsReview', CheckboxType::class, ['label_attr'=> ['class' => 'checkbox-custom'], 'required' => false, 'label' => 'part.edit.needs_review']) ->add('favorite', CheckboxType::class, ['label_attr'=> ['class' => 'checkbox-custom'], - 'required' => false, 'label' => 'part.edit.is_favorite']); + 'required' => false, 'label' => 'part.edit.is_favorite']) + ->add('mass', SIUnitType::class, ['unit' => 'g', + 'label' => 'part.mass', 'required' => false]) + ->add('partUnit', StructuralEntityType::class, ['class'=> MeasurementUnit::class, + 'required' => false, 'disable_not_selectable' => true, 'label' => 'part.partUnit']); + + + //Comment section + $builder->add('comment', CKEditorType::class, ['required' => false, + 'label' => 'comment.label', 'attr' => ['rows' => 4], 'help' => 'bbcode.hint', + 'disabled' => !$this->security->isGranted('comment.edit', $part), 'empty_data' => '']); //Part Lots section $builder->add('partLots', CollectionType::class, [ diff --git a/src/Form/Type/SIUnitType.php b/src/Form/Type/SIUnitType.php new file mode 100644 index 00000000..63010110 --- /dev/null +++ b/src/Form/Type/SIUnitType.php @@ -0,0 +1,156 @@ +si_formatter = $SIFormatter; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'show_prefix' => true, + 'is_integer' => false, + ]); + + $resolver->setRequired('unit'); + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('value', NumberType::class); + + if ($options['show_prefix']) { + $builder->add('prefix', ChoiceType::class, [ + 'choices' => ['M' => 6, 'k' => 3, '' => 0, 'm' => -3 ] + ]); + } + + $builder->setDataMapper($this); + } + + public function buildView(FormView $view, FormInterface $form, array $options) + { + $view->vars['unit'] = $options['unit']; + parent::buildView($view, $form, $options); // TODO: Change the autogenerated stub + } + + /** + * Maps the view data of a compound form to its children. + * + * The method is responsible for calling {@link FormInterface::setData()} + * on the children of compound forms, defining their underlying model data. + * + * @param mixed $viewData View data of the compound form being initialized + * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances + * + * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported + */ + public function mapDataToForms($viewData, $forms) + { + if ($viewData === null) { + return null; + } + + $data = $this->si_formatter->convertValue($viewData); + + $forms = iterator_to_array($forms); + + if (isset($forms['prefix'])) { + $forms['value']->setData($data["value"]); + $forms['prefix']->setData($data['prefix_magnitude']); + } else { + $forms['value']->setData($viewData); + } + } + + /** + * Maps the model data of a list of children forms into the view data of their parent. + * + * This is the internal cascade call of FormInterface::submit for compound forms, since they + * cannot be bound to any input nor the request as scalar, but their children may: + * + * $compoundForm->submit($arrayOfChildrenViewData) + * // inside: + * $childForm->submit($childViewData); + * // for each entry, do the same and/or reverse transform + * $this->dataMapper->mapFormsToData($compoundForm, $compoundInitialViewData) + * // then reverse transform + * + * When a simple form is submitted the following is happening: + * + * $simpleForm->submit($submittedViewData) + * // inside: + * $this->viewData = $submittedViewData + * // then reverse transform + * + * The model data can be an array or an object, so this second argument is always passed + * by reference. + * + * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances + * @param mixed $viewData The compound form's view data that get mapped + * its children model data + * + * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported + */ + public function mapFormsToData($forms, &$viewData) + { + //Convert both fields to a single float value. + + $forms = iterator_to_array($forms); + + $viewData = $forms['value']->getData(); + + if (isset($forms['prefix'])) { + $multiplier = $forms['prefix']->getData(); + $viewData *= 10 ** $multiplier; + } + } +} \ No newline at end of file diff --git a/src/Services/SIFormatter.php b/src/Services/SIFormatter.php index 965fd2ee..083d3cb4 100644 --- a/src/Services/SIFormatter.php +++ b/src/Services/SIFormatter.php @@ -75,12 +75,32 @@ class SIFormatter } /** + * * @param float $value - * @param string $unit - * @param int $decimals + * @return array + */ + public function convertValue(float $value) : array + { + //Choose the prefix to use + $tmp = $this->getPrefixByMagnitude($this->getMagnitude($value)); + + $ret = array( + 'value' => $value / $tmp[0], + 'prefix_magnitude' => log10($tmp[0]), + 'prefix' => $tmp[1] + ); + + return $ret; + } + + /** + * Formats the given value to a string, using the given options + * @param float $value The value that should be converted + * @param string $unit The unit that should be appended after the prefix + * @param int $decimals The number of decimals (after decimal dot) that should be outputed. * @return string */ - public function format(float $value, string $unit = '', int $decimals = 2) + public function format(float $value, string $unit = '', int $decimals = 2) : string { [$divisor, $symbol] = $this->getPrefixByMagnitude($this->getMagnitude($value)); $value /= $divisor; diff --git a/templates/Form/extendedBootstrap4_layout.html.twig b/templates/Form/extendedBootstrap4_layout.html.twig index e8fefb43..6a1e6a22 100644 --- a/templates/Form/extendedBootstrap4_layout.html.twig +++ b/templates/Form/extendedBootstrap4_layout.html.twig @@ -29,4 +29,18 @@ {% endif %} {%- endif -%} {% endfor %} -{%- endblock choice_widget_options -%} \ No newline at end of file +{%- endblock choice_widget_options -%} + +{% block si_unit_widget %} +