Adrian also suggested using the registration_form_created signal to create the new field which is probably better than hooking into create_personal_data_fields.
Thank you very much for your help! I managed to create a new field like this successfully, and it works:
section_to_add = sender.sections[0]
field1 = RegistrationFormField(
registration_form=sender,
parent=section_to_add,
title="GitHub Username",
input_type="text",
is_required=False,
position=1,
)
field1.data, versioned_data = field1.field_impl.process_field_data({})
field1.current_data = RegistrationFormFieldData(versioned_data=versioned_data)
section_to_add.children.append(field1)
My final question is, how can I prefill the registration form, which hook/signal can I use to intercept the form? I tried with schema_post_dump, schema_pre_load, schema_post_load, but canāt see a similar form info to the one in profile page. What would be the best way to approach this?
Edit: I am guessing there is something I can use in indico.core.signals.event but havenāt figured out testing the signals here yet.
My final question is, how can I prefill the registration form
See my other reply a while back: Editing the user profile page with additional fields - #12 by troun
Oopps sorry, my bad. Thank you!
For sure this time itās the final question!
Intercepting the get_user_data I can currently add info for text areas, however, for single or multi-choice areas, I couldnāt prefill like this ( testing example ):
def _get_user_data(self, sender, func, args, **kwargs):
print("Intercepted get_user_data call")
# Call the original function to get the base data
user_data = func(*args.args, **args.kwargs)
user_data["field_208"] = "DevOps" # Text area
user_data["field_209"] = ["m"] # Single choice
user_data["field_210"] = ["veg"] # Multi choice
print("Final user_data with custom fields:", user_data)
return user_data
For single choice, I both tried sending it as string ( "m" ) and the list as above, both not working. I have been trying to fix it for a while but couldnāt figure out what I am missing. I have the config for the fields as follows:
# Text Field
{"name": "product", "title": "Product", "input_type": "text", "is_required": False},
# Single Choice Field
{
"name": "shirt_size",
"title": "T-Shirt Size",
"input_type": "single_choice",
"is_required": True,
"item_type": "dropdown",
"choices": [
{"id": "s", "caption": "Small"},
{"id": "m", "caption": "Medium"},
{"id": "l", "caption": "Large"},
{"id": "uxl", "caption": "Extra Large"},
],
},
# Multi Choice Field
{
"name": "dietary_options",
"title": "Dietary Options",
"input_type": "multi_choice",
"is_required": False,
"item_type": "checkbox",
"choices": [
{"id": "veg", "caption": "Vegetarian"},
{"id": "vegan", "caption": "Vegan"},
{"id": "gf", "caption": "Gluten-Free"},
{"id": "halal", "caption": "Halal"},
],
},
and this is how I add them to the form:
section_to_add = sender.sections[0]
for idx, field_meta in enumerate(self.custom_fields, start=1):
field = RegistrationFormField(
registration_form=sender,
parent=section_to_add,
title=field_meta["title"],
input_type=field_meta["input_type"],
is_required=field_meta["is_required"],
position=idx,
)
field_data = {}
if field_meta["input_type"] in ("single_choice", "multi_choice"):
field_data = {
"item_type": field_meta.get("item_type", "dropdown"),
"with_extra_slots": False,
"is_enabled": True,
"choices": [
{
"id": c.get("id"),
"caption": c["caption"],
"is_enabled": True,
}
for c in field_meta.get("choices", [])
],
}
# Initialize field data
field.data, versioned_data = field.field_impl.process_field_data(field_data)
field.current_data = RegistrationFormFieldData(
versioned_data=versioned_data
)
section_to_add.children.append(field)
I have been playing with the code, trying to figure out what might be wrong by checking the source code etc, but couldnāt figure out the problem. The field appears in the form as it should, but I canāt prefill it or send the registration form. What am I missing here?
Edit: I am sorry, registering actually DOES work. I deleted that part from my original question However, prefilling is still the issue, and canāt prefill at the moment, so that question still stands! Thanks!
Ahh I was supposed to pass a dictionary like :
user_data["field_208"] = "DevOps" # Text area
user_data["field_209"] = {"m": 1} # Single choice
user_data["field_210"] = {"veg":1, "gf":1} # Multi choice
Solved!
Please note that the ids of choice items are typically uuid4 UUIDs. While anything else may work, I highly recommend to use UUIDs in case we ever add stronger validation there.
Ah thanks for the heads-up, will do!