Vaadin: How do I add options to a combo box? - vaadin

I have a combo box that I am trying to add options to. How Do I go about this? This is what I have so far:
ComboBox contactPrefixNametf = new ComboBox("Prefix");
contactPrefixNametf.setItemCaption(contactPrefixNametf, "Mr");
fLayout.addComponent(contactPrefixNametf);
contactPrefixNametf.setImmediate(true);
I guess .setItemCaption() is not the correct method? What is the correct method?
Thank you in advance!

Use addItem() method:
final ComboBox my_combox_box = new ComboBox("My Combo Box");
for (final My_object mo: list_of_my_objects)
{
my_combox_box.addItem(mo);
my_combox_box.setItemCaption(mo, mo.name());
}
This example uses addItem inconjunction with setItemCaption() to store the actual object selected by the user with a display friendly name (if toString() is not appropriate).

myComboBox.addItem("Option 1");

(Especially if you are new to Vaadin), I suggest to try Viritin add-on and its TypedSelect variant of ComboBox. Its well typed API makes many things ridiculously simpler. For instance it has a (typed) setOptions method and its value change listeners provide the value directly instead of through untyped Property interface.
A code example of its usage:
List<Person> options = service.findMyPersons();
TypedSelect<Person> select = new TypedSelect<>(Person.class)
.withSelectType(ComboBox.class);
select.setOptions(options);
// If toString() representation is not good, modify it to something else
select.setCaptionGenerator(person -> person.getFirstName() + person.getLastName());
select.addMValueChangeListener(event -> {
Person person = event.getValue();
});
Disclaimer: I'm the maintainer of Viritin, but also have maintained Vaadin for 8 years and nowadays work as its developer advocate.

Related

How to Add a field in cascade of 2 many to one on Easyadmin 4 Symfony 6

I read and try a lots of things just to add a field witch is in relation.
One Dance have a level (beginner, improver...) and one Level have a Style (Country music, disco...). So for a dance I can get the level and associate style. Dance is MTO with Level, and Level is MTO with Style. It work fine in traditionnel controller and in Dance Index twig I can do
{{ dance.level.style }}
It's work fine.
Impossible for me to do that in EasyAdmin: In Danse Crud Controller
yield AssociationField::new('level');
is naturally working fine but how adding the style name? I'm not familiar with Queribuilder if it's the solution. I read Symfony Documentation easyadmin about unmapped fields but I don't undestand "createIndexQueryBuilder" parameters. If you can help me to progress. Thank's in advance
I don't find examples in stack with Easyadmin 4. And (I'm sorry), documentation is not very clear for me.
Example:
class UserCrudController extends AbstractCrudController
{
// ...
public function configureFields(string $pageName): iterable
{
return [
TextField::new('fullName'),
// ...
];
}
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
// if user defined sort is not set
if (0 === count($searchDto->getSort())) {
$queryBuilder
->addSelect('CONCAT(entity.first_name, \' \', entity.last_name) AS HIDDEN full_name')
->addOrderBy('full_name', 'DESC');
}
return $queryBuilder;
}
}
Why we have "entity.first_name" (why entity word and not entityDto...). dump parameters don't give me persuasive results
Easy finally.
You can choice the field you want to be rendered. Basically add __toString in Entity.
In my case just add for a many to many relation:
AssociationField::new('dances')
->setFormTypeOption('choice_label','level.style'),

How to dynamically set binding type's "formatOptions" and "constraints" in XML with binding?

I have a list of elements (OData set) and use a binding to show this list.
One field is for a quantity value and this value could sometimes need some decimal places.
The requirement is: only show that amount of decimal numbers that is also available in the OData service.
Annotation techniques can't be used.
I 'hacked' something that is misusing a formatter to update the type of a binding. But this is 'a hack' and it is not possible to convert it to XML views. (The reason is a different handling of the scope the formatter will be called).
So I am searching for a working solution for XML views.
The following code would not work but shows the issue:
new sap.m.Input({ // looking for an XML solution with bindings
value: {
path: "Quantity",
type: new sap.ui.model.type.Float({
// formatOptions
maxFractionDigits: "{QuantityDecimals}",
// ...
}, {
// constraints
minimum: 0
}),
// ...
}
});
The maxFractionDigits : "{QuantityDecimals}" should be "dynamic" and not a constant value.
Setting formatOptions and constraints dynamically in XML (via bindings or a declared function) is unfortunately not (yet) supported. But IMHO this is a valid enhancement request that app developers would greatly benefit from, since it encourages declarative programming.
I already asked for the same feature some years ago but in a comment at https://github.com/SAP/openui5/issues/2449#issuecomment-474304965 (See my answer to Frank's question "If XMLViews would allow a way to specify the dynamic constraints as well (e.g. enhanced syntax), would that fix the problem?").
Please create a new issue via https://github.com/SAP/openui5/issues/new with a clear description of what kind of problems the feature would resolve and possibly other use cases (You can add a link to my comment). I'll add my đź‘Ť to your GitHub issue, and hopefully others too.
I'll update this answer as soon as the feature is available.
Get your dynamic number from your model and store it in a JS variable.
var nQuantityDecimals = this.getModel().getProperty("/QuantityDecimals");
new sap.m.Input({
value : {
path : "Quantity",
type : new sap.ui.model.type.Float({
maxFractionDigits : nQuantityDecimals,
source : {
groupingSeparator: ",",
decimalSeparator: ".",
groupingEnabled: false
}
}, {
minimum:0
})
}
}),

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem:
We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.
'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',
class TcaHook
{
public function addFields($config){
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
$setup = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
);
}
$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.
Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.
Does anybody know where the problem is? Is there some alternative?
You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whĂ­ch is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks.
Depending on what you want to configure via TypoScript, you may want to do something like this:
'config' => [
'type' => 'select',
'renderType' => 'singleSelect',
'items' => [
['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
],
'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
'customSetting' => 'somesetting'
]
and then access it in your class:
class TypeSelectProcFunc{
public function fillSelect(&$params){
if( $params['customSetting'] === 'somesetting' ){
$params['items'][] = ['New item',1];
}
}
}
I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.
However, before we look at the solution, Euli made some good points in his answer:
Do not use extbase configuration manager in TCA functions
Use TSconfig instead of TypoScript for backend configuration
You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.
For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)
I am posting this in the hope that it may be helpful for similar problems.
public function populateItemsProcFunc(array &$config): array
{
// workaround to set current page id for BackendConfigurationManager
$_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$configurationManager = $objectManager->get(BackendConfigurationManager::class);
$setting = $configurationManager->getTypoScriptSetup();
$templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];
// ... some code removed
}
protected function getPageId(int $pid): int
{
if ($pid > 0) {
return $pid;
}
$row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
return $row['pid'];
}
The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout
If you look at the code in the TYPO3 core, it will try to get the current page id from
(int)GeneralUtility::_GP('id');
https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132
This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

How to determine if a Dart list is a fixed list?

How can I determine, at runtime, if a list in Dart is a "fixed list" ?
There are (at least) three ways to create a fixed-length list in Dart:
var fixed = new List(5); // fixed at five elements
var alsoFixed = new List.filled(5, null); // fixed at five elements, set to null
var fixedToo = new List.from([1,2,3], growable: false);
How do I ask, in code, if fixed, alsoFixed, and fixedToo are fixed-length?
You can try to add an element and remove it to know if the list has a fixed length:
bool hasFixLength(List list) {
try {
list
..add(null)
..removeLast();
return false;
} on UnsupportedError {
return true;
}
}
runtimeType can be used for that, but shouldn't because it's not very reliable especially with dart2js otherwise there isn't. AFAIR there were several requests to add support for this but was declined.
We did not add any way to see if a list is fixed (or const).
So far, we have only encountered one use case where this would fit into well-written code: checking that a function returned a mutable array. We decided that this use case was not worth changing the API.
Most of the time, an additional boolean flag that asks to modify an existing list is cleaner (since then, the caller can decide what the callee should do).
If you have another use case, please let us know and we will investigate.

Filter BindingSource with entity framework

Hi
How can i filter results exists in BindingSource filled with entities ( using EF 4)?
I tried this:
mybindingsource.Filter = "cityID = 1"
But it seems that binding source with entity framework doesn't support filtering .. am i right ?,is there another way to filter(search) data in binding source .
PS:
- I'm working on windows application not ASP.NET.
- I'm using list box to show the results.
Thanx
Maybe a better one than Leonid:
private BindingSource _bs;
private List<Entity> _list;
_list = context.Entities;
_bs.DataSource = _list;
Now when filtering is required:
_bs.DataSource = _list.Where<Entity>(e => e.cityID == 1).ToList<Entity>;
This way you keep the original list (which is retrieved once from the context) and then use this original list to query against in memory (without going back and forth to the database). This way you can perform all kinds of queries against your original list.
I think, you have made mistake in syntax. You should write Filter like this:
mybindingsource.Filter = "cityID = '1'"
Another way is to use LINQ expressions.
(About LINQ)
Why do you have to call Entety again?
Simple solution:
public List<object> bindingSource;
public IEnumerable FiltredSource
{
get{ return bindingSource.Where(c => c.cityID==1);
}
.where (Function (c) c.cityID = 1)

Resources