MultiSelectField andere layout

Ik ben bezig om een nieuwe interface in onze Viktor applicatie te maken en gebruik hiervoor MultiSelectField. Het probleem is alleen dat deze niet de layout geeft zoals ik hem zou willen zien. In de afbeelding heb ik het idee toegevoegd hebben jullie een idee hoe ik zit kan bereiken?

image

Hoi Bob,

Wat is het resultaat dat je wel krijgt dan? Is er iets mis met de text, of de iconen oid? Of bedoel je dat je niet 2 kolommen krijgt maar alle opties onder elkaar? In dat laatste geval: ik geloof niet dat het nu mogelijk is om te beinvloeden dat er meerdere kolommen in 1 veld zitten. Misschien kun je uitleggen wat je specifiek probeert op te lossen dat nu niet lukt, wellicht helpt dat met het verzinnen van nieuwe ideeen.

Mvg,

Roeland

Hoi roeland,

Wat ik voor elkaar wil krijgen is dezelfde layout gebruiken als optionfield, maar in plaats van het gebruiken van radio buttons zou ik checkboxes willen hebben. Bij optionfield is het namelijk maar mogelijk om één optie aan te geven maar ik wil meerdere opties kunnen kiezen.

Hoi Bob,

Ik snap dan toch niet helemaal wat je nu krijgt en wat je daaraan ongewenst vind. Als voorbeeld heb ik deze code toegevoegd aan een app:

    from viktor.parametrization import MultiSelectField

    ...

    project_overview.test = MultiSelectField('Test', options=['a', 'b', 'c', 'd', 'e'])

Dat levert in de interface deze knop (met checkboxes!?) op:
Screenshot from 2022-07-11 16-30-04

Hoi Roeland,

Dat is ook gelukt. Het probleem wat ik heb is dat ik de inhoud van dit veld na elke keuzen in dit veld zou willen veranderen. Ik weet hoe dit moet met een callback alleen deze activeert pas zodra ik uit de interface met de checkboxes klik. Misschien heb jij een ander idee hoe ik dit probleem moet oplossen?

Hoi Bob,

Mooi om te lezen dat je in ieder geval de multiselect (en daarmee de checkboxes) succesvol kan gebruiken. Het is inderdaad niet mogelijk om binnen 1 veld de opties dynamisch te maken. Ik vraag me ook meteen af of dat voor een eindgebruiker nou heel duidelijk zou zijn ook, als de opties in veld A wijzigen iedere keer dat hij in veld A iets kiest.

Ik weet natuurlijk niet precies wat voor opties er dynamisch moeten worden, maar zou het geen mogelijkheid zijn om de dynamische opties in een tweede veld te hebben? Dat het tweede veld dus wordt gevuld met opties op basis van de keuze in het eerste veld?

De andere mogelijkheid is gebruik maken van een SetParamsButton, maar ook dan zal de gebruiker een selectie in veld 1 moeten maken, op de knop drukken, en dan verschijnen de relevante extra opties in veld 1 er bij. Persoonlijk lijkt de eerste optie (2 velden maken) me dan gebruiksvriendelijker.

Mvg,

Roeland

Hoi Roeland,

Nee de opties zijn niet te onderverdelen in meerdere velden. Is er geen mogelijkheid om dit toch voor elkaar te krijgen?

Hoi Bob,

Jammer dat het splitsen niet mogelijk is. Wat zie je als grootste probleem aan splitsen?

Het is inderdaad niet mogelijk, en dat is omdat het invullen van opties in een veld gebeurd als de gebruiker een actie heeft gedaan. Met een actie bedoelen we dan: op een knop gedrukt, een waarde ingevuld in een veld (en er dus met de muis “uit” is gegaan), een visualisatie geselecteerd, etc. Zolang je nog “in” het veld zelf bent is er geen actie, en dus ook geen vullen van opties in het veld (of in andere velden), net zo min als we een visualisatie zouden uitrekenen.

De enige andere mogelijkheid, naast callback, om je parametrisatie dynamisch te maken vanuit de parametrisatie zelf is dus via de SetParamsButton

Mvg,
Roeland

Hoi Roeland,

We hebben er toch voor gekozen om de meerdere optionfield te implementeren. Een andere vraag die ik nu heb is het mogelijk om een optionfield/multiselectfield op niet visible te zetten als er geen opties in het veld beschikbaar zijn?

Hoi Bob,

Ok, dat klinkt mij persoonlijk als een goede keuze in de oren!

Ieder veld heeft een visible argument, waar je True of False in moet stoppen. Die True of False kun je echter ook weer laten uitrekenen met bijvoorbeeld een callback functie, of mbv Lookup op basis van andere velden laten bepalen. Het lijkt me dat je bijv. een veld 2 pas wil tonen als er een specifieke waarde in veld 1 is gekozen? Voorbeelden kun je hier vinden.

Mvg,

Roeland

Hoi Roeland,

Ja dat had ik ook al gevonden dat dit op deze manier kon. Wat ik niet kan vinden is hoe ik de opties van een ander veld op kan halen. Het ophalen van de gekozen waarde lukt wel maar ik wil kijken hoeveel opties er in een veld zitten als dit groter dan 0 is visible true geven en anders false. Heb jij enig idee hoe ik de beschikbare opties uit een veld kan halen?

Hi Bob,

Als ik het goed begrijp worden de opties voor deze multiselect dynamish bepaald. Er zijn twee manieren om dat te doen. Ten eerste kun je visibility op de OptionListElements zetten, zoals dit voorbeeld, ik geloof dat dat is wat je nu gebruikt? Ik denk dat in jou geval een callback function misschien beter werkt zoals dit voorbeeld:

from viktor.parametrization import Parametrization, OptionField

def get_material_options(params, **kwargs):
    if params.material_group == 'Aluminium':
        return ['Aluminium 5083', 'Aluminium 6082']
    elif params.material_group == 'Steel':
        return ['Steel S355', 'Steel S690']
    else:
        return []

class ExampleParametrization(Parametrization):
    material_group = OptionField('Material group', options=['Aluminium', 'Steel'])
    material_type = OptionField('Material', options=get_material_options)

Als je niet wil dat het veld zichtbaar is als er geen opties zijn, kun je de functie get_material_options hergebruiken voor de visibility van het veld, zoals dit:

def material_type_visibility(params, **kwargs):
    available_options = get_material_options(params)
    if available_options == []:
        return false
    else:
        return true

class ExampleParametrization(Parametrization):
    material_group = OptionField('Material group', options=['Aluminium', 'Steel'])
    material_type = OptionField('Material', options=get_material_options, visible=material_type_visibility)