# Create numberfields dynamically

Hi, I wanted to create numberfield dynamically based on the number of files uploaded/to be analysed to cusomise a parameter for each file.

But I ended up with following error:
2024-08-22 16:07:43.505 ERROR : ‘function’ object has no attribute ‘_generate_entity_type’
2024-08-22 16:07:43.505 ERROR : Error in app definition, app not reloaded

I can also confirm that " num_files, epa_ranges = analyze_files()" works pretty well in the controller.

Can someone enlight me what happend? Thank you.

def create_EPA_sliders():
    num_files, epa_ranges = analyze_files()

    for i in range(1, num_files):
        slider_name = f'slider_{i}'
        setattr(
            Section1,
            slider_name,
            NumberField(
                f'Adjust axial strain % for test {i}',
                min=0,
                max=30,
                variant='slider',
                flex=100,
                default=10.5,
                name=f"epa_{i}",
                num_decimals=1,
                suffix="%",
                description=f'Specify axial strain at critical state for test {i}'
            )
        )

Hi @Hao ,

My recommendation would be to have a parametrization set up with a field to upload your files, and then a dynamic array that can be used to have these number fields dynamically set. The setting of the fields can be done through a SetParamsButton. E.g.:

class Parametrization(ViktorParametrization):
    file_upload = MultiFileField("Upload files")
    set_fields_btn = SetParamsButton("Set my fields", method="set_fields")
    dynamic_array = DynamicArray("Dynamic numbers based on files")
    dynamic_array.my_number = NumberField("My number", variant="slider", min=0, max=30, flex=100)

class Controller(ViktorController):
    label = "My Entity Type"
    parametrization = Parametrization

    def set_fields(self, params, **kwargs):
        number_list = []
        for _file in params.file_upload:
            number_list.append({"my_number": 10.5})
        params.dynamic_array = number_list
        return SetParamsResult(params)

I hope this helps.

Hi mslootweg,

Many thanks, it worked! But when I want to pass a two column list to Table, it only allowed one.

In the case below, only Axial strain (%) was passed to the Table from number_list, while the number_list contains both Test ID and Axial strain (%), which is printed as Number List: [{‘Test ID’: ‘Test 10’, ‘Axial strain (%)’: 8.3}…

def set_fields(self, params, **kwargs):
    number_list = []

    # Get the list of files in the order they are retrieved
    file_dict = self._get_sample_file_dict()
    files = list(file_dict.glob("*.csv"))

    sample_file_count = len(files)  # Use the length of files for sample CSV toggle

     for file in files:
            file_stem = Path(file).stem
            print(f"Processing file: {file}, Test ID: {file_stem}")  # Debugging: Check file and Test ID
            number_list.append({"Test ID": file_stem, "Axial strain (%)": 8.3})

    print("Number List:", number_list)  # Debugging: Check the final number_list

    # Set the eap_tabe with the ordered number_list
    params.Section1.eap_tabe = number_list
    return SetParamsResult(params)

Hi @Hao ,

I suspect that it has to do with the keys that you are using for your number_list. Fields are defined as names without spacings, and from your example it looks like you might be using the labels. Your snippet does not include your parametrization, but I suspect that it should be changed to something like:

number_list.append({"test_id": file_stem, "axial_strain": 8.3})

with test_id and axial_strain referring to the parametrization attribute that you’ve defined the table’s columns.

1 Like

Thans Mslootweg! It is indeed the spacing, which quickly solve the problem…